【问题标题】:Is SQL injection possible with this query?此查询是否可以进行 SQL 注入?
【发布时间】:2011-07-06 01:20:15
【问题描述】:
UPDATE `company` SET `itnumber` = '595959' WHERE (id = 932) 

所以 itnumber 的值来自该公司的用户输入。我想确保我能够防止任何类型的 sql 注入。所以用户输入 595959,我在动态查询中将该值构建为“595959”。在这个查询中是否仍然可能有 sql 注入攻击?我知道使用prepare语句来防止sql注入,但是prepare语句可能需要我的应用程序进行大量的开发工作,所以我正在寻找更省时、更简单的方法来修复我的大部分sql语句注入是可能的.

StringBuffer sb = new StringBuffer();
sb.append(" UPDATE ");
sb.append(DB.quote(table));
sb.append(" SET ");
/* logic if column value has changed */
/* if yes */
sb.append(DB.quote(column.name));
sb.append(" = ");
sb.append(column.getSQLvalue());
sb.append(" WHERE (id = ");
sb.append(columns[0].getSQLvalue());
sb.append(")");
execute(sb.toString());

【问题讨论】:

  • 分析 SQL 注入是否可能需要查看生成 SQL 的,而不是生成的 SQL。
  • @Alexander Pogrebnyak - 猜测一下,SQL 字符串可能是在 Java 应用程序中构造的。
  • 我们需要生成查询的动态 SQL 等等。
  • 学习使用 Prepare Statements 的时间是值得的,而且时间并不长。这就像说“我没有时间学习如何制作水泥,我可以用强力胶建造房子吗?” :)

标签: java sql sql-injection


【解决方案1】:

如果您只是将输入连接成一个 SQL 字符串而不进行任何清理(并且只是用单引号 ' 将其括起来并不能使其干净),那么是的,它容易受到 SQL 注入的攻击。

请发布构造此 SQL 的代码以获得明确的答案。


更新:

由于您使用的是 Oracle SQL 库中的getSQLvalue(),这将确保传入的值被正确转义。这对于 SQL 注入确实是安全的,但是它需要您记住在每个地方都使用它。但是,使用参数可以确保相同,而不会忘记转义 SQL 值。

【讨论】:

    【解决方案2】:

    是的,是的。例如:

    UPDATE `company`
    SET `itnumber` = '595959'; DROP TABLE company; --' WHERE (id = 932)
    

    可能会工作。

    【讨论】:

    • 我试过这个,但它存储了 595959';DROP TABLE company;-- for itnumber 字段的值。
    • 这取决于您正在更新的数据库类型以及您在代码中构建动态 SQL 字符串的方式。你有可以给我们看的例子吗?
    【解决方案3】:

    我知道使用准备语句 用来防止sql注入,但是 准备语句可能需要很多时间 我的发展努力 应用程序,所以我正在寻找更少 耗时且更容易的方法 修复我的大部分 sql 语句 注射是可能的。

    您会惊讶于从一开始就以right 方式实施解决方案所花费的时间少了多少。另外,这怎么比连接查询字符串更复杂?

    PreparedStatement pstmt = con.prepareStatement(
           "UPDATE `company` SET `itnumber` = ? WHERE (id = ?)"
       );
    pstmt.setString(1, "595959");
    pstmt.setInt(2, 932);
    

    另外,大多数现代驱动程序都会缓存准备好的语句的执行计划,这将加快其他查询的速度。

    【讨论】:

      【解决方案4】:

      真正最安全的做法是为此创建一个存储过程,然后您的数据类型至少可以保护您一点。

      CREATE PROC usp_Update_itnumber_by_Company_Id
      
      @itnumber int
      , @Company_Id int
      
      as
      
      BEGIN TRAN    
      UPDATE [Company]
      SET itnumber = @itnumber
      WHERE id = @Company_Id;
      
      COMMIT TRAN 
      

      这样 if if ; DROP TABLE 公司; --' WHERE (id = 932) 被传递到@Company_Id 它将失败,因为数据类型是不匹配的。

      如果您尝试确定要更新哪些列并且仅当它们已更改时,您可以考虑执行 MERGE 而不是 UPDATE 语句。这样您就可以提取记录的当前状态,并且仅在它们不相同时才更新。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-02-14
        • 2020-04-26
        • 2014-06-09
        • 2010-09-08
        • 1970-01-01
        • 2015-04-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多