PHP项目代码审计与Fortify

wen PHP项目 3

本文目录导读:

PHP项目代码审计与Fortify

  1. Fortify在PHP审计中的核心能力与局限
  2. Fortify扫描前的环境准备
  3. Fortify报告的关键PHP漏洞类型分析
  4. 人工审计的重点补充区域
  5. 修复建议与验证闭环
  6. 自动化审计脚本示例

针对PHP项目的代码审计,特别是使用Fortify这类静态应用安全测试(SAST)工具,需要结合工具的特点和PHP语言的特性来进行,以下是一套系统性的操作指南和关注重点:

Fortify在PHP审计中的核心能力与局限

核心能力:

  • 数据流分析:追踪用户输入($_GET$_POST$_COOKIE)到敏感函数(evalmysql_queryinclude)的路径。
  • 语义分析:识别PHP特有漏洞模式(如变量覆盖、Type Juggling)。
  • 配置识别:自动识别php.ini中的危险配置(如allow_url_fopen=On)。

主要局限:

  • 动态调用:难以处理可变函数($func())、call_user_func、反射API。
  • 加密/混淆代码:无法分析eval(base64_decode(...))这种多层编码。
  • 框架特性:对Laravel的Facade、Symfony的Dependency Injection等高级特性支持不完整。

Fortify扫描前的环境准备

项目配置优化

<!-- fortify-sca.properties -->
com.fortify.sca.ProjectRoot=/path/to/php/project
com.fortify.sca.PhpVersion=8.1
com.fortify.sca.EnableDynamicCodeAnalysis=false
com.fortify.sca.EnableControlFlowSensititivity=true
  • 禁用动态分析:避免对eval等执行大量假阳性探查。
  • 设置PHP版本:新版本(7.4+)的空安全运算符、属性类型提示等语法需要对应版本解析器。

依赖库处理

# 将第三方库移出扫描范围,避免噪音
--exclude "vendor/" --exclude "node_modules/" --exclude "public/assets/"

Fortify报告的关键PHP漏洞类型分析

高危漏洞(需100%人工复核)

漏洞类型 Fortify典型规则ID 示例代码 审计要点
SQL注入 SQL Injection $sql = "SELECT * FROM users WHERE id = " . $_GET['id']; 检查是否使用预处理语句(PDO/MySQLi)
命令注入 Command Injection exec("ping " . escapeshellcmd($_GET['ip'])); escapeshellcmd不够安全,应用escapeshellarg
文件包含 Path Manipulation include("/var/www/".$_GET['page'].".php"); 检查是否有basename()或白名单验证
反序列化 Insecure Deserialization $obj = unserialize($_COOKIE['data']); 确认是否使用了allowed_classes参数
SSRF URL Redirector Abuse file_get_contents($_POST['url']); 检查是否有域名白名单或协议限制

典型误报处理

  • Type Juggling误报if ($_GET['auth'] == "admin") 会被标记为弱比较,但若输入仅为字符串则无害。
  • Header Injection误报header("Location: ".$user_input) 若输入经urlencode()处理则为误报。
  • Cookie Security:未设置HttpOnly标记时,若框架默认添加(Laravel默认开启),可标记为已修复。

人工审计的重点补充区域

Fortify遗漏的常见PHP安全场景:

伪全局变量覆盖

extract($_GET);  // Fortify可能标记,但常误报
// 以下代码Fortify可能忽略:
foreach ($_GET as $key => $value) { $$key = $value; }

审计:检查extractparse_strimport_request_variables的使用。

Phar反序列化漏洞

$phar = new Phar('test.phar');
// 当phar文件内容可控时,触发phar://反序列化

审计:所有file_existsis_dir等文件操作函数若参数含phar://则危险。

PHP-FPM配置错误

; Fortify无法检测
security.limit_extensions = .php ; 允许上传.php文件

审计:检查Nginx/Apache配置是否限制上传目录的PHP执行权限。

修复建议与验证闭环

修复优先级矩阵

高影响 + 低利用难度 = 立即修复(如未过滤的$_GET直接拼接SQL)
高影响 + 高利用难度 = 重点规划(如反序列化需要特定类存在)
低影响 + 高利用难度 = 记录但不紧急(如某页面URL重定向的开放重定向)

验证步骤:

  1. 重新扫描:修复后对修改文件增量扫描,确认漏洞归零。
  2. 渗透测试:Burp Suite验证:
    • 发送?id=1' OR '1'='1确认SQL注入
    • 发送?file=../../etc/passwd确认路径穿越
  3. 代码审查:人工检查修复是否引入新问题(如过滤过于严格导致功能异常)。

自动化审计脚本示例

结合Fortify结果,使用PHP_CodeSniffer自定义规则:

// 自定义嗅探规则:禁止使用双引号中的变量
$sniff = new PHP_CodeSniffer();
$sniff->registerRule('Generic.PHP.DisallowDoubleQuoteVariable');

集成CI/CD

# GitLab CI
php-audit:
  script:
    - sourceanalyzer -b myapp -scan -f results.fpr
    - BIRTReportGenerator -format PDF -source results.fpr -output report.pdf
  1. Fortify是高效的“警卫”而非“侦探”:它能快速发现明显的SQL注入、XSS,但需要人工补充审计动态调用和业务逻辑漏洞。
  2. 重点关注“输入流到输出流”的完整链路:即使看似安全的参数也可能通过$_SERVERgetenv()等间接来源进入危险函数。
  3. PHP版本适配:PHP8.0的match表达式、8.1的枚举类型可能绕过Fortify旧版规则,需升级扫描器。

建议定期运行以下命令生成增量报告以跟踪修复进度:

sourceanalyzer -b myapp -scan -f latest.fpr -filter "Category:SQL Injection"

抱歉,评论功能暂时关闭!