Qodana
The code quality platform for teams
通过 Qodana 的污点分析保护 PHP 代码
本文由 JetBrains 的代码质量平台 Qodana 提供。 该平台旨在将服务器端静态分析引入您的首选 CI 工具。 Qodana 使用与 PhpStorm 和其他 JetBrains IDE 相同的代码检查和配置文件,有助于确保在 IDE 和 CI 环境中实现一致的代码质量检查。
只要一个用户就可以利用项目中的漏洞破坏系统。 为了保护程序免受来自外部用户的恶意输入(即“污点”),开发团队可以将污点检查添加到静态分析例程中。
在今年的第一个版本中,Qodana 团队在 EAP 中为 PHP 提供了污点分析。 该功能仅在 Qodana for PHP 2023.1 (jetbrains/qodana-php:2023.1-eap) 中可用。 Qodana for PHP 是我们发布的第一个 linter,因此我们决定让 PHP 开发者也率先测试我们的新安全功能。 未来,我们计划在收集到足够的反馈后添加更多语言。
下文将详细介绍污点分析及其在 Qodana 中的运作方式。
什么是污点分析?
污点是由外部用户修改后可能造成安全风险的值。 如果代码中存在污点,并且未经验证的外部数据可以分布在程序中,黑客可以执行这些代码段,导致 SQL 注入、算术溢出、跨站脚本攻击、路径遍历等。 他们通常利用这些漏洞破坏系统、劫持凭据和其他数据,并改变系统的行为。
作为针对恶意输入的额外保护层,开发团队在对程序的攻击面进行安全审核时可以执行污点分析。
污点分析是评估整个函数或方法主体中不可信的用户输入流的过程。 它的核心目标是确定意外输入是否会以恶意方式影响程序执行。
污点源是程序访问潜在污染数据的位置。 程序中易受污染输入影响的关键点称为污点汇聚点。 此数据可以通过函数调用或赋值传播到汇聚点。
如果手动运行污点分析,您应该找出所有从外部用户接收数据的位置,并跟踪数据在系统中的分布 – 受污染的数据可能用于数十个节点。 然后,为了防止污点传播,您应该采用以下两种方式之一:
- 净化数据,将数据转换为安全状态。 在下面的示例中,我们移除了标记以解析污点。
- 验证数据,检查添加的数据是否符合所需模式。 在下面的示例中,我们启用了对
$
email
变量的验证。
也就是说,污点分析检查会从源头到汇聚点跟踪用户污染的数据,并在您未净化或验证数据的情况下使用数据时发出警报。
污点分析在 Qodana 中的运作方式
从 2023.1 EAP 版本开始,污点分析由 Qodana for PHP 执行。 此功能包括扫描代码并高亮显示污点和潜在漏洞的检查、在 PhpStorm 中打开问题以当场解决的功能,以及呈现污点流的数据流图。
示例 1. SQL 注入
我们来看看 SQL 注入的示例以及 Qodana 如何检测:
在这里,Qodana 展示了 system_admin() 函数中的以下污点:
标记 1-2:用户表单输入中的数据检索自 $
_POST
全局数组,没有净化或验证,并被赋给变量 $
edit
。 这是一个污点。
标记 3:受污染的变量 $
edit
作为实参传递给 system_save_settings
函数,没有经过适当净化。
标记 4:来自 $
edit
变量的数据现在位于 $
edit
形参中。
标记 5:$
edit
变量以 $
filename
键和 $
status
值传递给 foreach
。 这两个变量都包含来自与字符串串联的 $
edit
变量的受污染数据。 $
filename
键与受污染的 SQL 字符串串联,然后它将受污染的数据传播到传递给 db_query
的实参。
标记 6:$
filename
键包含来自与字符串串联的 $
edit
变量的受污染数据。
标记 7:$
filename
键与受污染的 SQL 字符串串联。
标记 8:受污染的 SQL 字符串将受污染的数据传播到传递给 db_query
的实参
现在,我们来看看 db_query
:
标记 9:受污染的字符串将位于 $
query
形参中。
标记 10:此形参将成为 _db_query
函数的实参。
接下来是 _db_query
函数:
标记 11:位于 _db_query
函数的第一个形参 $
query
中的受污染数据。
标记 12:形参的数据被传递给 mysql_query
函数,它是一个汇聚点。
上面的整个数据流说明了数据如何在没有净化或验证的情况下从 $
_POST[“edit”]
移动到 mysql_query($query)
。 这就让攻击者可以操纵与 $
_POST[“edit”]
键串联的 SQL 查询并触发 SQL 注入。
Qodana 会在代码库以及所有使用受污染数据的节点中发现这些风险,让您可以及时净化所有受污染数据。
示例 2. XSS 问题
在 Qodana UI 中,您可以看到呈现整个污点流的图表。 以下说明了 Qodana 将如何呈现 XSS 漏洞,其中包含 2 个将在标记 5 上合并的源。
源 1
标记 1-2:searchUpdate.pos 文件中的数据将被读取,受污染的数据将被被赋给 $
start
变量。
源 2
标记 3-4:取路径位于 $
posFile
中的文件中的数据将被读取,受污染的数据将被赋给 $
start
变量。
标记 5:$
start
变量中所有条件分支的合并污染状态将作为实参传递给 doUpdateSearchIndex
方法。
来看 doUpdateSearchIndex()
方法的内部:
标记 6-8:$
start
形参将包含这个数据流切片上的受污染数据,然后它将在串联的字符串中作为实参传递给 output
方法。
看一下 output
方法:
标记 9:传输字符串中包含的受污染数据将位于 $
out
形参中。
标记 10:来自 $
out
形参的数据将被传输到 print
函数,不进行净化。 这个函数是一个汇聚点,会导致可被利用的 XSS 漏洞。
例如,为了利用漏洞,攻击者可以上传 shell 脚本而不是标记 1 和 2 中的预期文件,并且由于未净化的 print 函数,攻击者能够将任何信息放到网页上。
Qodana 会提醒您注意这个漏洞,并给予高优先级,让您尽快解决,防止遭受攻击。
结论
污点分析有助于消除可被利用的攻击面,是降低软件风险的有效方法。 要详细了解污点分析和 Qodana,请浏览 Qodana 文档。
祝您开发愉快并保持代码健康!
本博文英文原作者: