提问人:scottyboombox 提问时间:5/4/2023 更新时间:5/6/2023 访问量:245
我可以使用 if 语句来防止 SQL 注入吗?
Can I use if statements to prevent SQL injection?
问:
我一直在尝试让我的应用程序通过Checkmarx,但我一直遇到二阶SQL注入漏洞。
目前我的代码如下所示:
public static final String SELECT_NEXTVAL_FOR = "SELECT NEXTVAL FOR ";
@Value("#{ systemProperties['sequence.schema']}")
String sequenceSchema;
public Integer getNextContactId() {
if (sequenceSchema.matches("[A-Z]{3}@[A-Z]{3}|[A-Z]\\d[A-Z]{5}")) {
Query getNextContactIdQuery = entityManager.createNativeQuery(
SELECT_NEXTVAL_FOR + sequenceSchema + ".CNTCT_ID FROM SYSIBM.SYSDUMMY1");
return (Integer) getNextContactIdQuery.getSingleResult();
} else {
return null;
}
Checkmarx在这里将问题标记为问题。我的想法是,if 语句将确保中存在的任何内容仅与我们的架构的特定正则表达式匹配。显然这还不够好。我尝试使用位置/命名参数,但这些参数在 WHERE 或 HAVING 子句之外不起作用。我尝试过此处看到的条件查询,但没有任何运气。sequenceSchema
sequenceSchema
我有另一个想法,与我在这里的想法类似,但是我可以创建一组有效的模式并将其与以下模式进行比较,而不是使用正则表达式:sequenceSchema
public static final String SELECT_NEXTVAL_FOR = "SELECT NEXTVAL FOR ";
@Value("#{ systemProperties['sequence.schema']}")
String sequenceSchema;
Set<String> validSchemas = ... //create set of valid schemas
public Integer getNextContactId() {
if (validSchemas.contains(sequenceSchema)) {
Query getNextContactIdQuery = entityManager.createNativeQuery(
SELECT_NEXTVAL_FOR + sequenceSchema + ".CNTCT_ID FROM SYSIBM.SYSDUMMY1");
return (Integer) getNextContactIdQuery.getSingleResult();
} else {
return null;
}
这会阻止 SQL 注入吗?如果不是,为什么?我真的很难在这里找到一个可行的解决方案。
答:
我不会为你做你的工作......但是你的问题可以概括为“为什么我要进行SQL注入?
答案是“因为我在动态创建 SQL 查询”,所以解决方案是:停止进行动态创建的 SQL 查询。一旦你停止这样做,你所有的问题都会消失。你怎么停下来?与变量绑定(参数化查询)一起使用。PreparedStatement()
使用 sql 访问将如下所示:PreparedStatement()
string what_schema= //! Some value;
String query = SELECT_NEXTVAL_FOR + "?.CNTCT_ID FROM SYSIBM.SYSDUMMY1";
PreparedStatement pstmt = connection.prepareStatement(query);
pstmt.setString(1, what_schema);
ResultSet results = pstmt.executeQuery();
评论
建议使用查询参数来防御 SQL 注入的人说对了一半。在大多数动态 SQL 查询的情况下,这是推荐的解决方案。
但查询参数只能用于代替常量值。不是标识符(在本例中是架构标识符)、表达式或 SQL 关键字等。
使用某种验证是正确的,因此架构标识符被限制为已知的安全值。然后,可以将该字符串插入到 SQL 查询中。如果您已经进行了充分的验证,那么它就不会被 SQL 注入。
您还应该分隔标识符,以防它包含空格或标点符号,或者与 SQL 保留关键字冲突。在 DB2 中,使用双引号作为标识符分隔符。
但是,即使您正在执行的验证类型可能就足够了,它也可能不是一种可以被 Checkmarx 等自动 SQL 注入检测工具识别的防御方法。它可能会看到你正在将变量放在一个 SQL 字符串中,并得出结论,这是一个 SQL 注入风险。它无法判断您的验证是否足以防止出现问题。
用于 SQL 注入检测的自动化解决方案始终受到限制。有时您必须使用人工分析。
我知道现在这样说是不合时宜的,因为有一种趋势是说人工智能会让程序员失业。但人工智能还不能像专家人类那样可靠地处理边缘情况。我不相信它会永远存在。
评论