Fortify控制流巧用之XXE规则调试记录
字数 1518 2025-08-22 12:23:30
Fortify控制流规则在XXE漏洞检测中的应用与调试
1. 前言
Fortify静态代码扫描工具在执行扫描时会加载默认规则和自定义规则。当需要仅使用自定义规则进行扫描时,可以通过Fortify portal接口执行扫描并附加参数来丢弃默认规则的导入。本文详细记录XXE漏洞静态代码扫描规则的定义、使用、优化和调试过程。
2. 基础知识:控制流分析
控制流分析器通过将安全属性建模为状态机来检测不安全操作序列:
-
状态机组成:
- 初始状态(Initial state)
- 一个或多个错误状态(Error states)
- 任意数量的内部状态(Internal states)
-
工作原理:
- 函数开始时处于初始状态
- 当进入错误状态时报告漏洞
- 状态转换由程序构造的规则模式触发
- 按顺序检查转换,执行第一个匹配的语句
3. 控制流规则XML结构
控制流规则XML包含以下关键元素:
<?xml version="1.0" encoding="UTF-8"?>
<RulePack xmlns="xmlns://www.fortifysoftware.com/schema/rules">
<RulePackID>3E108F67-3116-481D-8C52-67C6E6939CE9</RulePackID>
<SKU>SKU-SAXParserXXE-rule</SKU>
<Name><![CDATA[SAXParserXXE-rule]]></Name>
<Version>1.0</Version>
<Rules version="3.2">
<RuleDefinitions>
<ControlflowRule formatVersion="22.1.0" language="java">
<MetaInfo></MetaInfo>
<RuleID>6FC83768-C5A0-0E26-044B-59E8A1EBA0BA</RuleID>
<VulnKingdom>Input Validation and Representation</VulnKingdom>
<VulnCategory>Resource Leak</VulnCategory>
<DefaultSeverity>2.0</DefaultSeverity>
<FunctionIdentifier id="XXX">
<NamespaceName><Pattern>xxx</Pattern></NamespaceName>
<ClassName><Pattern>xxx</Pattern></ClassName>
<FunctionName><Value>xxx</Value></FunctionName>
<ApplyTo implements="true" overrides="true" extends="true"/>
</FunctionIdentifier>
<FunctionCallIdentifier id="validateSetA">
<FunctionIdentifier>
<NamespaceName><Pattern>xxx</Pattern></NamespaceName>
...
关键XML元素说明
-
FunctionIdentifier:
- 标识函数
- 控制流规则可包含多个函数标识符
- 包含命名空间、类名和方法名定义
-
FunctionCallIdentifier:
- 结合FunctionIdentifier和Conditional元素
- 匹配对函数的特定调用
-
Definition:
- 包含控制流状态机定义
- 建议使用CDATA部分避免XML特殊字符转义问题
4. 规则定义:XXE漏洞示例
漏洞代码示例
package org.example;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.InputStream;
public class XmlSAXParserWithHandler {
public static void parse(InputStream xmlInput) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
/* 安全设置被注释掉
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
*/
SAXParser parser = factory.newSAXParser();
DefaultHandler handler = new DefaultHandler() {
// 处理XML元素的回调方法
};
parser.parse(xmlInput, handler);
}
}
关键匹配点分析
需要匹配的三个关键部分:
SAXParserFactory factory = SAXParserFactory.newInstance();SAXParser parser = factory.newSAXParser();parser.parse(xmlInput, handler);
规则定义步骤
第一阶段:函数匹配
定义三个关键函数的匹配规则:
<FunctionIdentifier id="factoryCreate">
<NamespaceName><Pattern>javax.xml.parsers</Pattern></NamespaceName>
<ClassName><Pattern>SAXParserFactory</Pattern></ClassName>
<FunctionName><Value>newInstance</Value></FunctionName>
<ApplyTo implements="true" overrides="true" extends="true"/>
</FunctionIdentifier>
<FunctionIdentifier id="parserCreate">
<NamespaceName><Pattern>javax.xml.parsers</Pattern></NamespaceName>
<ClassName><Pattern>SAXParserFactory</Pattern></ClassName>
<FunctionName><Value>newSAXParser</Value></FunctionName>
<ApplyTo implements="true" overrides="true" extends="true"/>
</FunctionIdentifier>
<FunctionIdentifier id="parserParse">
<NamespaceName><Pattern>javax.xml.parsers</Pattern></NamespaceName>
<ClassName><Pattern>SAXParser</Pattern></ClassName>
<FunctionName><Value>parse</Value></FunctionName>
<ApplyTo implements="true" overrides="true" extends="true"/>
</FunctionIdentifier>
第二阶段:状态机设计
XXE漏洞状态转换流程:
- 初始状态 → 创建factory
- 创建factory → 创建parser
- 创建parser → 执行parse(漏洞点)
状态机XML定义:
<Definition><![CDATA[
StateMachine: {
InitialState: Init;
States: {
Init: {
Transitions: {
factoryCreate -> FactoryCreated;
}
}
FactoryCreated: {
Transitions: {
parserCreate -> ParserCreated;
}
}
ParserCreated: {
Transitions: {
parserParse -> ErrorState;
}
}
ErrorState: {
Error: "XXE Injection Vulnerability Detected";
}
}
}
]]></Definition>
5. 规则扫描与验证
漏洞代码扫描结果
执行扫描后,Fortify会报告XXE注入漏洞,可通过检查RuleID确认是否由自定义规则检测到。
安全代码示例(误报问题)
public static void parse(InputStream xmlInput) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
// 添加安全设置
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
SAXParser parser = factory.newSAXParser();
// 其余代码...
}
初始规则会对安全代码也报告漏洞(误报),需要优化。
6. 规则优化
误报问题解决
添加对安全设置方法的检测:
- 添加FunctionCallIdentifier:
<FunctionCallIdentifier id="validateSetA">
<FunctionIdentifier>
<NamespaceName><Pattern>javax.xml.parsers</Pattern></NamespaceName>
<ClassName><Pattern>SAXParserFactory</Pattern></ClassName>
<FunctionName><Value>setFeature</Value></FunctionName>
</FunctionIdentifier>
<Conditional><![CDATA[
(arg[0]=="http://apache.org/xml/features/disallow-doctype-decl" && arg[1]==true) ||
(arg[0]=="http://xml.org/sax/features/external-general-entities" && arg[1]==false) ||
(arg[0]=="http://xml.org/sax/features/external-parameter-entities" && arg[1]==false)
]]></Conditional>
</FunctionCallIdentifier>
- 更新状态机:
<Definition><![CDATA[
StateMachine: {
InitialState: Init;
States: {
Init: {
Transitions: {
factoryCreate -> FactoryCreated;
}
}
FactoryCreated: {
Transitions: {
validateSetA -> SafeState;
parserCreate -> ParserCreated;
}
}
ParserCreated: {
Transitions: {
parserParse -> ErrorState;
}
}
SafeState: {
// 安全状态,不报告漏洞
}
ErrorState: {
Error: "XXE Injection Vulnerability Detected";
}
}
}
]]></Definition>
漏洞级别调整
通过MetaInfo元素调整漏洞严重性:
<MetaInfo>
<Group name="Accuracy" value="4"/> <!-- 高准确性 -->
<Group name="Impact" value="4"/> <!-- 高影响力 -->
<Group name="Probability" value="4"/> <!-- 高发生概率 -->
</MetaInfo>
<DefaultSeverity>4.0</DefaultSeverity> <!-- 调整为High -->
评分标准:
- Accuracy(0-5): 准确性
- 4-5: 高准确性,误报率低
- Impact(0-5): 影响力
- 4-5: 高影响力,可导致严重问题
- Probability(0-5): 发生概率
- 4-5: 高概率,易被利用
修复建议完善
添加规范的漏洞描述和修复建议:
<Description><![CDATA[
XXE (XML External Entity) injection vulnerability occurs when XML input containing
a reference to an external entity is processed by a weakly configured XML parser.
]]></Description>
<Recommendations><![CDATA[
To prevent XXE injection:
1. Disable DTDs (doctypes):
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
2. Disable external entities:
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
]]></Recommendations>
7. 最终优化后的规则
整合所有优化点后的完整规则包含:
- 精确的函数匹配定义
- 完善的状态机设计(包含安全状态)
- 适当的漏洞级别设置
- 详细的漏洞描述和修复建议
8. 总结与最佳实践
-
规则编写流程:
- 分析漏洞代码模式
- 定义关键函数匹配
- 设计状态转换流程
- 测试并优化误报/漏报
-
评估规则质量:
- 对存在漏洞的代码能准确检测
- 对添加防护的安全代码不误报
- 漏洞级别设置合理
- 提供有效的修复建议
-
扩展应用:
- 类似方法可用于其他类型漏洞的规则编写
- 根据具体风险代码调整规则逻辑
- 结合多种规则类型提高检测覆盖率
通过控制流规则可以有效地建模复杂的安全问题检测逻辑,特别适合需要跟踪多个函数调用序列的漏洞模式检测。