准备好的语句会阻止sql注入攻击吗?

时间:2011-08-19 11:03:52

标签: java security sql-injection

考虑一个假设的情况,我必须根据userId从数据库中检索一些细节,下面给出了示例代码

private String getpassword(String username) {

PreparedStatement statement = null;
ResultSet resultSet = null;
Connection conn = null;

final String selectQuery = "SELECT password FROM " + "users WHERE username=?";
try {
    conn = dataSource.getConnection();
    statement = conn.prepareStatement(selectQuery);
    statement.setString(1, username);
    resultSet = statement.executeQuery();
    if (resultSet.next()) {
        }

} catch (SQLException e) {
 // log it
}
//return
}

此用户名实际上来自客户端,用户可以篡改数据(如果他愿意)。因此,preparedStatements将阻止接受引号并仅将过滤后的SQL形式发送到数据库。

例如:我可以提供username ='或1 = 1,它将是一个有效的SQL语句。但是如果驱动程序从用户输入中删除引号,那么它们将阻止sql注入。

对它的一般理解是什么?

3 个答案:

答案 0 :(得分:4)

根据这个,是的:http://en.wikipedia.org/wiki/SQL_injection

在这种情况下,语句已经被编译,注入的代码将不再被解释(因此也不会被执行)。

答案 1 :(得分:3)

使用参数和预准备语句确实可以防止SQL注入攻击,即传递“'或1 = 1”不会导致返回意外数据。但是,如果在任何阶段将数据显示给用户,则需要确保生成的HTML不会受到从数据库返回的用户输入的影响

例如,如果您的网页显示:

Hello, ${username}

如果用户名是

<script>alert('I could have been more malicious')</script>

会导致XSS或CSRF攻击。

N.B。

Hello, ${fn:escapeXml(username)}

会更安全(JSP代码)。

一个很好的参考是:

答案 2 :(得分:0)

用户名和查询将作为两个单独的东西发送到数据库,数据库引擎将负责将两者重新组合在一起。在读取参数时,引擎已经编译了查询,因此这两个从不被视为同一语句的一部分。