是的,SQL 注入攻击可以使用未转义的 ORDER BY 子句作为向量。这里有一个关于如何利用它以及如何避免这个问题的解释:
http://josephkeeler.com/2009/05/php-security-sql-injection-in-order-by/
该博客文章建议使用白名单来验证 ORDER BY 参数,这几乎可以肯定是最安全的方法。
要响应更新,即使子句很复杂,您仍然可以编写一个例程来根据白名单对其进行验证,例如:
function validate_order_by($order_by_parameter) {
$columns = array('first_name', 'last_name', 'zip', 'created_at');
$parts = preg_split("/[\s,]+/", $order_by_parameter);
foreach ($parts as $part) {
$subparts = preg_split("/\s+/", $part);
if (count($subparts) < 0 || count($subparts) > 2) {
// Too many or too few parts.
return false;
}
if (!in_array($subparts[0], $columns)) {
// Column name is invalid.
return false;
}
if (count($subparts) == 2
&& !in_array(strtoupper($subparts[1]), array('ASC', 'DESC')) {
// ASC or DESC is invalid
return false;
}
}
return true;
}
即使 ORDER BY 子句很复杂,它仍然只是由您提供的值构成的(假设您不允许用户手动编辑它)。您仍然可以使用白名单进行验证。
我还应该补充一点,我通常不喜欢在URL或UI中的其他地方公开我的数据库结构,并且经常会给URL中参数中的东西起个别名,并使用哈希将其映射到实际值。