flawopen.com/SQL 注入/Java

SQL 注入 in Java

严重 CWE-89 Draft — pending review
Language: English Português (Brasil) Español Français Deutsch Русский 简体中文 日本語 हिन्दी 한국어 Bahasa Indonesia
通俗解释 (ELI5)

想象一个只接收取件码的窗口。SQL 注入就是有人在输入框里输入了一段特殊指令,导致系统把所有人的快递信息全倒了出来,因为系统根本没验证输入是不是合法数字。

核心概念
output encoding
Converting special markup characters into safe entities so browsers display them as text rather than script.

原理解析

SQL 注入 in Java occurs when unvalidated strings are concatenated into JDBC Statement or HQL/JPQL queries.

真实安全事件

In 2005, the Samy XSS worm infected over 1 million user profiles on MySpace in under 20 hours, forcing the platform offline.

Documented historical AppSec case study.

缺陷代码 vs 修复方案

VULNERABLE
// userId comes straight from the request
String query = "SELECT * FROM users "
    + "WHERE id = " + userId;
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);
FIXED
// value is bound, never concatenated
String query = "SELECT * FROM users WHERE id = ?";
PreparedStatement stmt =
    connection.prepareStatement(query);
stmt.setString(1, userId);
ResultSet rs = stmt.executeQuery();

修复原理

PreparedStatement precompiles the query structure in the database engine, binding parameter values separately.

语言专属陷阱

MyBatis: ${} vs #{}

#{} uses safe parameterized binding, while ${} performs raw string substitution.

Hibernate HQL/JPQL

Concatenating HQL queries is just as dangerous as raw SQL. Always use setParameter().

常见认知误区

"Stored procedures prevent injection"

Only if the stored procedure itself uses parameters rather than dynamic EXECUTE strings.

如何检测与排查

grep -rn "createStatement().*executeQuery(.*+" --include="*.java" .
Run SpotBugs with the FindSecBugs plugin in CI to catch SQL_INJECTION_JDBC automatically.

防御自查清单

常见问题 (FAQ)

Is Spring Data JPA safe?

Derived queries (@Query) are safe if method parameters are bound with :param or ?1.

参考规范

相关漏洞: Cross-Site Scripting Command InjectionPath Traversal