这是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版或更高版本