2010-06-10 52 views
3

我寫了一個名爲「isinFile.sh」的小bash腳本,用於檢查是否可以在文件「file.txt」中找到給腳本的第一個術語:如何防止在bash腳本中的代碼/選項注入

#!/bin/bash 

FILE="file.txt" 

if [ `grep -w "$1" $FILE` ]; then 
echo "true" 
else 
echo "false" 
fi 

但是,運行腳本類似

> ./isinFile.sh -x 

斷腳本,因爲-xgrep解釋爲一個選項。 所以我用--作爲參數傳遞給grep提高了我的腳本

#!/bin/bash 

FILE="file.txt" 

if [ `grep -w -- "$1" $FILE` ]; then 
echo "true" 
else 
echo "false" 
fi 

。現在正在運行

> ./isinFile.sh -x 
false 

的作品。但是使用--正確且唯一的方法來阻止bash腳本中的代碼/選項注入?我沒有看到它在野外,只發現它在ABASH: Finding Bugs in Bash Scripts中提到。

+1

爲什麼在'['中使用反引號而不是直接使用'grep -q'? – 2010-06-10 08:51:16

+0

我嘗試了你的建議,但是 'if [grep -q -w - 「$ 1」$ ACCOUNTS_DGRID]; '不適合我。我得到錯誤,如'./isinFile.sh:第5行:[:太多參數' – asmaier 2010-06-10 09:04:08

+0

他的意思是沒有方括號,也:'如果grep -q -w - 「$ 1」$ ACCOUNTS_DGRID' – 2010-06-10 12:46:53

回答

2
grep -w -- ...

防止在下面這種解釋 -

編輯

(我沒看過的最後一部分抱歉)。是的,這是唯一的方法。另一種方法是避免它作爲搜索的第一部分;例如".{0}-x"也有效,但它很奇怪。

grep -w ".{0}$1" ...

也應該工作。

+0

__important note__ {}使用擴展正則表達式,因此添加-E選項; (對不起,我把grep命名爲grep -E所以在開始時並沒有注意到) – ShinTakezou 2010-06-10 09:04:47

+0

你可以在基本的正則表達式(至少在我測試過的grep的實現中)通過轉義大括號來做到這一點:'grep - w「。\ {0 \} $ 1」...' – 2010-06-11 02:44:41

+0

到ShinTakezou:你有另外一個參考,其中描述了'--'-選項嗎?或者你是否知道用於描述「 - 」的技術術語,以便搜索它? – asmaier 2010-06-11 08:02:10

1

雖然並不適用於這種特殊情況下,另一種技術可以用來防止用連字號被解釋爲選項文件名:

rm ./-x 

rm /path/to/-x 
+1

要以編程方式應用此修復程序,請使用如下形式:'[「$ {FILE:0:1} = - ] && FILE =」./$ FILE「(即如果FILE以破折號開頭,它) – 2010-06-11 02:49:28

+0

@戈登:Bash:'[[$ FILE == - *]] ...' – 2010-06-11 06:33:26

2

其實還有另一種代碼注入(或任何你想要調用它的)在這個腳本中的錯誤:它只是將grep的輸出傳遞給[(又名test)命令,並且假定如果它不爲空則返回true。但是,如果輸出長度超過一個「單詞」,[會將其視爲表達式並嘗試對其進行評估。例如,假設文件包含行0 -eq 2,並且您搜索「0」 - [將決定0不等於2,並且該腳本將打印出假,儘管它發現匹配。

解決這個問題的最好方法是使用伊格納西奧巴斯克斯 - 艾布拉姆斯建議(如澄清丹尼斯威廉姆森) - 這完全避免了分析問題,並且速度也更快(因爲-q使得grep停在第一場比賽搜索)。如果該選項不可用,另一種方法是用雙引號保護輸出:if [ "$(grep -w -- "$1" "$FILE")" ]; then(請注意,我也使用$()而不是反引號,因爲我發現它們更容易閱讀,並且引用$ FILE如果它包含任何有趣的東西,如空白)。