我有一个查询条件,排序和限制。我正在使用预准备语句来设置where条件和限制。目前我正在使用字符串追加来导致SQL注入漏洞。
我不能像这样使用set string来排序order by ? ?
如果我这样做,SQL Order功能就不起作用了。
示例查询:
SELECT siteid, technology, address, state, status FROM archive LEFT OUTER
JOIN mappings ON siteid = child_site_id order by siteid asc limit ? offset ?
SELECT siteid, technology, address, state, status FROM archive LEFT OUTER
JOIN mappings ON siteid = child_site_id order by siteid asc limit 10 offset 0
我可以采用其他任何方式来避免SQL注入。
答案 0 :(得分:1)
执行类似的操作并将其连接起来:
List<String> allowedSortableColumns = Arrays.asList(new String[]{"siteid", "technology", "address"})
if(! allowedSortableColumns.contains(sortByColumn)){
throw new RuntimeException("Cannot sort by: " + sortByColumn);
}
// Continue here and it's safe to concatenate sortByColumn...
你可以做消毒和其他事情,但这应该适合你的情况
答案 1 :(得分:1)
您应该使用可能列的白名单:
const getInnerResult = (x, y, input) => {
switch (input) {
case 1:
case 3: return x;
case 2: return y;
default: return null;
}
}
const getResult = function(input) {
const result = getInnerResult("a", "b", input);
// Other logic using the `result` variable
return result ? result.toUpperCase() : "-";
};
console.log(getResult(2));
console.log(getResult(5));
然后在向用户引用列时使用索引:
String[] cols = {"siteid", "technology", "address", "state", "status"};
并在将列名附加到int colFromUser = Integer.parseInt(request.getParameter("sortCol"));
列表之前验证索引:
order by
虽然如果是我,我会使用Hibernate criteria之类的东西来完成这项工作:
if(colFromUser < 0 || colFromUser >= cols.length) { throw new IllegalArgumentException("Invalid column"); } String col = cols[colFromUser]; query.append(col);
答案 2 :(得分:0)
PreparedStatement SetMethods仅适用于数据库表列值(WHERE
和SELECT
SQL语句的DELETE
子句值,还包括{ {1}}和UPDATE
语句)。
因此,这意味着不能通过问号符号({{}来参数化以下常用的SQL部分,例如列名,表模式,表名,ORDER BY,GROUP BY,分页(LIMIT,OFFSET,FETCH FIRST等) 1}})的INSERT
将用户输入中的值直接附加到查询中将导致安全漏洞,唯一的出路是从有效值列表中检查这些SQL部分的输入值。
例如您期望使用什么表名? ,特定表应采用哪种模式? ,特定表中存在哪些列? ,页码是整数吗?LIMIT值是整数吗? ?
子句的列名之后的值只能是java.sql.PreparedStatement
或ORDER BY
,而不能是其他等等。
您可以动态填充这些有效值或系统中的硬代码。
如果传递了无效值,那么我们要么不执行查询(并将其记录为error),要么将无效值替换为有用的默认值并执行查询。