JAVA代码审计的一些Tips(附脚本)
字数 1939 2025-08-29 08:31:47
Java代码审计与安全编码实践指南
1. XXE (XML外部实体注入)漏洞
1.1 漏洞原理
XML文档结构包括XML声明、DTD文档类型定义(可选)和文档元素。当允许引用外部实体时,攻击者可构造恶意内容访问服务器资源。
1.2 危险示例
String xmldata = request.getParameter("data");
SAXReader sax = new SAXReader();
Document document = sax.read(new ByteArrayInputStream(xmldata.getBytes()));
1.3 常见XML解析接口
javax.xml.parsers.DocumentBuilderjavax.xml.stream.XMLStreamReaderorg.jdom.input.SAXBuilderorg.dom4j.io.SAXReaderjavax.xml.parsers.SAXParser
1.4 修复方案
sax.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
sax.setFeature("http://xml.org/sax/features/external-general-entities", false);
sax.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
2. 反序列化漏洞
2.1 漏洞原理
当输入的反序列化数据可被用户控制时,攻击者可通过构造恶意输入让反序列化产生非预期的对象并执行任意代码。
2.2 危险示例
InputStream in = request.getInputStream();
ObjectInputStream ois = new ObjectInputStream(in);
ois.readObject();
ois.close();
2.3 常见反序列化函数
ObjectInputStream.readObjectXMLDecoder.readObjectYaml.loadXStream.fromXMLObjectMapper.readValue
2.4 修复方案
白名单校验
public class AntObjectInputStream extends ObjectInputStream {
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
if (!desc.getName().equals(SerialObject.class.getName())) {
throw new InvalidClassException("Unauthorized deserialization attempt", desc.getName());
}
return super.resolveClass(desc);
}
}
3. SSRF (服务器端请求伪造)
3.1 漏洞原理
代码提供了从其他服务器获取数据的功能但没有对目标地址做过滤与限制。
3.2 危险示例
String url = request.getParameter("picurl");
URL pic = new URL(url);
HttpURLConnection con = (HttpURLConnection) pic.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
3.3 常见HTTP请求函数
HttpClient.executeHttpURLConnection.connectURL.openStream
3.4 修复方案
- 使用白名单校验HTTP请求URL地址
- 禁用不需要的协议及限制请求端口
4. SQL注入
4.1 漏洞原理
用户输入数据被拼接到SQL语句中执行,导致SQL语义被改变。
4.2 MyBatis危险示例
select * from books where id = ${id}
4.3 修复方案
使用#{}而非${}:
select * from books where id = #{id}
5. 文件上传漏洞
5.1 漏洞原理
未校验上传文件后缀类型,导致可上传webshell文件。
5.2 危险示例
String fileName = file.getOriginalFilename();
String filePath = "/static/images/uploads/" + fileName;
BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(filePath)));
5.3 修复方案
- 使用白名单校验上传文件类型
- 限制文件大小
6. Autobinding漏洞
6.1 漏洞原理
框架自动将HTTP请求参数绑定到程序变量或对象上,攻击者可构造请求将参数绑定到对象上。
6.2 危险注解
@SessionAttributes@ModelAttribute
6.3 修复方案
使用@InitBinder设置允许或不允许绑定的参数。
7. URL重定向漏洞
7.1 漏洞原理
未对跳转地址进行校验,导致钓鱼攻击。
7.2 危险示例
String site = request.getParameter("url");
response.sendRedirect(site);
7.3 常见重定向函数
sendRedirectsetHeaderforward
7.4 修复方案
使用白名单校验重定向的URL地址。
8. CSRF (跨站请求伪造)
8.1 漏洞原理
已登录用户在不知情的情况下执行恶意操作。
8.2 漏洞示例
GET http://blog.com/article/delete.jsp?id=102
8.3 修复方案
- Referer校验
- Token校验
- 高安全性操作使用验证码、短信等二次校验
9. 命令执行漏洞
9.1 漏洞原理
执行的命令用户可控且未做好限制。
9.2 危险示例
String cmd = request.getParameter("cmd");
Runtime.getRuntime().exec(cmd);
9.3 常见命令执行函数
Runtime.execProcessBuilder.startGroovyShell.evaluate
9.4 修复方案
- 避免命令用户可控
- 对用户输入做严格校验(如
&&、|、;等)
10. 权限控制漏洞
10.1 漏洞类型
- 水平越权:操作其他相同角色用户数据
- 垂直越权:低权限用户操作高权限用户数据
10.2 危险示例
String userid = request.getParameter("userid");
String info = userModel.getuserInfoByid(userid);
10.3 修复方案
校验当前登录用户是否有操作权限及数据是否属于该用户。
11. 批量请求漏洞
11.1 漏洞原理
未对短信、邮件等接口做频率限制,导致轰炸攻击。
11.2 危险示例
String phone = request.getParameter("phone");
boolean ifex = userModel.ifuserExitByPhone(phone);
11.3 修复方案
在服务端对请求频率、发送量做限制。
12. 第三方组件安全
12.1 风险点
- Struts2漏洞
- 不安全的XML解析器
- 可被利用的库(如commons-collections:3.1)
12.2 修复方案
使用最新或安全版本的第三方组件。
13. 自动化审计工具
13.1 JavaID脚本
通过正则匹配查找危险函数,可在regexp.xml中自定义规则。
14. 审计方法论
- 通读代码理解业务逻辑
- 查找危险函数
- 检查框架安全配置
- 验证输入输出处理
- 检查权限控制
- 测试边界条件
15. 参考资源
- OWASP XML External Entity (XXE) Prevention Cheat Sheet
- 浅谈Java反序列化漏洞修复方案
- Mybatis框架下SQL注入漏洞面面观
- Spring MVC Autobinding漏洞实例初窥