【问题标题】:Appscan source edition - SQL InjectionAppscan 源码版 - SQL 注入
【发布时间】:2015-09-26 09:47:15
【问题描述】:

我正在使用 Appscan 源代码版本进行 Java 安全编码。它在我的应用程序中报告 SQL 注入。问题是我们在代码中动态生成查询,所以我不能使用准备好的语句。相反,我必须使用Esapi.encoder().encodeForSql(new OracleCodec(), query)。 AppScan 不认为这可以缓解 SQL 注入问题。

final String s = "SELECT name FROM users WHERE id = " +
    Esapi.encoder().encodeForSql(new OracleCodec(), userId);            
statement = connection.prepareStatement(s);

此代码还不适用于ESAPI.encoder()

我该如何解决这个问题?

【问题讨论】:

    标签: java sql-injection owasp esapi secure-coding


    【解决方案1】:

    你应该做的是

    final String s = "SELECT name FROM users WHERE id = ?"
    statement = connection.prepareStatement(s);
    statement.setString(1, userId);
    

    【讨论】:

      【解决方案2】:

      encodeForSQL 的文档推荐了一个 PreparedStatement,您仍然可以使用它来动态生成查询:

      根据所选编解码器对输入进行编码以用于 SQL 查询 (适当的编解码器包括 MySQLCodec 和 OracleCodec)。 这个 不推荐方法。 PreparedStatement接口的使用 是首选方法。但是,如果由于某种原因这是 不可能,则提供此方法作为较弱的替代方法。 最好的方法是确保任何单引号都是双引号。 另一种可能的方法是使用中描述的 {escape} 语法 1.5.6 节中的 JDBC 规范。但是,这种语法不 与所有驱动程序一起工作,并且需要修改所有查询。

      让我们检查一下编码器在做什么,看看为什么你的代码存在注入漏洞。编码器在 oracle 编解码器中调用 encodeCharacter,它只是将单引号替换为两个单引号:

      public String encodeCharacter( char[] immune, Character c ) {
          if ( c.charValue() == '\'' )
              return "\'\'";
          return ""+c;
      }
      

      仅当值在单引号内时才有意义,即字符串值。如果id 实际上是一个整数,并且您想将它与查询连接起来,那么您应该先将其转换为 int 类型,而不是使用此编码器。

      【讨论】:

        猜你喜欢
        • 2014-09-24
        • 2020-08-25
        • 1970-01-01
        • 2017-07-19
        • 2016-08-22
        • 2011-03-27
        • 2022-01-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多