2014-10-28 63 views
0
is_exec = lambda x: subprocess.call("type " + x, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0 and (os.path.isfile(x) and os.access(x, os.X_OK)) 

我碰到過這段代碼,它工作正常,但它是多餘的嗎?Python:檢查可執行文件

Isnt is_exec = lambda x: os.access(x, os.X_OK)足夠嗎?

問:有沒有is_exec = lambda x: os.access(x, os.X_OK)沒有捕獲但第一個呢?

+0

我很確定它是多餘的。這兩段代碼都可以正常工作。只有第二個更簡潔。不同之處在於其中一個實際進行測試,另一個檢查屬性。此外,無論如何避免第一個,因爲它可能容易受到任意代碼執行。 – 2014-10-28 18:01:45

+1

如果你沒有仔細審查'x'的值,第一個看起來像後門。 – chepner 2014-10-28 18:03:41

回答

1

這裏有一個微妙的不同 - 在第一個呼叫,這也將檢測殼內置插件,例如:

$ type cd 
cd is a shell builtin 
$ echo $? 
0 

但沒有實際cd可執行文件等,所以你可以」請用os.access()明確檢查。不過,我認爲它實際上應該是

is_exec = lambda x: subprocess.call("type " + x, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0 or (os.path.isfile(x) and os.access(x, os.X_OK)) 

需要注意的是中間運營商現在or。另外,這裏的子過程管看起來有些多餘,並且有一點需要注意,它可以用作殼注入來考慮。總而言之,如果你只關心驗證可執行的文件,那麼開溝第一位就可以了。

1

兩者都要求os.access(x, os.X_OK)返回True。但是,除了在致電os.access之前執行一些不必要的測試之外,第一次打開殼體注入攻擊,除非您在使用之前仔細檢查了值x。使用shell=Truesubprocess.call只是將一個字符串傳遞給shell執行。如果仔細構建了x的值,則最終執行的不僅僅是命令type。例如:

x = "somefile.txt; rm foo.txt" 
subprocess.call("type " + x, shell=True, 
       stdout=subprocess.PIPE, stderr=subprocess.PIPE) 

將字符串「類型somefile.txt; RM foo.txt的」傳遞到外殼,從而導致兩個命令,而不是一個,在正在執行。