这样的声明
String query = "SELECT * FROM users WHERE userid ='"+ userid + "'" + " AND password='" + password + "'";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);
符合 SQL 注入(inject)条件。但是PreparedStatement 如何帮助防止 SQL 注入(inject)?考虑以下场景:
PreparedStatement stmt = connection.prepareStatement("SELECT * FROM users WHERE userid=? AND password=?");
stmt.setString(1, userid);
stmt.setString(2, password);
ResultSet rs = stmt.executeQuery();
如果有人输入 userId = "abc"
和 password = "1=1"
会怎样,因为这也将被视为有效字符串...
最佳答案
保护您的确切方式取决于数据库,但有两个明显的选择:
- 数据库驱动程序可以执行字符串插值并生成 SQL 语句以确保所有参数都被正确转义。
- 数据库驱动程序可以完全按照您指定的方式将 SQL 传递给数据库,并通过完全独立的 channel 传递参数值,不需要任何转义,因为它只是 包含值。
在我看来,后者是一个更明智的解决方案,因为它允许数据库非常简单地缓存查询计划,识别两个查询除了参数值之外完全相同。我希望任何现代数据库都能在其 native 通信协议(protocol)中支持这一点。
关于java - SQL 注入(inject)漏洞通过 preparedStatement,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25024894/