如何为用户输入生成的 mySQL 列添加添加安全性?

Posted

技术标签:

【中文标题】如何为用户输入生成的 mySQL 列添加添加安全性?【英文标题】:How can I add security to a mySQL column addition generated by user input? 【发布时间】:2020-03-15 16:02:51 【问题描述】:

使用 php 7 和 mysql 8

首先让最终用户生成一个新列并不是最好的主意,但在这种情况下(以及其他不易使用常见 PDO 策略的情况),提供针对 SQL 的安全性的解决方案是什么注射?

我正在尝试做的事情: 我有一个动态注册表,它从数据库中获取输入,并且该网站的所有者可以在此表单中添加字段。当然,如果在表单中添加了一个新字段,那么数据库中也必须添加一个新列来存储数据。直接插入没有问题,但如果有人侵入管理系统,他们可以轻松添加 sql 注入。因此,我试图找到一种更安全的方法。

工作(不安全)代码:

  //$fName is the field name and also the column name
  $fName= $_POST['fName'];
  $sql2=$pdo->prepare("ALTER TABLE attendee ADD $fName VARCHAR( 255 )");
  $go2=$sql2->execute();

我尝试过的: 我研究过白名单,但我认为这不是最佳选择,因为列名称的可能性是无穷无尽的。

//Tried using named paramater PDO array (also tried unnamed ? version)
  $data2=[
    'fName'=>$fName
         ];
  $sql2=$pdo->prepare("ALTER TABLE attendee ADD :fName VARCHAR( 255 )");
  $go2=$sql2->execute($data2);

//Using PDO Quote indirectly
  $roger=$pdo->quote($fName);
  $sql2=$pdo->prepare("ALTER TABLE attendee ADD $roger VARCHAR( 255 )");
  $go2=$sql2->execute();

//Using PDO Quote Directly with concatenation
  $sql2=$pdo->prepare("ALTER TABLE attendee ADD" . $pdo->quote($fName) . " VARCHAR( 255 )");
  $go2=$sql2->execute();

【问题讨论】:

您可以考虑一个可接受的列名的白名单,并检查该名称是否在该列表中。 啊,谢谢尼克的回答!我还将把它添加到我尝试过/考虑过的内容中。我不认为白名单在这种情况下会起作用,因为他们将来会为该列命名的内容超出了我的范围。 我只是使用正则表达式验证或过滤用户选择的列名。只允许普通字符和格式,例如/^[a-z][a-z0-9-]1,20$/i .之后就可以安全使用了。不要忘记检查重复的列名。同样重要的是:在列名和表名周围使用反引号`。但我支持@Your Common Sense,即编号的列名可以工作并且完全兼容 PDO。批量添加列(每 10 个左右)也将最小化表重建。 【参考方案1】:

根据用户输入命名额外的列绝对没有意义

只需将它们命名为 extra_column1、extra_column2 等。

对于像您这样的完全自动化的系统,这没问题。对于这个系统,您将不可避免地需要维护一种映射,其中列名链接到一些元数据,如显示名称等,因此只需将 extra_column1 作为列名添加到此映射中。

【讨论】:

我已经实现了这个解决方案,但这是最后的手段,因为还有一个 CSV 生成器,公司将使用它从注册表单中获取信息。他们已经明确表示希望将标题(列名)作为 CSV 的一部分,因此拥有 extra_column 1、extra_column_2 等将是不令人满意的。 我完全不明白这是个问题。您必须使用显示名称,而不是 csv 标题的列名称。您在 html 表格标题和 HTML 表单标签中显示的内容相同。【参考方案2】:

通过 SQL 查询添加字段或添加列没有区别,因为两者都写入数据库,因此 sql-injection 在这两种情况下都是可能的,不仅在添加列时,特别是如果您直接将用户输入传递给 SQL 查询而不转义不需要的字符。

所以只需关心用户输入,正确清理所有输入。

谢谢, 杰基萨拉夫

【讨论】:

以上是关于如何为用户输入生成的 mySQL 列添加添加安全性?的主要内容,如果未能解决你的问题,请参考以下文章

如何为动态生成的输入文件添加“多个”属性?

刷新令牌如何为 jwt 添加安全性?

excel 如何为列添加指定内容(字符串)

Angular.js:如何为价格添加用户输入并保持小计

如何为对象的特定变量添加管理员用户名和密码字段?

如何为任何输入添加带有快捷方式的特殊字符?