第3章 静态应用安全测试(SAST)原理

SAST核心概念 · 代码审计流程 · 误报与漏报分析

3.1 SAST核心概念

静态应用安全测试(Static Application Security Testing, SAST)是一种白盒安全分析方法,在不运行程序的情况下,通过扫描源代码、字节码或二进制文件来识别安全漏洞。SAST 通常在开发早期(编码阶段)介入,能够精准定位缺陷代码行。

源代码 SAST 分析引擎 词法/语法/数据流/控制流 漏洞报告
图3-1 SAST 分析流程示意

SAST 的核心能力包括:

  • 词法分析:将源代码分解为 Token 流,识别关键字、标识符、运算符等。
  • 语法分析:构建抽象语法树(AST),理解程序结构。
  • 数据流分析:追踪变量赋值、传播路径,检测未验证输入、敏感数据泄露。
  • 控制流分析:分析程序执行路径,发现逻辑缺陷、死代码、未初始化变量。
  • 污点分析:标记不可信输入(污点源),跟踪其传播到危险函数(污点汇)。

💡 关键术语: 污点源(Taint Source)、污点汇(Taint Sink)、净化函数(Sanitizer)、抽象语法树(AST)、符号执行。

3.2 代码审计流程

一个完整的 SAST 代码审计流程通常包含以下阶段:

  1. 项目配置与编译:配置扫描目标、语言、框架,部分工具需要编译环境(如 Java 需 classpath)。
  2. 规则加载:加载内置规则库(OWASP Top 10、CWE)或自定义规则。
  3. 扫描执行:引擎执行词法/语法/数据流分析,生成中间表示。
  4. 结果聚合:合并重复告警,按严重等级分类(Critical / High / Medium / Low)。
  5. 误报剔除:通过上下文分析、模式匹配过滤明显误报。
  6. 报告生成:输出包含代码位置、漏洞类型、修复建议的详细报告。
① 配置编译 ② 规则加载 ③ 扫描执行 ④ 结果聚合 ⑤ 误报剔除 ⑥ 报告生成
图3-2 SAST 代码审计流程(六阶段)

实际项目中,SAST 通常集成到 CI/CD 流水线中,实现自动化扫描。以下是一个典型的 Jenkins Pipeline 集成示例:

pipeline {
    agent any
    stages {
        stage('SAST Scan') {
            steps {
                sh 'sast-cli --source . --language java --rules java-rules.xml --output report.json'
            }
        }
        stage('Quality Gate') {
            steps {
                sh 'sast-cli --check report.json --threshold high=0'
            }
        }
    }
}

3.3 误报与漏报分析

SAST 工具的准确性由误报率和漏报率衡量。误报指工具报告了实际不存在的漏洞;漏报指真实漏洞未被检测到。两者往往此消彼长。

类型 定义 常见原因 影响
误报 (False Positive) 工具报告了非漏洞 过于宽泛的规则、缺乏上下文、未考虑运行时环境 降低开发信任度,增加人工审核成本
漏报 (False Negative) 真实漏洞未被检测 规则覆盖不全、复杂数据流/控制流、未知漏洞模式 安全风险残留,可能导致生产环境被攻击

误报与漏报的平衡是 SAST 工具选型的核心考量。以下 SVG 展示了误报/漏报与规则严格度的关系:

规则严格度 → 误报/漏报率 漏报 误报 理想平衡区 宽松规则 严格规则
图3-3 误报与漏报随规则严格度的变化趋势

降低误报与漏报的常用策略:

  • 自定义规则:针对业务逻辑编写精确规则,减少泛匹配。
  • 上下文敏感分析:支持跨函数、跨文件的数据流追踪。
  • 机器学习辅助:利用历史数据训练分类器,自动过滤误报。
  • 增量扫描:仅扫描变更代码,降低噪声。
  • 人工复核:安全专家定期审计告警,反馈调优规则。

📌 选型建议: 在 PoC 阶段,使用包含已知漏洞的开源项目(如 WebGoat、DVWA)测试工具的漏报率;同时用干净代码测试误报率。优先选择支持规则自定义和误报标记反馈的工具。