引言:为什么 Java 应用程序安全不是选项,而是必需品
Java 仍然是开发企业级和 Web 应用程序最流行的语言之一。然而,受欢迎也伴随着攻击者更多的关注。根据 OWASP(开放 Web 应用程序安全项目),代码漏洞每年导致数据泄露和数十亿美元的经济损失。在本文中,我们将分解十大 Java 应用程序漏洞,展示真实的代码示例,并提供具体的保护建议。本文对于努力编写安全代码的初级和资深开发者都将有所帮助。
1. 注入攻击:SQL、LDAP 和命令注入
注入攻击仍然是漏洞之王。最常见的情况是SQL 注入,用户输入被直接拼接到 SQL 查询中。
漏洞代码示例
String query = "SELECT * FROM users WHERE username = '" + request.getParameter("user") + "'";Statement stmt = connection.createStatement();ResultSet rs = stmt.executeQuery(query);如果攻击者输入 admin' OR '1'='1,他们就能获取所有用户的数据。
如何保护
- 使用 PreparedStatement:参数化查询会自动转义输入。
- 在服务器端验证输入数据(使用白名单)。
- 对于 LDAP 和操作系统命令,使用转义并避免使用用户数据调用
Runtime.exec()。
// 安全版本String query = "SELECT * FROM users WHERE username = ?";PreparedStatement pstmt = connection.prepareStatement(query);pstmt.setString(1, request.getParameter("user"));ResultSet rs = pstmt.executeQuery();2. 认证与会话管理缺陷
弱认证是第二危险的漏洞。常见问题包括:缺少登录尝试限制、以明文存储密码以及可预测的会话 ID。
建议
- 仅以加盐哈希(例如 bcrypt 或 Argon2)的形式存储密码。
- 使用
SecureRandom生成会话令牌。 - 设置会话超时时间和带有安全令牌的“记住我”机制。
// 生成安全的会话 IDimport java.security.SecureRandom;String sessionId = new SecureRandom().ints(48, 122) .filter(i -> Character.isLetterOrDigit(i)) .limit(64) .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append) .toString();3. XSS(跨站脚本攻击)
XSS 允许将恶意 JavaScript 注入到其他用户浏览的页面中。这对于使用 JSP 或 Thymeleaf 的 Java Web 应用程序尤其危险。
漏洞示例
<div>${userComment}</div>如果 userComment 包含 <script>alert('XSS')</script>,该代码将在浏览器中执行。
保护措施
- 转义输出:在 JSP 中使用
c:out或fn:escapeXml()。 - 对于 Thymeleaf —
th:utext是危险的,请使用th:text。 - 应用内容安全策略(CSP)头部。
4. 不安全的反序列化
Java 反序列化是最关键的漏洞之一,允许任意代码执行(RCE)。攻击者可以篡改字节流并注入恶意对象。
攻击示例
ObjectInputStream ois = new ObjectInputStream(request.getInputStream());Object obj = ois.readObject(); // 危险!如何保护
- 不要反序列化