【问题标题】:Inserting string into PreparedStatement将字符串插入 PreparedStatement
【发布时间】:2011-05-11 17:41:59
【问题描述】:

我正在使用使用 Statement 的 MySQL 包装器方法,我想将其更改为 PreparedStatement 以增强安全性,不幸的是,此方法要求允许任意 SQL 作为参数,例如“WHERE id=5” .

我可以通过 PreparedStatement 以某种方式允许这样做吗?

如果没有,您能否建议另一种方法来清理数据库输入以防止 SQL 注入?

谢谢

编辑:抱歉,不清楚,整个“WHERE id=5”位每次都可以更改,而不仅仅是 5。

【问题讨论】:

  • arbitary SQL 是指“5”还是完整的WHERE 片段?
  • @leonbloy 完整的 WHERE 片段,编辑了原始帖子以使其清晰。

标签: java mysql security sql-injection


【解决方案1】:

如果您的意思是您是否可以制作动态 PreparedStatements,那么您可以,只要您可以控制备选方案。例如(伪代码):

  sql = "SELECT * FROM EMAIL WHERE TYPE = ?";
  if(haveId) 
    sql += " AND id=?";
  st = createPreparedStatement(sql);
  st.setString(1,type);  
  if(haveId) 
     st.setString(2,id);  

当然,如果您的查询有很多变体,这会变得复杂。参见例如here。 如果您的查询完全是任意的(如果您的用户可以输入“WHERE”本身)...您就有麻烦了。

【讨论】:

  • 用户自己无法输入 WHERE 位,但可能会有太多变化,无法按照您建议的方式进行操作。在这种情况下,您将如何防止 SQL 注入?
  • 如果它们是 WHERE 条件的变化,请查看我发布的链接。在其他地方,恐怕我需要更多信息。
  • 它们通常是 WHERE 条件,但实际上,它可以是任何条件。
  • 这可能很丑,甚至很危险。
【解决方案2】:

打几个问号:

PreparedStatement s = new PreparedStatement("SELECT X FROM Y WHERE ID = ?");
s.setString(1, "123456");
s.execute();
// ...

更多信息在这里:http://download.oracle.com/javase/tutorial/jdbc/basics/prepared.html

【讨论】:

    【解决方案3】:

    是的,您可以输入以下内容:

    "WHERE id=?";
    preparedStatementInstantce.setInt(id);
    

    【讨论】:

      【解决方案4】:

      当您使用 PreparedStatement 时,您可以用问号替换您的注入值

      WHERE id=?
      

      然后您可以使用 PreparedStatement 对象上的设置器来插入它们。

      pstmt.setInt(1, 5);
      

      【讨论】:

        【解决方案5】:

        你也可以按照

        WHERE (id = ? OR false = ? ) AND (name = ? OR false = ?) --etc
        

        并把假=?当你得到相应的参数时,标志为真

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-09-12
          • 1970-01-01
          • 2013-06-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多