我需要获取用户主文件夹。目前我正在使用此
home=$(eval echo ~$user)
调用者提供$user
的内容,因此不受信任值。在这里使用eval
危险吗?如果是(可能),如何在没有它的情况下解决它?
答案 0 :(得分:4)
答案 1 :(得分:1)
在解析过程中很早就发生了Tilde扩展,没有多次评估就没有办法实现你想要的东西。因此eval
是的解决方案。实现您想要的最安全的方法是:
eval "$(printf "home=~%q" "$user")"
感谢%q
修饰符,扩展$user
将被完全引用,因此这里没有危险(不要修改该行,但是你会这样做)肯定会引入一些安全漏洞)。
你不应该单独使用它:在这一行之后,你必须检查你是否有一个有效的目录,例如,
if [[ ! -d $home ]]; then
echo >&2 "Couldn't find home dir for user $user"
exit 1
fi
还要考虑user
为空的情况:在这种情况下,home
将是运行脚本的用户的主目录。您是否想要此行为取决于您。
还需要考虑另一点:当user
包含斜杠时:您是否想要此功能取决于您。
现在,根据您希望拥有的功能,可以更好地针对某些预定义模式验证扩展$user
,例如,
if [[ $user != [a-z]*([-a-z0-9_]) ]]; then
echo >&2 'Provided user doesn't match valid pattern'
exit 1
fi
事实证明,通过此验证,您的解决方案是安全的。
示例:
一切运作良好的情况:
$ user=gniourf
$ eval "$(printf "home=~%q" "$user")"
$ declare -p home
declare -- home="/home/gniourf"
对您的代码造成危险的情况(代码ls
将被执行,但不会在此处执行):
$ user='; ls >&2'
$ eval "$(printf "home=~%q" "$user")"
$ declare -p home
declare -- home="~; ls >&2"