我正在使用Appscan源代码版本进行Java安全编码。它在我的应用程序中报告了一个SQL注入。问题是我们在代码中动态生成查询,所以我不能使用预准备语句。相反,我必须使用e 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()
如何解决此问题?
发布于 2015-08-15 16:46:59
你应该做的是
final String s = "SELECT name FROM users WHERE id = ?"
statement = connection.prepareStatement(s);
statement.setString(1, userId);发布于 2015-08-15 18:01:17
encodeForSQL的文档推荐了一个仍然可以使用的PreparedStatement,它可以动态生成查询:
根据所选的编解码器(适当的编解码器包括MySQLCodec和OracleCodec)对
查询中使用的输入进行编码。不推荐使用此方法。使用PreparedStatement接口是首选方法。但是,如果由于某种原因这是不可能的,那么这个方法是作为一个较弱的替代方法提供的。最好的方法是确保所有的单引号都是双引号的。另一种可能的方法是使用1.5.6节中的JDBC规范中描述的{转义}语法。但是,此语法并不适用于所有驱动程序,需要修改所有查询。
让我们检查一下编码器正在做什么,以了解为什么您的代码有注入漏洞。编码器在oracle编解码器中调用encodeCharacter,它简单地将单引号替换为两个单引号:
public String encodeCharacter( char[] immune, Character c ) {
if ( c.charValue() == '\'' )
return "\'\'";
return ""+c;
}只有当值包含在单引号中时,这才有意义,字符串值就是单引号。如果id实际上是一个整数,并且您希望将其与查询连接起来,那么您应该首先将其转换为int类型,而不是使用此编码器。
https://stackoverflow.com/questions/31293417
复制相似问题