2015-10-06 30 views
0

使用sudo,可以作爲其他用戶執行命令,並且確實安全地將參數傳遞給該命令。將參數安全地傳遞到通過su執行的命令

例討厭論點:

nastyArg='"double quoted" `whoami` $(whoami) '"'simple quoted "'$(whoami)'"'" 

預期輸出,經由termninal運行作爲congelli501:

% echo "$nastyArg" 
"double quoted" `whoami` $(whoami) 'simple quoted $(whoami)' 

執行如congelli501,經由須藤:

# sudo -u congelli501 -- echo "$nastyArg" 
"double quoted" `whoami` $(whoami) 'simple quoted $(whoami)' 

執行如congelli501,通過su(通常的逃生方法):

# su congelli501 -c "echo '$nastyArg'" 
"double quoted" `whoami` $(whoami) simple quoted congelli501 

正如您所看到的,參數並不安全地傳遞,因爲它由shell重新解釋。

有沒有辦法通過su啓動命令並直接傳遞它的參數,就像你可以使用sudo一樣?

回答

1

傳遞的命令,如蘇shell腳本的說法似乎工作:

# su congelli501 -s "$(which echo)" -- "$nastyArg" "'another arg'" 
"double quoted" `whoami` $(whoami) 'simple quoted $(whoami)' 'another arg' 

用法示例:

# Safely execute a command as an other user, via su 
# 
# $1 -> username 
# $2 -> program to run 
# $3 .. n -> arguments 
function execAs() { 
    user="$1"; shift 
    cmd="$1"; shift 
    su "$user" -s "$(which "$cmd")" -- "[email protected]" 
} 

execAs congelli501 echo "$nastyArg" "'another arg'" 
0

這裏的根本問題是,你想窩報價。你會希望su -c "stuff "with" double "quotes"被解析爲|su||-c||stuff "with" double "quotes"|但它實際上被解析爲|su||-c||stuff ||with|| double||quotes|然而其中最後四個令牌評估後粘貼在一起作爲一個字符串(注意空格,其中「內部」引號終止了表面的「外部」引號,而不是包裹在它們內部)。

在雙引號內,`whoami`擴展爲之前的任何內容都會傳遞給su

你可以做的,而不是要麼(一)$nastyArg尚未更引述周圍添加值(幾乎註定)或(B)su執行的程序的環境定義它。一個明顯的第三個選項是(c)以解除它的方式傳遞值,比如標準輸入。

printf '%s\n' "$nastyArg" | su -c 'cat' congelli501 

這似乎公然簡單,但真的去當你沒有在什麼將可能被root莫名其妙地評估完全信任的方式。

這是sudo優於su的原因之一。