【问题标题】:Is it necessary to validate column names when submitting an SQL Query?提交 SQL 查询时是否需要验证列名?
【发布时间】:2012-04-24 06:57:28
【问题描述】:

在我的 SQL 查询中,我从用户填写的表单中提交数据,如 here 所示,无法使用 PDO 参数化我的列名。这很重要,因为查询中的列名是根据表单中的字段名动态插入的。

我可以很容易地验证 $_POST 数组中提交的列名,只需将它们从数据库中提取出来并丢弃任何不匹配的内容。这是避免 SQL 注入的好事还是只是浪费系统资源(因为它有效地使依赖数据库的任何请求的执行加倍)?

【问题讨论】:

    标签: php mysql pdo sql-injection


    【解决方案1】:

    这是避免SQL注入的好方法

    没有。

    或者只是浪费系统资源

    没有。

    这不能浪费,因为它只是从系统表中简单选择。

    但是当用户不允许进入某些字段时,它仍然可以是某种注入。比如说,如果有一个由站点管理员填写的(虚构的)字段“user_role”,并且用户可以在 POST 中定义它,他们可以更改他们的访问权限。

    因此,硬编码(白名单)允许的字段是唯一可靠的方法。

    因为它有效地使依赖数据库的任何请求的执行加倍

    男人。打算查询的数据库。这是他们唯一的目的。不能支持简单选择查询的数据库是无稽之谈。查询不同。插入一个比 10 个选择要重得多。您必须按质量而不是数量来区分查询。

    查询中的列名是根据表单中的字段名动态插入的。

    虽然对于插入/更新查询来说这是完全正确的,但对于 SELECT 查询来说,这是糟糕设计的一个重要标志。我可以在 WHERE/ORDER BY 子句中保留变量字段名,但如果您必须在表名子句的字段集中进行 vem - 您的数据库设计肯定是错误的。

    【讨论】:

    • 可能应该更清楚,我的 SELECT 查询不使用动态字段名称。正如你所说,那将是愚蠢的。
    【解决方案2】:

    除了对列列表进行硬编码之外,您还可以通过数据库中的另一个表来构建列列表,以便允许从中查询列,例如

    QuerableSources
    SrcTable      SrcColumn      DescriptToUser
    SomeTable     SomeColumn     Column used for
    AnotherTable  AnotherColumn  Something Else
    etc.
    

    然后,您构建一个组合框供用户选择“DescriptionToUser”内容以便于阅读,并控制有效的列和表源。

    至于他们正在搜索的 VALUE,一定要擦洗/清理它以防止 SQL 注入。

    【讨论】:

      【解决方案3】:

      您可以对列名进行硬编码以加快速度。还可以缓存拉取的表描述,这样就不用在每次表schema改变的时候更新代码。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-06-30
        • 1970-01-01
        • 2021-01-24
        • 2021-06-02
        • 1970-01-01
        • 1970-01-01
        • 2014-09-29
        相关资源
        最近更新 更多