基本上,我想做的是:

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

他们显然可以很容易地通过在其中放入无义内容来创建SQL错误,但是mysql_query只允许您执行一个查询,所以他们不能放入像1; DROP TABLE ...这样的内容.

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

如果是,我如何清理查询?

由于$_GET['order']变量采用类似SQL的语法,因此有很多逻辑构建在此之上,因此我真的不想更改格式.


需要说明的是,$_GET['order']不仅仅是一个字段/列.可能是last_name DESC, first_name ASC左右.

推荐答案

是的,SQL注入攻击可以使用未转义的ORDER BY子句作为向量.这里解释了如何利用这一点,以及如何避免此问题:

http://josephkeeler.com/2009/05/php-security-sql-injection-in-order-by/

这篇博文建议使用白名单来验证ORDER BY参数,这几乎肯定是最安全的方法.


要响应更新,即使该子句很复杂,也可以编写一个 routine ,根据白名单对其进行验证,例如:

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中的其他位置公开我的数据库 struct ,并且通常会给URL中的参数中的内容加上别名,并使用散列将其映射到实际值.

Database相关问答推荐

撤销语句释放类实例中可用的缓冲区

我们可以在 CnosDB 中的单个数据库中创建的标签数量是否有限制?

Android SQLiteno such table异常

我们如何使用 Hibernate 和 JPA 调用存储过程?

何时将数据库称为嵌入式数据库?

每个请求可以多次查询 MongoDB 吗?

在 PostgreSQL 中使用 pg_notify(text, text) 监听/通知

如何处理 SQL Server 中列名中的空格?

Windows 环境下无法识别 postgres 'psql' 命令

我们如何保存在 sqlite3 中创建的数据库

为什么有人需要内存数据库?

用于 Java 桌面应用程序的最佳数据库是什么

触发器、断言和判断之间有什么区别?

执行语句还是运行脚本?

无法加载时区?

是否有标准的Electron 商务数据库架构来将折扣/税收/礼券应用于产品?

数据完整性和数据一致性之间有什么区别吗?

复式记账的关系数据模型

App=EntityFramework 在 Sql 连接字符串中有什么作用?

DBMS中数据模型和数据库模式的区别?