使用太阿(Tai-e)进行静态代码安全分析(spring-boot篇一)
字数 1049 2025-08-06 00:52:37
使用太阿(Tai-e)进行Spring Boot静态代码安全分析指南
概述
Tai-e是由南京大学李樾樾、谭添老师开发的Java静态程序分析框架,支持指针分析、数据流分析、污点分析等多种静态分析技术。本指南详细讲解如何使用Tai-e分析Spring Boot应用程序,解决控制反转带来的分析难题。
环境准备
1. 下载Tai-e源码
git clone https://github.com/pascal-lab/Tai-e.git
git submodule update --init --recursive
2. 配置IDEA开发环境
- 打开Tai-e项目
- 设置File->Project Structure
- 确保Java SDK配置正确
3. 下载测试项目java-sec-code
git clone https://github.com/JoyChou93/java-sec-code.git
cd java-sec-code
mvn clean package
基础配置
1. 创建配置文件
在config/common/目录下创建两个文件:
options.yml:
optionsFile: null
printHelp: false
classPath: []
appClassPath:
- /path/to/java-sec-code/target/classes
mainClass:
inputClasses: []
javaVersion: 8
prependJVM: false
allowPhantom: true
worldBuilderClass: pascal.taie.frontend.soot.SootWorldBuilder
outputDir: output
preBuildIR: false
worldCacheMode: true
scope: REACHABLE
nativeModel: true
planFile: null
analyses:
pta: cs:ci;implicit-entries:true;distinguish-string-constants:null;reflection-inference:solar;merge-string-objects:false;merge-string-builders:false;merge-exception-objects:false;taint-config:config/common/taint-config.yml;
onlyGenPlan: false
keepResult:
- $KEEP-ALL
taint-config.yml:
sources:
- { kind: param, method: "<org.joychou.controller.SQLI: java.lang.String jdbc_sqli_vul(java.lang.String)>", index: 0}
sinks:
- { vuln: "SQL Injection", level: 4, method: "<java.sql.Statement: java.sql.ResultSet executeQuery(java.lang.String)>", index: 0 }
- { vuln: "SQL Injection", level: 4, method: "<java.sql.Connection: java.sql.PreparedStatement prepareStatement(java.lang.String)>", index: 0 }
transfers:
- { method: "<java.lang.String: java.lang.String concat(java.lang.String)>", from: base, to: result }
# 更多传播规则...
call-site-mode: true
2. 运行配置
在IDEA中配置Main类为pascal.taie.Main,参数为--options-file=config/common/options.yml
核心问题与解决方案
问题1:缺少EntryPoint
Spring Boot的控制反转机制导致传统入口点分析无法到达Controller方法。
解决方案:实现AddControllerEntryPointHandler插件
public class AddControllerEntryPointHandler implements Plugin {
private Solver solver;
@Override
public void setSolver(Solver solver) {
this.solver = solver;
}
@Override
public void onStart() {
// 添加所有Mapping注解方法为入口点
solver.getHierarchy().applicationClasses().forEach(jClass -> {
jClass.getDeclaredMethods().forEach(jMethod -> {
if (jMethod.getAnnotations().stream()
.anyMatch(annotation ->
annotation.getType().matches("org.springframework.web.bind.annotation.\\w+Mapping"))) {
solver.addEntryPoint(new EntryPoint(jMethod, EmptyParamProvider.get()));
}
});
});
}
}
问题2:缺少Source点
手动配置每个Controller方法的参数作为source点不现实。
解决方案:修改SourceHandler处理参数source的逻辑
private void handleParamSource(CSMethod csMethod) {
JMethod method = csMethod.getMethod();
if (paramSources.containsKey(method)) {
// 原有处理逻辑...
} else {
// 自动添加Mapping注解方法的参数为source
if (method.getAnnotations().stream()
.anyMatch(annotation ->
annotation.getType().matches("org.springframework.web.bind.annotation.\\w+Mapping"))) {
Context context = csMethod.getContext();
IR ir = method.getIR();
for (int i = 0; i < ir.getParams().size(); i++) {
Var param = ir.getParam(i);
SourcePoint sourcePoint = new ParamSourcePoint(method, new IndexRef(IndexRef.Kind.VAR, i, null));
Obj taint = manager.makeTaint(sourcePoint, param.getType());
solver.addVarPointsTo(context, param, taint);
}
}
}
}
执行与分析
- 运行Tai-e分析:
java -cp tai-e-all-0.5.1-SNAPSHOT.jar pascal.taie.Main --options-file=options.yml
- 将结果转换为可视化图表:
dot -Tsvg -o taint-flow-graph.svg taint-flow-graph.dot
结果解读
分析结果将显示从Controller方法参数到SQL执行点的污点传播路径,标识出潜在的SQL注入漏洞。示例输出可能包含:
Source: org.joychou.controller.SQLI.jdbc_sqli_vul(String) parameter 0
-> java.sql.Statement.executeQuery(String)
高级配置
污点传播规则扩展
在taint-config.yml中可以定义更多传播规则:
transfers:
- { method: "<java.lang.StringBuilder: java.lang.StringBuilder append(java.lang.String)>", from: 0, to: result }
- { method: "<java.lang.StringBuilder: java.lang.String toString()>", from: base, to: result }
- { method: "<java.lang.String: java.lang.String replace(java.lang.CharSequence,java.lang.CharSequence)>", from: base, to: result }
新增漏洞类型
添加新的sink点检测其他类型漏洞:
sinks:
# RCE漏洞
- { vuln: "RCE", level: 5, method: "<java.lang.Runtime: java.lang.Process exec(java.lang.String)>", index: 0 }
# XSS漏洞
- { vuln: "XSS", level: 3, method: "<javax.servlet.http.HttpServletResponse: void sendRedirect(java.lang.String)>", index: 0 }
参考资源
常见问题解决
-
分析结果为空:
- 检查EntryPoint是否正确添加
- 确认source点配置正确
- 确保classpath包含所有依赖
-
性能优化:
- 启用worldCacheMode
- 限制分析范围(scope)
- 使用更精确的指针分析算法
-
缺失的反射调用:
- 配置reflection-inference策略
- 考虑添加特定反射调用的建模规则
通过本指南,您应该能够使用Tai-e对Spring Boot应用进行有效的静态安全分析,识别潜在的漏洞传播路径。