2013-04-23 111 views
1

正如我们所知,避免sql注入的最好方法是使用带有绑定变量的准备好的语句。但我有我如果用刚刚准备什么 声明,但没有绑定变量了下方的客户编号是从用户界面来问题SqlInjection with prepared statement without bind variable?

String query ="select * from customer where customerId="+customerId; 
PreparedStatement stmt = con.prepareStatement(query); //line1 

请问1个线照顾限制,即使我没有使用绑定变量的SQL注入?

我同意最好的办法是低于但如果上述方法还需要restrcting SQL注入的护理的话,我宁愿上面一个(如 其遗留项目)

String query ="select * from customer where customerId=?"; 
    PreparedStatement stmt = con.prepareStatement(query); 
    stmt.setInt(1, 100); 

准备语句不使用绑定变量足以确保SQL注入不可能?或

+1

无sql注入行1 – BlackJoker 2013-04-23 06:35:24

+0

你的意思是只使用准备好的语句,而不使用绑定变量足以确保SQL注入不可能? – 2013-04-23 06:38:02

+0

我简单的意思是SQL注入不会发生在line1中。不管是否使用变量绑定,使用准备好的语句都是足够的 – BlackJoker 2013-04-23 06:40:52

回答

1

一个必须区分几个事​​项

查询。

使用准备好的语句不会只凭本身做任何帮助。
除了有在一般使用非准备方式没有坏处。

的事作品只有当您需要将动态部分插入查询时。 因此,在后一种情况下,例如一动态部分具有通过占位符仅,其实际值必须被后来结合到进入查询(占位符是一个?或表示在查询中的实际数据的任何其它标记)。

非常术语“准备好的声明” 使用占位符所有是进入查询动态数据意味着。所以,

  • 如果您在查询中没有动态部分,那么即使不使用预处理语句,显然也不会有任何注入。
  • 如果您使用的是事先准备好的声明,但注入值直接进入查询,而不是结合他们 - 这将是注入敞开的。

所以,再一次 - 只用占位符编写的语句将所有工作动力数据。和它的作品,因为:

  • 每一个动态值必须正确格式化
  • 事先准备好的声明,使正确的格式(或处理)必然
  • 准备好的声明不正确的格式(或处理)的唯一合适的地方 - 查询执行前的权利,而不是别的地方,所以,我们的安全不会依赖不可靠等来源,如
    • 一些“魔力”功能,而不是使其安全,而不是破坏数据。
    • 一个(或几个)程序员的良好愿望,他们可以决定在程序流程中的某个地方格式化(或不格式化)我们的变量。这点非常重要。
  • 准备语句影响了进入查询很值,但不能在源变量,保持完整,并可以在进一步的代码被用于(通过电子邮件被发送或屏幕上示出)。
  • 准备好的语句可以使应用程序代码大大缩短,在后台执行所有格式化(仅在驱动程序允许的情况下才会执行*)。
+0

您的意思是说,如果它是一个动态查询(就像在亩情况下客户id是来自用户界面),我使用没有绑定变量(即?)准备好的语句,它很容易sql注入。是吗? – 2013-04-23 06:55:40

+0

如果你可以在你的陈述中解释占位符的含义,那么它会很有帮助。“因此,在后一种情况下,这样的动态部分必须通过占位符进入查询” – 2013-04-23 06:56:28

+0

是的,这就是我的意思。在问题中添加了占位符定义。 – 2013-04-23 07:08:45

1

1号线将不会检查是否develeper想不想删除表。如果你写查询它假设它是好的。

目标SQL注入是准备允许作出额外的SQL查询,而无需意志也不是开发商的知识价值。用属性中的虚假值引用您的网站。 实施例:

 id = "'); DROP ALL TABLES; --"; 
     query = "select * from customer where customerId="+id; 

的PreparedStatement确保特殊符号(如“或“)加到使用SETINT /了setString /等等不会与SQL查询干扰

-1

我知道这是一个老帖子,我只是想补充一点,你避免注入攻击,如果你能确保你只允许整数到您的查询线1.字符串输入是在注入攻击发生。在上面的示例中,虽然它看起来像一个int,但不清楚哪个类的变量'customerId'是。由于这个问题被标记为Java,所以你不能用int来进行注入攻击,所以你应该没问题。

如果它是第1行中的字符串,则需要确信'customerId'来自必须是整数的安全源。如果它来自帖子表单或其他用户生成的字段,那么您可以尝试将其转义或将其转换为整数以确保。如果它是一个字符串,则将其转换为整数,并且不需要绑定参数。

+0

有些查询也需要字符串,你知道 – 2013-08-23 13:24:40

+0

这个问题没有询问关于使用字符串,而是关于使用ID。我相信这个问题是关于是否有必要在这个用户的情况下使用绑定来防止注入攻击。在原始问题中描述的情况下,如果你能满足我在我的回答中描述的条件,那么我就说他们不是必需的。当然,有些查询需要字符串,但这是针对不同的应用程序,并未在此问题中讨论。 – RightHandedMonkey 2013-08-23 13:38:20

+0

是的,是否有必要使用绑定来防止注入攻击。任何状况之下。 – 2013-08-23 13:48:36