2012-10-23 57 views
2

在Perl中編寫代碼時應該真的使用外部命令嗎?我看到它的幾個缺點。它不是系統獨立的,加上安全風險也可能存在。你怎麼看?如果沒有辦法,並且必須使用Perl的shell命令,那麼執行該特定命令的最安全方法是什麼(如檢查pid,uid等)?在Perl中編碼時安全地執行系統命令

回答

6

這取決於在Perl中複製功能的難度。如果我需要運行m4宏處理器,我不想嘗試在Perl中自己複製該功能,並且因爲http://search.cpan.org/上沒有模塊,所以看起來合適,但其他人會同意我的看法。那樣的話,使用外部程序是明智的。另一方面,如果我需要讀取目錄的內容,那麼Perl內部的readdir()等加上stat()lstat()的組合比打開ls的輸出更合理。

如果您需要執行命令,請仔細考慮如何調用它們。特別是,您可能希望避免shell解釋參數,因此請使用system(另請參閱exec)等數組形式,而不是命令加參數的單個字符串(這意味着shell用於處理命令線)。

2

執行外部命令的代價可能很高,因爲它涉及分叉新進程並在需要時監視其輸出。

可能更重要的是,如果外部過程因任何原因失敗,可能很難通過腳本理解發生了什麼。更糟糕的是,令人驚訝的是,外部過程經常會永久停留,所以會是你的腳本。你可以使用特殊的技巧,例如打開管道和在循環中觀察輸出,但是這本身很容易出錯。

Perl能夠做很多事情。因此,如果您堅持只使用Perl本機構造和模塊來完成您的任務,不僅因爲您永遠不會分叉,速度會更快,而且通過查看返回的本地Perl對象和結構來捕獲錯誤更可靠,更容易庫例程。當然,它會自動移植到不同的平臺上。

如果您的腳本在提升的權限下運行(如root或sudo下),您應該非常小心執行哪些外部程序。確保基本安全性的一個簡單方法是始終使用全名來指定命令,例如/ usr/bin/grep(但仍然會考慮兩次,並且僅由Perl本身執行grep!)。但是,如果攻擊者正在使用LD_PRELOAD機制注入惡意共享庫,這甚至可能不夠。

如果你願意去很安全,建議使用-T標誌像這樣使用受污染的檢查:

#!/usr/bin/perl -T 

污點標誌將被Perl也自動啓用,如果你的腳本被確定有不同的真實和有效的用戶或組ID。

受感染的模式將嚴重限制您在沒有Perl抱怨的情況下執行許多事情(如system()調用)的能力 - 請參閱http://perldoc.perl.org/perlsec.html#Taint-mode更多內容,但它會爲您提供更高的安全性。

+0

是污染模式會更加嚴格和安全的方式。 –

1

應該在Perl中編碼時真的使用外部命令嗎?

這個問題沒有單一的答案。這完全取決於您在Perl的廣泛潛在用途中所做的事情。

你是否在你的本地機器上使用Perl作爲美化的shell腳本,或者只是試圖爲你的問題找到一個快速而又髒的解決方案?在這種情況下,如果這是完成任務的最簡單方法,那麼運行系統命令就很有意義。安全性和速度並不那麼重要。重要的是快速編碼的能力。

另一方面,你在寫一個生產程序嗎?在這種情況下,您需要安全,便攜,高效的代碼。通常最好在Perl中編寫功能(或使用模塊),而不是調用外部程序。至少,你應該認真思考好處和缺點。