记一次审计的奇思妙想
字数 1319 2025-08-09 17:09:35
奇安信攻防社区漏洞审计实战教学文档
一、目标系统分析
1.1 系统架构识别
- 目标系统采用Java语言开发
- 使用Spring框架(Spring MVC)
- 数据库交互使用MyBatis
- 前端使用Thymeleaf模板引擎
1.2 关键组件分析
- Spring Security:负责身份认证和授权
- Apache Commons FileUpload:文件上传组件
- Jackson:JSON处理库
- Hibernate Validator:数据验证框架
二、审计前准备
2.1 环境搭建
- 使用IDEA导入项目
- 配置Maven依赖
- 设置调试环境
- 准备测试数据库
2.2 代码审计工具
- 静态分析工具:Fortify、Checkmarx
- 动态分析工具:Burp Suite、Postman
- 辅助工具:JD-GUI、JADX(用于反编译)
三、漏洞挖掘过程
3.1 SQL注入漏洞
发现点
@GetMapping("/user/info")
public String getUserInfo(@RequestParam String userId) {
String sql = "SELECT * FROM users WHERE id = " + userId;
// 直接拼接SQL查询
return jdbcTemplate.queryForObject(sql, String.class);
}
漏洞原理
- 直接拼接用户输入的userId到SQL语句
- 未使用预编译语句或参数化查询
- 未进行任何输入过滤
修复建议
@GetMapping("/user/info")
public String getUserInfo(@RequestParam String userId) {
String sql = "SELECT * FROM users WHERE id = ?";
return jdbcTemplate.queryForObject(sql, new Object[]{userId}, String.class);
}
3.2 XSS漏洞
发现点
@PostMapping("/comment/add")
public String addComment(@RequestParam String content, Model model) {
model.addAttribute("comment", content);
return "comment/show";
}
Thymeleaf模板
<div th:utext="${comment}"></div>
漏洞原理
- 使用
th:utext而非th:text渲染用户输入 - 未对用户输入的content进行任何过滤或转义
修复建议
- 使用
th:text替代th:utext - 添加XSS过滤器:
public class XssFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(new XssRequestWrapper((HttpServletRequest) request), response);
}
}
3.3 文件上传漏洞
发现点
@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file) {
String fileName = file.getOriginalFilename();
File dest = new File("/uploads/" + fileName);
file.transferTo(dest);
return "upload success";
}
漏洞原理
- 未验证文件类型
- 未重命名上传文件
- 直接使用原始文件名可能导致目录穿越
修复建议
@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file) {
// 验证文件类型
String contentType = file.getContentType();
if (!Arrays.asList("image/jpeg", "image/png").contains(contentType)) {
throw new RuntimeException("Invalid file type");
}
// 生成随机文件名
String fileName = UUID.randomUUID().toString() +
FilenameUtils.getExtension(file.getOriginalFilename());
// 防止目录穿越
fileName = fileName.replace("../", "");
File dest = new File("/uploads/" + fileName);
file.transferTo(dest);
return "upload success";
}
3.4 权限绕过漏洞
发现点
@GetMapping("/admin/deleteUser")
public String deleteUser(@RequestParam String userId) {
// 直接执行删除操作,未检查权限
userService.deleteUser(userId);
return "success";
}
漏洞原理
- 缺少权限验证注解(如@PreAuthorize)
- 仅依赖前端隐藏管理接口
修复建议
@GetMapping("/admin/deleteUser")
@PreAuthorize("hasRole('ADMIN')")
public String deleteUser(@RequestParam String userId) {
userService.deleteUser(userId);
return "success";
}
四、高级审计技巧
4.1 反序列化漏洞检测
检测点
- 查找接收JSON/XML输入的接口
- 检查是否使用不安全的ObjectMapper配置:
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(); // 危险配置
修复建议
ObjectMapper mapper = new ObjectMapper();
// 禁用默认类型
mapper.deactivateDefaultTyping();
// 使用安全的@JsonTypeInfo注解替代
4.2 表达式注入检测
检测点
- 查找使用SpEL表达式的代码
@PreAuthorize("#userId == authentication.principal.userId")
public String getUserInfo(String userId) {
// ...
}
- 检查Thymeleaf表达式中是否包含用户输入
修复建议
- 避免在安全表达式中直接使用用户输入
- 对表达式中的变量进行严格校验
4.3 不安全的加密实现
常见问题
- 使用弱哈希算法(MD5、SHA1)
- 硬编码加密密钥
- 使用ECB模式加密
修复建议
// 使用PBKDF2或bcrypt进行密码哈希
String hashedPassword = BCrypt.hashpw(password, BCrypt.gensalt());
// 使用AES-GCM模式加密
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
五、自动化审计辅助
5.1 自定义规则编写
Fortify自定义规则示例
<Rule formatVersion="3.4" language="java">
<Pattern>jdbcTemplate.queryForObject($sql, $...)</Pattern>
<Description>Potential SQL injection</Description>
<Category>SQL Injection</Category>
<Severity>High</Severity>
</Rule>
5.2 代码审计检查清单
-
输入验证:
- 所有用户输入是否经过验证
- 是否使用白名单验证
-
输出编码:
- 动态内容是否正确编码
- 是否区分HTML、JS、CSS等上下文
-
身份认证:
- 密码存储是否使用强哈希
- 会话管理是否安全
-
访问控制:
- 是否实施最小权限原则
- 是否进行服务端权限检查
-
错误处理:
- 是否泄露敏感信息
- 是否使用自定义错误页面
六、总结与最佳实践
6.1 审计经验总结
- 不要过度依赖工具,人工分析必不可少
- 关注框架的错误配置和安全特性禁用
- 特别注意业务逻辑中的安全缺陷
- 跟踪数据从入口到最终使用的完整流程
6.2 安全开发建议
- 采用安全编码规范
- 实施SDL流程
- 定期进行安全培训
- 建立代码审查制度
6.3 持续学习资源
- OWASP Top 10
- CWE/SANS Top 25
- 框架官方安全文档
- 安全社区漏洞分享