java代码审计手书(四)
字数 1790 2025-08-27 12:33:43
Java代码审计手书(四) - 安全漏洞与防护措施详解
一、Android应用安全漏洞
1. 外部文件访问漏洞
漏洞特征:ANDROID_EXTERNAL_FILE_ACCESS
风险:
- 应用往外部存储(SD卡)写数据可能导致敏感信息泄露
- 其他应用可通过READ_EXTERNAL_STORAGE权限读取这些文件
有漏洞代码:
File file = new File(getExternalFilesDir(TARGET_TYPE), filename);
fos = new FileOutputStream(file);
fos.write(confidentialData.getBytes());
fos.flush();
修复方案:
fos = openFileOutput(filename, Context.MODE_PRIVATE);
fos.write(string.getBytes());
最佳实践:
- 敏感数据应存储在内部存储中
- 必须使用外部存储时应对数据进行加密
2. Broadcast广播漏洞
漏洞特征:ANDROID_BROADCAST
风险:
- 任何应用都可监听广播意图
- 可能通过广播传输敏感数据
有漏洞代码:
Intent i = new Intent();
i.setAction("com.insecure.action.UserConnected");
i.putExtra("username", user);
i.putExtra("email", email);
i.putExtra("session", newSessionId);
this.sendBroadcast(v1);
修复方案:
- 使用权限保护广播:
<permission android:name="my.app.PERMISSION" />
<receiver android:name="my.app.BroadcastReceiver"
android:permission="my.app.PERMISSION">
<intent-filter>
<action android:name="com.secure.action.UserConnected" />
</intent-filter>
</receiver>
- 发送方声明权限:
<uses-permission android:name="my.app.PERMISSION" />
<permission android:name="my.app.PERMISSION"
android:protectionLevel="signature"/>
3. 任意文件写漏洞
风险:
- 使用MODE_WORLD_READABLE模式创建文件
- 可能导致敏感信息泄露或文件被篡改
有漏洞代码:
fos = openFileOutput(filename, MODE_WORLD_READABLE);
fos.write(userInfo.getBytes());
修复方案:
fos = openFileOutput(filename, MODE_PRIVATE);
替代方案:
- 使用SQLite数据库存储结构化数据
4. WebView相关漏洞
地理位置泄露
有漏洞代码:
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onGeolocationPermissionsShowPrompt(String origin,
GeolocationPermissions.Callback callback) {
callback.invoke(origin, true, false);
}
});
修复方案:应询问用户确认
JavaScript启用风险
风险:可能导致XSS攻击
有漏洞代码:
WebView myWebView = (WebView) findViewById(R.id.webView);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
防护措施:
- 避免不必要的JavaScript启用
- 对渲染内容进行XSS防护
JavaScript接口暴露
风险:可能暴露危险API
有漏洞代码:
myWebView.addJavascriptInterface(new FileWriteUtil(this), "fileWriteUtil");
二、Web应用安全漏洞
1. Cookie安全配置
缺少Secure标志
风险:Cookie可能通过非HTTPS连接传输
有漏洞代码:
Cookie cookie = new Cookie("userName",userName);
response.addCookie(cookie);
修复方案:
cookie.setSecure(true);
cookie.setHttpOnly(true);
缺少HttpOnly标志
风险:Cookie可能被JavaScript读取
持久性Cookie风险:
- 长期存储敏感信息
- 增加信息泄露风险
2. 反序列化漏洞
漏洞特征:OBJECT_DESERIALIZATION
风险:可能导致远程代码执行
有漏洞代码:
try (ObjectInputStream in = new ObjectInputStream(receivedFile)) {
return (UserData) in.readObject();
}
修复方案:
- 避免反序列化不受信任的数据
- 使用白名单限制可反序列化的类
Jackson不安全配置:
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping();
mapper.readValue(json, ABean.class);
修复方案:
- 明确指定多态类型
- 禁用默认类型推导
3. 信任边界违规
漏洞特征:TRUST_BOUNDARY_VIOLATION
风险:混淆信任与不信任数据的边界
示例:
req.getSession().setAttribute(activateProperty,"true");
req.getSession().setAttribute("user",userSubmitted);
修复方案:
- 对跨边界数据进行严格验证
- 明确区分信任与不信任数据源
4. 模板注入漏洞
Velocity引擎
有漏洞代码:
Velocity.evaluate(context, swOut, "test", userInput);
Freemarker引擎
有漏洞代码:
Template template = cfg.getTemplate(inputTemplate);
template.process(data, swOut);
修复方案:
- 避免用户控制模板内容
- 考虑使用限制性更强的模板引擎(如Handlebars)
5. CORS策略过宽松
风险:可能导致敏感数据泄露
有漏洞代码:
response.addHeader("Access-Control-Allow-Origin", "*");
修复方案:
- 明确指定允许的源
- 避免使用通配符(*)
三、LDAP相关漏洞
1. 匿名LDAP绑定
有漏洞代码:
env.put(Context.SECURITY_AUTHENTICATION, "none");
DirContext ctx = new InitialDirContext(env);
修复方案:使用适当的认证机制
2. LDAP入口投毒
风险:可能导致远程代码执行
有漏洞代码:
ctx.search(query, filter, new SearchControls(scope, countLimit,
timeLimit, attributes, true, // 启用对象反序列化
deref));
修复方案:禁用对象反序列化
四、文件泄露漏洞
1. Struts文件泄露
有漏洞代码:
String returnURL = request.getParameter("returnURL");
return new ActionForward(returnURL);
2. Spring文件泄露
有漏洞代码:
String returnURL = request.getParameter("returnURL");
return new ModelAndView(returnURL);
3. RequestDispatcher文件泄露
有漏洞代码:
String jspFile = request.getParameter("jspFile");
request.getRequestDispatcher("/WEB-INF/jsps/" + jspFile + ".jsp")
.include(request, response);
通用修复方案:
- 避免用户输入直接控制文件路径
- 对用户输入进行严格校验
五、其他重要漏洞
1. 格式化字符串操纵
风险:可能导致信息泄露或应用崩溃
有漏洞代码:
String format = "The customer: %s %s has the balance %4$." + userInput + "f";
formatter.format(format, firstName, lastName, accountNo, balance);
修复方案:避免用户控制格式化字符串
2. HTTP参数污染
风险:可能改变应用行为
有漏洞代码:
String lang = request.getParameter("lang");
get.setQueryString("lang=" + lang + "&user_id=" + user_id);
修复方案:严格过滤用户输入
3. 错误信息泄露
风险:可能暴露敏感信息
有漏洞代码:
try {
out = httpResponse.getOutputStream()
} catch (Exception e) {
e.printStackTrace(out);
}
修复方案:使用自定义错误页面
4. SMTP头部注入
风险:可能操纵邮件内容
有漏洞代码:
message.setSubject(usernameDisplay + " has sent you notification");
修复方案:使用安全的邮件库并过滤特殊字符
总结
本手书涵盖了Java和Android开发中的多种安全漏洞,从数据存储、网络通信到用户输入处理等多个方面。关键防护原则包括:
- 最小权限原则:只请求和使用必要的权限
- 数据加密:敏感数据必须加密存储和传输
- 输入验证:所有用户输入都应视为不可信的
- 安全默认值:使用安全的默认配置(MODE_PRIVATE等)
- 错误处理:避免泄露敏感信息的错误消息
开发者应将这些安全实践纳入开发流程,定期进行代码审计和安全测试,以确保应用的安全性。