這是PHAN的插件,以嘗試檢測安全問題(例如XSS)。它可以跟踪用戶可以修改變量的任何時間,並檢查以查看此類變量在輸出之前被逃脫為HTML或用作SQL查詢,等等。
它支持通用的PHP項目,並且還具有用於MediaWiki代碼的專用模式(分析掛鉤,HTMLFORM和數據庫方法)。
可以使用網絡演示。
$ composer require --dev mediawiki/phan-taint-check-plugin
該插件可在“手動”和“獨立”模式下使用。如果您的項目已經運行Phan,那麼前者是最佳選擇,幾乎不需要配置。僅當您不想在項目中添加PHAN並且不支持與MediaWiki相關的代碼,才應使用後者。有關Wikimedia使用此插件的更多信息,請參見https://www.mediawiki.org/wiki/phan-taint-check-plugin。
您只需將污染檢查添加到phan配置的plugins部分即可。假設Taint-Check在標準供應商位置,例如$seccheckPath = 'vendor/mediawiki/phan-taint-check-plugin/'; ,要包含的文件是通用項目的"$seccheckPath/GenericSecurityCheckPlugin.php"和"$seccheckPath/MediaWikiSecurityCheckPlugin.php" 。
另外,請確保禁用快速模式,否則插件將無法正常工作:
' quick_mode ' => false您還應將SecurityCheck-LikelyFalsePositive和SecurityCheck-PHPSerializeInjection添加到suppress_issue_types (後者俱有很高的誤報率)。
然後像往常一樣運行phan:
$ vendor/bin/phan -d . --long-progress-bar
使用--analyze-twice運行PHAN將捕獲其他安全問題,而在正常分析階段可能不會忽略的安全問題。對此的一個已知限制是,通過不同的線路可能會報告相同的問題。
您可以通過:
$ ./vendor/bin/seccheck
您可能需要為此添加一個作曲家腳本別名:
"scripts" : {
"seccheck" : " seccheck "
}請注意,默認情況下,誤報將被禁用。
該插件將根據檢測到的內容輸出各種問題類型。它輸出的問題類型是:
SecurityCheck-XSSSecurityCheck-SQLInjectionSecurityCheck-ShellInjectionSecurityCheck-PHPSerializeInjection對於某人進行unserialize( $_GET['d'] );目前,此問題類型似乎具有很高的誤報利率。SecurityCheck-CUSTOM1允許人們擁有自定義污染類型SecurityCheck-CUSTOM2 -DittoSecurityCheck-DoubleEscaped檢測HTML是否被雙重逃脫SecurityCheck-RCE遠程代碼執行,例如eval( $_GET['foo'] )SecurityCheck-PathTraversal路徑遍歷,例如require $_GET['foo']SecurityCheck-ReDoS則表達式拒絕服務(重做),例如preg_match( $_GET['foo'], 'foo')SecurityCheck-LikelyFalsePositive潛在的問題,但可能沒有。通常,當插件混淆時會發生。嚴重性字段通常被標記為Issue::SEVERITY_NORMAL (5) 。誤報會出現Issue::SEVERITY_LOW (0) 。可能導致服務器妥協的問題(與最終用戶妥協相對),例如Shell或SQL注入,被標記為Issue::SEVERITY_CRITICAL (10) 。序列化注射通常是“關鍵的”,但目前將其表示為正常的嚴重性,因為該檢查目前似乎具有很高的假陽性率。
您可以使用PHAN的-y命令行選項來通過嚴重性過濾。
如果您需要抑制假陽性,則可以將@suppress NAME-OF-WARNING列入函數/方法放置。另外,您可以使用其他類型的抑製作用,例如@phan-suppress-next-line 。有關完整列表,請參見Phan的Readme。 @param-taint和@return-taint (請參閱“自定義”部分)在處理誤報方面也非常有用。
請注意,該插件將在CLI上下文中報告可能的XSS漏洞。為了避免它們,如果應用程序僅由CLI腳本組成,則可以在CLI腳本中使用@phan-file-suppress抑制SecurityCheck-XSS在CLI腳本中的 @Phan-file-suppress(使用phan-file-suppress),或用於整個應用程序(使用suppress_issue_types config)。另外,如果所有輸出都來自內部功能,則可以使用@param-taint如下:
/**
* @param-taint $stuffToPrint none
*/
public function printMyStuff ( string $ stuffToPrint ) {
echo $ stuffToPrint ;
}調試安全性問題時,您可以使用:
'@phan-debug-var-taintedness $varname';
這將散發出一個SecurityCheckDebugTaintedness問題,該問題包含$varname在找到註釋的行中的污染。請注意,您必須將註釋插入字符串文字;評論將行不通。另請參見Phan的@phan-debug-var註釋。
@return-taint html 。IDatabase::select()的第五( $options )和第六( $join_cond ),或直接從getQueryInfo()方法中返回。 通過將SecurityCheckPlugin類子類分類,該插件支持被自定義。有關這樣做的複雜示例,請參見MediaWikiseCurityCheckplugin。
有時,您的代碼庫中有可以改變變量的污點的方法。例如,自定義的HTML逃脫功能應清除HTML污染位。同樣,有時Phan-taint-Check可能會感到困惑,並且您想覆蓋針對特定功能計算的污點。
您可以通過在DocBlock評論中添加污點指令來做到這一點。例如:
/**
* My function description
*
* @param string $html the text to be escaped
* @param-taint $html escapes_html
*/
function escapeHtml ( $ html ) {
}方法還從祖先界面中的抽象定義繼承了這些指令,而不是祖先類中的具體實現。
污點指令以@param-taint $parametername或@return-taint前綴為前綴。如果有多個指令,則可以通過逗號分隔。 @param-taint用於標記如何從參數傳輸到方法返回值的污點,或者與exec_指令一起使用,以標記輸出/執行參數的位置。 @return-taint用於調整返回值的污點,無論輸入參數如何。
指令的類型包括:
exec_$TYPE如果將參數標記為exec_$TYPE ,則用$TYPE污染的值饋送該值將導致警告觸發。通常,當輸出或執行其參數的函數時,您會使用它escapes_$TYPE用於函數逃逸然後返回參數的參數。因此, escapes_sql會清除SQL調味位,但請留下其他污點。onlysafefor_$TYPE - 用於@return-taint中,將返回類型標記為特定$TYPE的安全性,但對於其他類型來說是不安全的。$TYPE如果僅在參數中指定類型,則將其貼合,並帶有輸入變量的污點。通常,您不想這樣做,但是當$TYPE none指定參數不用於生成返回值時,可能會很有用。在@return中,這可以用來枚舉返回值的污點,這通常只有在被指定為tainted說明它具有所有標誌時才有用。array_ok特殊目的標誌,說明如果它們在數組中,則忽略污染的論點。allow_override特殊目的標誌,以指定phan-taint-check的污點註釋是否可以檢測到特定的污點。 $TYPE的值可以是htmlnoent , html , sql , shell , serialize ,sustomize, custom1 , custom2 ,code2, code , path ,path, regex , sql_numkey , escaped ,encaped,note, none ,noted tainted 。其中大多數是污染類別,但以下除外:
htmlnoent - 像html一樣,但禁用與html一起使用的雙逃逸檢測。當指定escapes_html時,將自動添加到@return ,然後將exec_escaped添加到@param中。同樣, onlysafefor_html等效於onlysafefor_htmlnoent,escaped 。none - 意味著沒有污點tainted - 表示除特殊類別以外的所有污點類別(相當於SecurityCheckPlugin::YES_TAINT )escaped - 用來表示該值已經逃脫(跟踪雙逃逸)sql_numkey對於MediaWiki來說是相當特殊的目的。如果它們是用於關聯鍵,它會忽略dant在陣列中。 @param-taint的默認值如果是字符串(或其他危險類型),則會tainted ,如果它是整數,則none 。 @return-taint的默認值是allow_override (除非可以自動進行更好的none )。
您還可以自定義phan-taint-check中的phan-taint-check,以對方法污染具有內置的知識,而不是在代碼庫中註釋方法。另外,您可以擴展插件以具有相當任意的行為。
為此,您覆蓋getCustomFuncTaints()方法。此方法將完全合格的方法名稱的關聯數組返回到一個數組,描述了該函數的返回值如何根據其參數的污染。數字鍵對應於一個參數的數量,並且“總體”密鑰添加了任何參數中不存在的污點。基本上,對於每個參數,該插件將參數的污點(刻度)帶到了數組中,然後將其輸入到位置,然後將其變為位置,或者是整體鍵。如果數組中的任何鍵都具有EXEC標誌,則如果將相應的污點饋送為函數(例如,輸出函數),則立即提出問題。執行標誌在“總體”密鑰中無法使用。
例如,刪除HTML污染,逃脫其論點並返回逃脫價值的HTMLSpecialChars看起來像:
' htmlspecialchars ' => [
( self :: YES_TAINT & ~ self :: HTML_TAINT ) | self :: ESCAPED_EXEC_TAINT ,
' overall ' => self :: ESCAPED ,
];以下環境變量會影響插件。通常,您不必調整這些。
SECURITY_CHECK_EXT_PATH在媒體維基模式下時,通往extension.json / skin.json目錄的路徑。如果未設置,則假定項目根目錄。SECCHECK_DEBUG文件輸出額外的調試信息(如果從shell運行, /dev/stderr很方便) GNU通用公共許可證,第2版或更高版本