使用 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 语句以及包括更新或插入 UPDATE
和 INSERT
语句的列值)。
所以这意味着遵循通常的 SQL 部分,例如 - 列名、table 模式、table 名称、ORDER BY、GROUP BY、分页(LIMIT、OFFSET、FETCH FIRST etc ) 不能通过 java.sql.PreparedStatement
的问号符号 ( ?
) 进行参数化
直接将用户输入的值附加到查询会导致安全漏洞,唯一的出路是检查 有效值 列表中的输入值 SQL.
例如table 你期待什么名字? ,特定的 table 应该是什么模式? ,特定 table 中存在哪些列? , 页码是整数吗?, LIMIT 值是整数吗? ORDER BY
子句的列名后的值只能是 ASC
或 DESC
而不能是其他等等
您可以动态填充这些有效值或在系统中进行硬编码。
如果传递了无效值,那么我们要么不执行查询(并将其记录为错误),要么用有用的默认值替换无效值并执行查询。
我有一个关于 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 语句以及包括更新或插入 UPDATE
和 INSERT
语句的列值)。
所以这意味着遵循通常的 SQL 部分,例如 - 列名、table 模式、table 名称、ORDER BY、GROUP BY、分页(LIMIT、OFFSET、FETCH FIRST etc ) 不能通过 java.sql.PreparedStatement
?
) 进行参数化
直接将用户输入的值附加到查询会导致安全漏洞,唯一的出路是检查 有效值 列表中的输入值 SQL.
例如table 你期待什么名字? ,特定的 table 应该是什么模式? ,特定 table 中存在哪些列? , 页码是整数吗?, LIMIT 值是整数吗? ORDER BY
子句的列名后的值只能是 ASC
或 DESC
而不能是其他等等
您可以动态填充这些有效值或在系统中进行硬编码。
如果传递了无效值,那么我们要么不执行查询(并将其记录为错误),要么用有用的默认值替换无效值并执行查询。