58集团白盒代码审计系统建设实践2:深入理解SAST
字数 1453 2025-08-22 18:37:21
SAST静态应用安全测试与CodeQL实践详解
一、SAST技术基础
1.1 SAST核心概念
SAST(Static Application Security Testing)即静态应用安全测试,是一种通过分析源代码来发现安全漏洞的技术。其核心特点包括:
- 白盒测试:直接分析源代码
- 静态分析:无需运行程序
- 早期检测:可在开发阶段发现问题
1.2 SAST工作原理
SAST的完整工作流程包含以下关键步骤:
- 中间代码转换:将源代码转换为中间表示(IR)
- 语义分析:识别不安全函数和方法
- 数据流分析:跟踪数据传递过程
- 控制流分析:分析程序执行路径
- 配置分析:检查敏感配置
- 结构分析:评估程序上下文环境
- 规则匹配:对比漏洞特征库
- 报告生成:输出详细漏洞信息
二、抽象语法树(AST)技术
2.1 AST基本概念
抽象语法树(Abstract Syntax Tree)是源代码语法结构的树状表示:
- 节点表示:每个节点对应源代码中的结构元素
- 抽象特性:省略语法细节(如括号)
- 构建过程:词法分析→语法分析→AST生成
2.2 Java AST分析工具Spoon
Spoon是Java源代码分析的重要工具:
- 功能:分析、重写、转换Java代码
- 特点:
- 支持Java 11+版本
- 提供强大的API
- 开源项目(Inria/OW2)
2.2.1 Spoon使用示例
java -cp spoon-core-8.4.0-jar-with-dependencies.jar spoon.Launcher \
-i HelloController.java --gui
2.2.2 Spoon元模型
Spoon元模型分为三部分:
- 结构部分:类、接口、方法等声明
- 代码部分:方法体中的可执行代码
- 参考部分:对程序元素的引用
三、污点分析技术
3.1 污点分析定义
污点分析使用三元组模型:<sources, sinks, sanitizers>
- Source(污点源):不受信任的输入
- Sink(汇聚点):敏感操作点
- Sanitizer(无害处理):安全处理机制
3.2 污点分析流程
-
识别阶段:
- 标记污点源和汇聚点
- 方法包括:启发式策略、API标记、机器学习
-
传播分析:
- 显式流分析:跟踪数据依赖关系
- 隐式流分析:跟踪控制依赖关系
- 需解决欠污染(under-taint)和过污染(over-taint)问题
-
无害处理:
- 数据加密处理
- 输入验证处理
- 处理后移除污点标记
四、CodeQL深度解析
4.1 CodeQL整体架构
- AST解析:适配各语言解析器
- CodeDB:存储AST元数据
- QL语言:定义查询规则
- 查询引擎:高效搜索算法
4.2 CodeQL漏洞分析示例
4.2.1 命令注入检测
/* ExecTainted.ql */
import java
import semmle.code.java.dataflow.FlowSources
import semmle.code.java.security.ExternalProcess
import ExecCommon
import DataFlow::PathGraph
from DataFlow::PathNode source, DataFlow::PathNode sink, ArgumentToExec execArg
where execTainted(source, sink, execArg)
select execArg, source, sink, "$@ flows to here..."
4.2.2 规则配置(ExecCommon.qll)
private class RemoteUserInputToArgumentToExecFlowConfig extends TaintTracking::Configuration {
override predicate isSource(DataFlow::Node src) { src instanceof RemoteFlowSource }
override predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof ArgumentToExec }
override predicate isSanitizer(DataFlow::Node node) {
node.getType() instanceof PrimitiveType or
isSafeCommandArgument(node.asExpr())
}
}
4.3 实际应用案例
4.3.1 Spring路径扫描
/* SpringPath.ql */
import java
import semmle.code.java.frameworks.spring.SpringCustomController
from SpringWebApiBindMethod m
select m as controllerMethod, m.getLocation() as location,
m.getBindPath() as methodBindPath,
m.getControllerClassBindPath() as classBindPath
4.3.2 Fastjson检测
/* FastJson检测规则 */
class UnSafeFastJsonSink extends DataFlow::ExprNode {
UnSafeFastJsonSink() { unsafeFastjson(_, this.getExpr()) }
MethodAccess getMethodAccess() { unsafeFastjson(result, this.getExpr()) }
}
predicate unsafeFastjson(MethodAccess ma, Expr sink) {
exists(Method m | m = ma.getMethod() |
ma.getMethod() instanceof FastJsonParseMethod and
not fastJsonLooksSafe() and
sink = ma.getArgument(0)
)
}
五、工程实践要点
5.1 58集团实践经验
- 自动化集成:适配CI/CD流程,每日数千次构建
- 定制化开发:针对自研Java框架优化
- 高效分析:结合AST和污点分析技术
5.2 检测能力建设
-
基础能力:
- AST解析
- 数据流/控制流分析
- 规则引擎
-
高级能力:
- 框架支持(如Spring)
- 组件分析(如Fastjson)
- 路径扫描
-
集成能力:
- SCA(软件成分分析)
- CI/CD流水线
- 漏洞管理系统
六、学习资源
- CodeQL官方教程:基础语法和Java模块
- 实践案例:Spring路径扫描、Fastjson检测
- 进阶资料:污点分析技术论文
注:可通过"58安全应急响应中心"公众号获取完整CodeQL教程资源。