我们知道避免sql注入的最佳方法是使用带有绑定变量的预处理语句。但我有疑问是什么 如果我只使用预备语句但不绑定变量,如下面的客户ID来自用户界面
String query ="select * from customer where customerId="+customerId;
PreparedStatement stmt = con.prepareStatement(query); //line1
即使我没有使用绑定变量,第1行是否会注意限制sql注入?
我同意下面最好的方法,但如果上面的方法也负责重写sql注入,那么我更喜欢上面的一个(如 它是一个遗产项目)
String query ="select * from customer where customerId=?";
PreparedStatement stmt = con.prepareStatement(query);
stmt.setInt(1, 100);
是否准备好语句而不使用足够的绑定变量来确保不能进行sql注入?
答案 0 :(得分:1)
第1行不会检查develeper是否想要删除表。如果您编写查询,则认为它是好的。
sql注入的目标是准备值,允许在没有开发人员的情况下进行额外的sql查询。使用属性中的假值来查询您的网站。 例如:
id = "'); DROP ALL TABLES; --";
query = "select * from customer where customerId="+id;
PreparedStatement确保使用setInt / setString / etc添加到查询中的特殊符号(如'或')不会干扰sql查询。
答案 1 :(得分:1)
必须区分几个问题。
使用预备声明本身不会有任何帮助。
一般而言,使用非准备方式也没有坏处。
只有在您需要将动态部分插入查询时才会有效。
因此,在后一种情况下,这样的动态部分必须进入查询仅通过占位符,实际值必须在以后绑定(占位符是?
或任何其他代表查询中的实际数据)。
术语“预备声明”暗示使用占位符 所有进入查询的动态数据。所以,
因此,再次 - 只有所有动态数据准备语句的占位符才有效。它起作用的原因是:
答案 2 :(得分:-1)
我知道这是一篇较旧的帖子,我只是想补充一点,如果你能确保只允许整数进入第1行的查询,就可以避免注入攻击。字符串输入是注入攻击发生的地方。在上面的示例中,不清楚哪个类变量'customerId',尽管它看起来像一个int。由于这个问题被标记为Java,你不能用int进行注入攻击,所以你应该没问题。
如果它是第1行中的字符串,则需要确信'customerId'来自一个必须是整数的安全源。如果它来自帖子表单或其他用户生成的字段,那么您可以尝试将其转义或将其转换为整数以确定。如果是字符串,则将其强制转换为整数,并且不需要绑定参数。