我需要獲取用戶主文件夾。目前我使用這個無評估的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