我需要获取用户主文件夹。目前我使用这个无评估的Tilde扩展
home=$(eval echo ~$user)
的$user
内容是由主叫方提供的,因此不被信任值。这里使用的危险是eval
?如果是(可能),如何解决它没有它?
我需要获取用户主文件夹。目前我使用这个无评估的Tilde扩展
home=$(eval echo ~$user)
的$user
内容是由主叫方提供的,因此不被信任值。这里使用的危险是eval
?如果是(可能),如何解决它没有它?
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"
类似'$(cd〜; pwd)'也许吧? – n0rd
@ n0rd - 我认为OP意味着他们需要获得给定用户名的主文件夹,这是从不可信任来源指定的用户名。 –
对于未经验证的*输入,'eval'是危险的;你可以确保'$ user'只包含一个有效的用户名,例如'[[$ user =〜[a-zA-Z] [a-zA-Z0-9_]]] && home = $(eval echo 〜$用户)'。 (我不记得具体是什么构成了一个有效的用户名,但它就像一个有效的标识符。) – chepner