第九章 管理真實的程序(九) -污染模式

污染模式

Perl中的一些特性可以幫助你寫出安全的程序。當然這些手段無法取代細致的思考和規(guī)劃,但是能幫助你避免一些微妙的錯誤。

所謂污染模式就是對所有來自程序之外數(shù)據(jù)附加上一個元數(shù)據(jù)以便來跟蹤它們。從被污染的數(shù)據(jù)(臟數(shù)據(jù))中生成出來的數(shù)據(jù)也是被污染的。你可以在程序中使用被污染的數(shù)據(jù),但是如果使用臟數(shù)據(jù)會影響程序之外的內容(不安全的使用方式),Perl就會拋出致命異常。

使用污染模式

perldoc perlsec介紹了污染模式的具體細節(jié)。

使用命令行參數(shù)-T就會啟動污染模式。如果-T寫在#!行當中,就必須直接運行程序,如果你忽略-T標志使用perl mytaintedappl.pl來啟動程序,Perl就會拋出異常并退出。

污染源

污染來自2個地方:文件輸入和程序環(huán)境。前者就是指你從文件讀到的或從網(wǎng)站、網(wǎng)絡用戶那收集到的內容。后者包括所有的命令行參數(shù)、環(huán)境變量和來自于系統(tǒng)調用的數(shù)據(jù),甚至從目錄句柄中讀取到的數(shù)據(jù)也是被污染的。

核心模塊Scalar::Util中的函數(shù)tainted()用于測試是否被污染,如果參數(shù)是被污染的就返回真:

die 'Oh no! Tainted data!' if Scalar::Util::tainted( $suspicious_value );

從數(shù)據(jù)中解除污染

要凈化數(shù)據(jù)你就必須精確地提取數(shù)據(jù)中好的部分。比如如使用正則表達式來捕獲,捕獲到的數(shù)據(jù)就是干凈數(shù)據(jù)。例如,如用戶輸入中包含電話號碼,你可以這樣解除污染:

die 'Number still tainted!' unless $number =~ /(\(/d{3}\) \d{3}-\d{4})/;

my $safe_number = $1;

匹配的模式越細致,你的程序就越安全。相反的做法是拒絕指定的項目或忽略風險而運行。當然你也可以捕獲整個值來解除污染,但是這樣就失去了使用污染模式的價值。

從環(huán)境中解除污染

全局變量%ENV里面有程序所在系統(tǒng)的環(huán)境變量。該變量是被污染的,原因是程序之外的力量可以操縱該值。環(huán)境變量控制著Perl或shell如何定位文件和目錄,這也是一個攻擊向量。一個安全敏感的程序應該刪除%ENV中的一些鍵,并且設置$ENV{PATH}到一個安全的路徑:

delete @ENV{ qw( IFS CDPATH ENV BASH_ENV ) };
$ENV{PATH} = '/path/to/app/binaries/';

如果$ENV{PATH}設置的不當就會收到報告其不安全的消息。如果環(huán)境變量包含了當前工作目錄,或者包含了相關目錄,或者指定的目錄是全局可寫的權限,那么聰明的攻擊者就可以劫持系統(tǒng)調用來進行惡意攻擊。

出于類似的原因,@INC在污染模式下并不包含當前工作目錄。Perl也會忽略PERL5LIB和PERLLIB環(huán)境變量。使用lib編譯指示或者使用-l標志來添加庫目錄到程序。

常見陷阱

污染模式只有打開和關閉2種狀態(tài),也就是要么全有要么全無。有時候需要部分解除污染的時候,就會有人過度放開(比如之前的全面捕獲),這時候污染模式就沒有起到應有的作用,所以要仔細審查污染解除的規(guī)則。

不幸的是,并不是所有模塊都會妥善處理被污染的數(shù)據(jù),CPAN作者應認真對待這個BUG。如果面對的是歷史遺留代碼,你可以考慮使用-t標志,這個標志會啟用污染模式但是會將違規(guī)的告警從異常降為警告(也就是不再退出),但這個并不是完整的污然模式。(在不能使用完整污染模式下的一種折中方案)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容