使用 Order by 的准备语句来防止 SQL 注入 java

Using prepared statement for Order by to prevent SQL injection java

我有一个关于 where conditions 、 order by 和 limit 的查询。我正在使用准备好的语句来设置 where 条件和限制。目前我正在使用字符串追加命令导致 SQL 注入漏洞。

我不能像这样使用设置字符串来订购 order by ? ? SQL 如果我这样做,订购功能将不起作用。

示例查询:

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 注入。

做这样的事情并连接它:

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...

您可以进行消毒和其他操作,但这应该适用于您的情况

您应该使用可能列的白名单:

String[] cols = {"siteid", "technology", "address", "state", "status"};

然后在与用户引用列时使用索引:

int colFromUser = Integer.parseInt(request.getParameter("sortCol"));

并在将列名附加到 order by 列表之前验证索引:

if(colFromUser < 0 || colFromUser >= cols.length) {
    throw new IllegalArgumentException("Invalid column");
}
String col = cols[colFromUser];
query.append(col);

尽管如果是我,我会使用 Hibernate criteria 之类的东西来完成这项工作:

Criteria c2 = session.createCriteria(Supplier.class);
c2.addOrder(Order.desc("name"));

PreparedStatement SetMethods 仅适用于数据库 table 列值( WHERE 子句值 SELECT & DELETE SQL 语句以及包括更新或插入 UPDATEINSERT 语句的列值)。

所以这意味着遵循通常的 SQL 部分,例如 - 列名、table 模式、table 名称、ORDER BY、GROUP BY、分页(LIMIT、OFFSET、FETCH FIRST etc ) 不能通过 java.sql.PreparedStatement

的问号符号 ( ? ) 进行参数化

直接将用户输入的值附加到查询会导致安全漏洞,唯一的出路是检查 有效值 列表中的输入值 SQL.

例如table 你期待什么名字? ,特定的 table 应该是什么模式? ,特定 table 中存在哪些列? , 页码是整数吗?, LIMIT 值是整数吗? ORDER BY 子句的列名后的值只能是 ASCDESC 而不能是其他等等

您可以动态填充这些有效值或在系统中进行硬编码。

如果传递了无效值,那么我们要么不执行查询(并将其记录为错误),要么用有用的默认值替换无效值并执行查询。