强制cURL从环境中获取密码 [英] Forcing cURL to get a password from the environment
问题描述
这个question about using cURL with a username and password对我来说答案不太理想:
curl -u "user:pw" https://example.com
将PW放入进程列表curl "https://user:pw@example.com"
将PW放入进程列表curl -u "user:$(cat ~/.passwd)" https://example.com
将PW放入进程列表curl -u user https://example.com
PW提示curl --netrc-file ~/.netrc https://example.com
需要文件
cURL man page表示(请注意粗体文本):
指定用于服务器身份验证的用户名和密码。 覆盖
-u/--user <user:password>
-n/--netrc
和--netrc-optional
。 如果您只提供用户名(不输入冒号),cURL将 提示输入密码。 如果使用启用SSPI的cURL二进制文件并执行NTLM身份验证, 可以强制cURL从您的环境中获取用户名和密码 只需使用此选项指定单个冒号:-u :
。
我尝试在环境中设置$USER
和$PASSWORD
(以及$CURLOPT_PASSWORD
和其他),但是当作为curl -u : https://example.com
调用时,curl无法获取它们中的任何一个(没有-u :
也不起作用)。
我不是在做NTLM,所以这不起作用。除非我遗漏了什么。
 ;
是否有办法仅通过环境将凭据传递给curl
?
 ;
(解决办法已移至答案)
推荐答案
此bash
解决方案似乎最符合我的需求。它非常安全、便携、快捷。
#!/bin/bash
SRV="example.com"
URL="https://$SRV/path"
curl --netrc-file <(cat <<<"machine $SRV login $USER password $PASSWORD") "$URL"
这使用process substitution(<( command )
在子shell中运行command
来填充要作为"文件"传递给父命令的file descriptor,在本例中是curl
)。进程替换包含here-string(cat <<< text
,echo text
的变体,不会将任何内容放入您的进程列表中),为netrc file创建文件描述符,以便将凭据传递到远程Web服务器。
进程替换提供的安全性实际上非常好:它的文件描述符是而不是临时文件,即使是同一外壳实例中的其他调用也无法使用,因此appears secure在此上下文中;对手必须通过挖洞通过内存或发起复杂的攻击才能找到其内容。由于$PASSWORD
环境变量也在内存中,因此这不会增加attack surface。
只要您没有使用过export PASSWORD
,像ps ewwp $$
这样的技巧应该不会泄露密码(如this comment中所述)。使用一些不太明显的变量名称也是明智的。
以下是上述代码的一个简化的不安全版本,可能有助于解释其工作原理:
#!/bin/sh
# INSECURE VERSION, DO NOT USE
SRV=example.com
URL="https://$SRV/path"
TMP=$(mktemp)
printf "machine %s login %s password %s
" "$SRV" "$USER" "$PASSWORD" > "$TMP"
curl --netrc-file "$TMP" "$URL"
rm -f "$TMP"
这个不安全的版本有很多漏洞,上一版本都解决了:
- 它将密码存储在一个文件中(尽管该文件只对您可读)
- 它在命令行中的密码非常简短
- 临时文件保留到
curl
退出后 - Ctrl+c将退出,不删除临时文件
部分问题可以通过以下方式解决:
#!/bin/sh
SRV=example.com
URL="https://$SRV/path"
TMP=$(mktemp /dev/shm/.XXXXX) # assumes /dev/shm is a ramdisk
trap "rm -f $TMP" 0 18
cat << EOF > "$TMP"
machine $SRV login $USER password $PASSWORD
EOF
(sleep 0.1; rm -f "$TMP") & # queue removing temp file in 0.1 seconds
curl --netrc-file "$TMP" "$URL"
我认为这个版本很混乱,不太理想,而且可能不太安全(尽管它更便于移植)。它还需要支持十进制的sleep
版本(如果系统负载过重,0.1秒可能太快)。
 ;
我最初发布了一个解决办法,在我的问题中包含perl
一行,然后(使用help from Etan Reisner)我尝试了几种更好的方法,最后选择了Here-String方法,它既更轻(更快),又更便携。
这篇关于强制cURL从环境中获取密码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!