【问题标题】:Using prepared statement for Order by to prevent SQL injection java使用Order by的预处理语句来防止SQL注入java
【发布时间】:2018-01-29 15:08:03
【问题描述】:

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

如果我这样做,我不能使用设置字符串来像这样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 注入。

【问题讨论】:

  • 除了连接所需的列之外,您别无选择,但在此之前自己清理字符串。
  • 确保该列是已知的可排序列

标签: java prepared-statement sql-injection


【解决方案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...

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

【讨论】:

    【解决方案2】:

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

    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"));
    

    【讨论】:

      【解决方案3】:

      PreparedStatement SetMethods 仅适用于数据库表列值(WHERE 子句值用于SELECTDELETE SQL 语句,还包括要更新或插入的列值用于UPDATEINSERT 语句) .

      因此,这意味着不能通过问号符号 (@987654327) 参数化以下常见的 SQL 部分,如列名、表架构、表名、ORDER BY、GROUP BY、分页(LIMIT、OFFSET、FETCH FIRST 等) @ ) 的 java.sql.PreparedStatement

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

      例如你期待什么表名? ,特定表应该是什么模式? ,特定表中存在哪些列? , 页码是整数吗?, LIMIT 值是整数吗? ORDER BY 子句的列名后的值只能是 ASCDESC & 没有别的等等等等。

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

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

      【讨论】:

        猜你喜欢
        • 2021-06-21
        • 2011-10-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多