在“ORDER BY”子句之后有什么可以放置的可能构成安全风险的东西吗?

2022-08-30 17:34:30

基本上,我想做的是这样的:

mysql_query("SELECT ... FROM ... ORDER BY $_GET[order]")

他们显然可以通过在其中放置无意义来轻松创建SQL错误,但只允许您执行1个查询,因此他们不能放置类似.mysql_query1; DROP TABLE ...

除了创建语法错误之外,恶意用户还可能造成任何损害吗?

如果是这样,如何清理查询?

有很多逻辑建立在类似SQL的语法的变量上,所以我真的不想改变格式。$_GET['order']


为了澄清,将不仅仅是单个字段/列。它可能类似于 .$_GET['order']last_name DESC, first_name ASC


答案 1

是的,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中参数中的东西起个别名,并使用哈希将其映射到实际值。


答案 2

不要指望此时的SQL注入目前不会引起问题;不允许任何 SQL 注入。如果不出意外的话,恶意攻击者可以定义一个非常复杂的顺序,这可能会导致数据库严重变慢。


推荐