Ada*_*atz 15 security bash curl environment-variables sh
这有关使用卷曲用户名和密码的问题,对我来说最理想的答案:
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
提示pwcurl --netrc-file ~/.netrc https://example.com
需要一个文件#4是安全的,但我可能每天运行这个命令数百次,所以这很乏味.#5接近安全,但是具有root访问权限的人可以读取该文件.
该卷曲手册页说(注意粗体文本):
-u/--user <user:password>
指定用于服务器身份验证的用户名和密码.覆盖
-n/--netrc
和--netrc-optional
.如果您只是提供用户名(不输入冒号),curl将提示输入密码.
如果您使用启用SSPI的curl二进制文件并执行NTLM身份验证,则可以 通过使用以下选项指定单个冒号来强制curl从您的环境中获取用户名和密码:
-u :
.
我已经尝试在环境中设置$USER
和$PASSWORD
(以及$CURLOPT_PASSWORD
其他),但是cURL在调用时不会选择其中任何一个curl -u : https://example.com
(如果没有它也没有-u :
).
我不是在做NTLM,所以这不起作用.除非我错过了什么.
有没有办法将凭证传递给curl
环境?
(解决方法转到答案)
Ada*_*atz 19
此bash
解决方案似乎最符合我的需求.它非常安全,便携且快速.
#!/bin/bash
SRV="example.com"
URL="https://$SRV/path"
curl --netrc-file <(cat <<<"machine $SRV login $USER password $PASSWORD") "$URL"
Run Code Online (Sandbox Code Playgroud)
这使用进程替换(在子shell中<( command )
运行command
以填充文件描述符作为"文件"传递给父命令,在这种情况下是curl
).进程替换包含here-string(cat <<< text
其变体echo text
不会将任何内容放入进程列表中),为netrc文件创建文件描述符以便将凭据传递给远程Web服务器.
进程替换提供的安全性实际上非常合理:它的文件描述符不是临时文件,即使在同一个shell实例中的其他调用也不可用,因此在此上下文中看起来是安全的.对手必须通过内存挖掘或发动复杂的攻击才能找到其内容.由于$PASSWORD
环境变量也在内存中,因此不应增加攻击面.
只要您没有使用过export PASSWORD
,就不ps ewwp $$
应该泄露密码(如本评论中所述).使用一些不太明显的变量名称也是明智之举.
以下是上述代码的简化不安全版本,可能有助于解释它的工作原理:
#!/bin/sh
# INSECURE VERSION, DO NOT USE
SRV=example.com
URL="https://$SRV/path"
TMP=$(mktemp)
printf "machine %s login %s password %s\n" "$SRV" "$USER" "$PASSWORD" > "$TMP"
curl --netrc-file "$TMP" "$URL"
rm -f "$TMP"
Run Code Online (Sandbox Code Playgroud)
这个不安全的版本有很多缺陷,所有这些都在以前的版本中得到了解决:
curl
其中一些可以通过以下方式解决:
#!/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"
Run Code Online (Sandbox Code Playgroud)
我认为这个版本是凌乱的,次优的,可能不太安全(虽然它更便携).它还需要一个sleep
可以理解小数的版本(如果系统负载很重,则0.1秒可能太快).
我最初perl
在我的问题中发布了一个包含单行的解决方法,然后(在Etan Reisner的帮助下)我在解决这个字符串方法之前已经完成了一些更好的方法,这个方法既轻量级(更快)又更便携.
在这一点上,它足够优雅,我认为它是"答案",而不是"丑陋的解决方法",所以我把它迁移到这个官方答案.我已经给了@ghoti一个+1 的答案,它正确地指出cURL的命令行程序无法自己做我想要的,但我不是"接受"那个答案,因为它没有帮助解决问题.
有没有办法将凭证传递给
curl
环境?
不,我认为没有.
该CURLOPT_USERPWD文档我想介绍你所需要的,但是这是将使用curl库在其他语言可用的选项.PHP,Perl,C等
从shell运行的curl二进制文件只是该库的另一个前端,但是通过curl二进制文件将CURLOPT_USERPWD传递给库的方式是使用二进制文件上的命令行选项.
理论上,您可以将自己的二进制文件编写为curl库的前端,并编写支持环境变量.
您可以交替破解环境支持,因为您希望将其视为现有的curl二进制文件,并使用本地函数编译自己的.
但请注意,即使环境变量可能会被shell泄漏到进程表中.(你跑步时看到了什么ps ewwp $$
?)
也许具有受限权限的.netrc文件将是最安全的方式.也许你需要生成一个临时的.netrc文件供--netrc-file
curl选项使用.
我认为你要么必须为你的环境选择风险最小的解决方案,要么用真正安全的语言写一些东西.
用户“Tom, Bom”在这里提供了一个不错的解决方案:https : //coderwall.com/p/dsfmwa/securely-use-basic-auth-with-curl
curl --config - https://example.com <<< 'user = "username:password"'
Run Code Online (Sandbox Code Playgroud)
这可以防止密码出现在进程列表中,尽管这并没有专门解决 OP 的原始问题:
有没有办法传递凭据以仅在环境中卷曲?
我仍然给@goti 加分,因为他们给出了更全面、更翔实的答案。
以前的答案是正确的,最好的选择是使用 -n 进行curl(假设你在linux上):
vi ~YOUR_USER_NAME/.netrc
machine example.com
login YOUR_USER_NAME
password THE_ACTUAL_PASSWORD
curl -n https://example.com/some_end_point
Curl 在解析 netrc 文件中的标记时使用 SPACE 和 TAB 作为分隔符:
\nhttps://github.com/curl/curl/blob/bc5a0b3e9f16a431523ae54822adc38c3a396a26/lib/netrc.c#L122
\n因此,该--netrc-file
方法无法处理密码中的空格或制表符。
测试密码中的空格
\nSRV="httpbin.org"\nURL="https://$SRV/basic-auth/username/pass%20word"\nUSERNAME=username\nPASSWORD=\'pass word\'\ncurl -v --netrc-file <(echo "machine $SRV login $USERNAME password $PASSWORD") "$URL"\n
Run Code Online (Sandbox Code Playgroud)\n结果:\xe2\x9d\x8c 失败
\n\n\n警告:如果您的 shell 命令
\necho
不是内置命令,则上述curl 调用将暂时将 $PASSWORD 泄漏到进程表中。中bash
,是否echo
是内置的可以用 来测试type -t echo
。解决方法:使用cat
和 这里的字符串:替换<(echo "string")
为<(cat <<< "string")
. 此警告适用于本答案中的所有示例。
密码TAB测试
\nSRV="httpbin.org"\nURL="https://$SRV/basic-auth/username/pass%09word"\nUSERNAME=username\nPASSWORD=$\'pass\\tword\'\ncurl -v --netrc-file <(echo "machine $SRV login $USERNAME password $PASSWORD") "$URL"\n
Run Code Online (Sandbox Code Playgroud)\n结果:\xe2\x9d\x8c 失败
\n@sfgeorge 正确地指出,设置为 的-K, \xe2\x80\x89--config <file>
选项可用于在 STDIN 上提供密码。但是,将 STDIN 用于此目的会妨碍将 STDIN 用于其他目的,例如使用.<file>
-
--data @-
幸运的是,我们可以使用进程替换来代替 STDIN。进程替换扩展为文件名,因此可以在需要文件名的任何地方使用。
\n测试密码中的空格
\nUSERNAME=username\nPASSWORD=\'pass word\'\ncurl -v \\\n -K <(echo "user: \\"$USERNAME:$PASSWORD\\"") \\\n "https://httpbin.org/basic-auth/username/pass%20word"\n
Run Code Online (Sandbox Code Playgroud)\n结果:\xe2\x9c\x85 成功
\n密码TAB测试
\nUSERNAME=username\nPASSWORD=$\'pass\\tword\'\ncurl -v \\\n -K <(echo "user: \\"$USERNAME:$PASSWORD\\"") \\\n "https://httpbin.org/basic-auth/username/pass%09word"\n
Run Code Online (Sandbox Code Playgroud)\n结果:\xe2\x9c\x85 成功
\n而且,为了额外的稳健性,我们让它也处理密码中的双引号。
\n"
密码中双引号的测试
USERNAME=username\nPASSWORD=$\'pa s\\ts"wo$rd\'\n\n# Build \'user\' option\nUSER_OPT="$USERNAME:$PASSWORD"\nUSER_OPT=${USER_OPT//\\\\/\\\\\\\\} # Escape `\\`\nUSER_OPT=${USER_OPT//\\"/\\\\\\"} # Escape `"`\nUSER_OPT="user: \\"${USER_OPT}\\""\n\ncurl -v \\\n -K <(echo "$USER_OPT") \\\n "https://httpbin.org/basic-auth/username/pa%20s%09s%22wo%24rd"\n
Run Code Online (Sandbox Code Playgroud)\n结果:\xe2\x9c\x85 成功
\n为了更好地衡量,我还添加了一个表情符号。
\n 归档时间: |
|
查看次数: |
9295 次 |
最近记录: |