提交 SQL 查询时是否需要验证列名


Is it necessary to validate column names when submitting an SQL Query?

在我的SQL查询中,我从用户填写的表单中提交数据,如图所示,无法使用PDO参数化我的列名。这很重要,因为查询中的列名是根据 form.

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

这是避免SQL注入的好事吗

不。

或者只是浪费系统资源

不。

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

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

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

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

要查询的数据库。这是他们唯一的目的。无法维持简单选择查询的数据库是无稽之谈。查询是不同的。插入一个比 10 个选择重得多。您必须通过质量而不是数量来区分查询。

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

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

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

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

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

至于他们正在寻找的值,绝对擦洗/清理它以防止SQL注入。

您可以对列名称进行硬编码以使其更快。还可以缓存拉取的表说明,这样就不需要每次表架构更改时都更新代码。