【问题标题】:SQL injection | Changing id valuesSQL注入 |更改 id 值
【发布时间】:2013-08-23 05:03:20
【问题描述】:

我遇到了一个 sql 注入问题。我的页面显示表格的数据如下:

<input type="checkbox" name="id[]" value="<?php echo $row['id']; ?>" /><?php echo $row['data']; ?><br />

如何确定提交的值是该特定行的 id 而不是页面中“注入”的随机数?

显然,我会开始检查 id 是否返回 trueis_numeric() / 通过 mysql_real_escape_string(). 得到它

然后,我想到了两个选择:

  • 使用 $row['data'] 的副本添加隐藏输入,以便我可以 在mysql_query()之前检查id和数据的对应关系

  • 将行的 id 从一个自动递增的数字更改为一个大的随机数,这样我就可以降低幸运命中的机会。

我有错吗?有更好的主意吗? 感谢您的帮助!

【问题讨论】:

标签: php sql input xss sql-injection


【解决方案1】:

你不能。您的两种选择都存在根本缺陷:

  • 可以更改复选框值的人可以很好地更改隐藏输入的值。
  • 您的“随机 ID”仍然可以在 Dev Tools、Firebug 或类似工具上看到。

您不必担心用户如何发送数据,而应该担心数据是否有效以及用户是否具有给定操作的权限。


另外,is_numeric 不是我最喜欢的,因为它会以十六进制和指数表示法返回 true。我建议检查ctype_digit 或简单地进行(int) 演员表,例如:

if (!isset($_POST['id'])) die('invalid data');
$id = (int) $_POST['id'];
if ($id == 0) die('invalid id');

非数字字符串转换为0,自动递增字段通常将1 作为第一个值。如果0 是一个有效值,您需要调整上面的代码,例如:

if (!isset($_POST['id']) || !ctype_digit($_POST['id'])) die('invalid data');
$id = (int) $_POST['id'];

然后,检查给定 ID 是否存在于您的数据库中。进行适当的权限检查,就是这样。


您的服务器如何获取数据并不重要,重要的是数据是否有效以及用户有权执行给定操作。您在前端/界面中所做的任何事情都可以被黑客或任何中等经验的 Web 开发人员轻松更改和操纵。

专注于限制未经授权的访问并保持您的数据库完整性。无论请求是从您的页面、被篡改的页面还是通过终端发出的,都可以轻松复制所有标题和发布的数据,以看起来来自您的请求页面。


毕竟,我不确定您是否可以将其称为“SQL 注入”。您的应用程序的函数需要一些包含整数值的输入。现在剩下的就是检查是否提供了必要的输入并且是否有效。所有用户输入都必须被视为不安全的,并且在被投入查询之前必须经过适当的验证和转义。

另外,请查看PDO,它可以很好地处理值转义。 mysql_* 扩展和 mysql_real_escape_string 函数已被弃用,很容易出现人为错误。

关于防止 SQL 注入,问题 cmets 中的linked thread 是一本不错的读物。

【讨论】:

  • 非常感谢您的详尽解释!我几乎没有发现 mysql API 已被弃用......我知道,目前,使用 mysql 还不是安全问题,而是将来要放弃的东西,对吧?
  • @Greg 实际上使用mysql_* 已经被弃用十多年了,但是是的.. 并不是mysql_*邪恶,而是人们使用它的方式.很容易误用它。您可以使用 PDO 连接到 mysql 服务器,只需不到一两个小时即可完成我在答案中链接的 micro-PDO 教程,并且尽快学习它将为您免去很多麻烦。 . =]
  • 一般建议是,如果您正在开始一个新应用程序或刚开始学习,最好使用最新的扩展程序开始它,而不是那些旧的已弃用的东西。 :)
猜你喜欢
  • 1970-01-01
  • 2013-07-27
  • 1970-01-01
  • 2021-12-19
  • 2018-06-06
  • 2023-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多