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)

番号札だけを受け取るはずの窓口に、悪意のある命令文を紛れ込ませることで、システム全体の名簿を盗み見させてしまう手口です。

このページの主要用語
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