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元素说明

  1. FunctionIdentifier

    • 标识函数
    • 控制流规则可包含多个函数标识符
    • 包含命名空间、类名和方法名定义
  2. FunctionCallIdentifier

    • 结合FunctionIdentifier和Conditional元素
    • 匹配对函数的特定调用
  3. 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);
    }
}

关键匹配点分析

需要匹配的三个关键部分:

  1. SAXParserFactory factory = SAXParserFactory.newInstance();
  2. SAXParser parser = factory.newSAXParser();
  3. 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漏洞状态转换流程:

  1. 初始状态 → 创建factory
  2. 创建factory → 创建parser
  3. 创建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. 规则优化

误报问题解决

添加对安全设置方法的检测:

  1. 添加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>
  1. 更新状态机:
<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. 最终优化后的规则

整合所有优化点后的完整规则包含:

  1. 精确的函数匹配定义
  2. 完善的状态机设计(包含安全状态)
  3. 适当的漏洞级别设置
  4. 详细的漏洞描述和修复建议

8. 总结与最佳实践

  1. 规则编写流程

    • 分析漏洞代码模式
    • 定义关键函数匹配
    • 设计状态转换流程
    • 测试并优化误报/漏报
  2. 评估规则质量

    • 对存在漏洞的代码能准确检测
    • 对添加防护的安全代码不误报
    • 漏洞级别设置合理
    • 提供有效的修复建议
  3. 扩展应用

    • 类似方法可用于其他类型漏洞的规则编写
    • 根据具体风险代码调整规则逻辑
    • 结合多种规则类型提高检测覆盖率

通过控制流规则可以有效地建模复杂的安全问题检测逻辑,特别适合需要跟踪多个函数调用序列的漏洞模式检测。

Fortify控制流规则在XXE漏洞检测中的应用与调试 1. 前言 Fortify静态代码扫描工具在执行扫描时会加载默认规则和自定义规则。当需要仅使用自定义规则进行扫描时,可以通过Fortify portal接口执行扫描并附加参数来丢弃默认规则的导入。本文详细记录XXE漏洞静态代码扫描规则的定义、使用、优化和调试过程。 2. 基础知识:控制流分析 控制流分析器通过将安全属性建模为状态机来检测不安全操作序列: 状态机组成 : 初始状态(Initial state) 一个或多个错误状态(Error states) 任意数量的内部状态(Internal states) 工作原理 : 函数开始时处于初始状态 当进入错误状态时报告漏洞 状态转换由程序构造的规则模式触发 按顺序检查转换,执行第一个匹配的语句 3. 控制流规则XML结构 控制流规则XML包含以下关键元素: 关键XML元素说明 FunctionIdentifier : 标识函数 控制流规则可包含多个函数标识符 包含命名空间、类名和方法名定义 FunctionCallIdentifier : 结合FunctionIdentifier和Conditional元素 匹配对函数的特定调用 Definition : 包含控制流状态机定义 建议使用CDATA部分避免XML特殊字符转义问题 4. 规则定义:XXE漏洞示例 漏洞代码示例 关键匹配点分析 需要匹配的三个关键部分: SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); parser.parse(xmlInput, handler); 规则定义步骤 第一阶段:函数匹配 定义三个关键函数的匹配规则: 第二阶段:状态机设计 XXE漏洞状态转换流程: 初始状态 → 创建factory 创建factory → 创建parser 创建parser → 执行parse(漏洞点) 状态机XML定义: 5. 规则扫描与验证 漏洞代码扫描结果 执行扫描后,Fortify会报告XXE注入漏洞,可通过检查RuleID确认是否由自定义规则检测到。 安全代码示例(误报问题) 初始规则会对安全代码也报告漏洞(误报),需要优化。 6. 规则优化 误报问题解决 添加对安全设置方法的检测: 添加FunctionCallIdentifier: 更新状态机: 漏洞级别调整 通过MetaInfo元素调整漏洞严重性: 评分标准: Accuracy(0-5) : 准确性 4-5: 高准确性,误报率低 Impact(0-5) : 影响力 4-5: 高影响力,可导致严重问题 Probability(0-5) : 发生概率 4-5: 高概率,易被利用 修复建议完善 添加规范的漏洞描述和修复建议: 7. 最终优化后的规则 整合所有优化点后的完整规则包含: 精确的函数匹配定义 完善的状态机设计(包含安全状态) 适当的漏洞级别设置 详细的漏洞描述和修复建议 8. 总结与最佳实践 规则编写流程 : 分析漏洞代码模式 定义关键函数匹配 设计状态转换流程 测试并优化误报/漏报 评估规则质量 : 对存在漏洞的代码能准确检测 对添加防护的安全代码不误报 漏洞级别设置合理 提供有效的修复建议 扩展应用 : 类似方法可用于其他类型漏洞的规则编写 根据具体风险代码调整规则逻辑 结合多种规则类型提高检测覆盖率 通过控制流规则可以有效地建模复杂的安全问题检测逻辑,特别适合需要跟踪多个函数调用序列的漏洞模式检测。