2013-08-21 41 views
0

我陷入了一个SQL注入问题。我的页面显示如下表的数据:SQL注入|更改ID值

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

我怎么能肯定的是,提交的值是该特定行的id的不是一个随机数“注射”的页面?

很显然,我将开始检查该ID返回is_numeric() /通过mysql_real_escape_string().

得到它。然后,我想到了两个选项:

  • 添加一个隐藏的输入与副本的$ row ['data'],这样我就可以在 之前检查id和数据之间的对应关系mysql_query()

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

我有错吗?有什么更好的想法 感谢您的帮助!

+0

我首先阅读[如何防止SQL注入PHP?](http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php)和[为什么我不应该在PHP中使用mysql_ *函数?](http://stackoverflow.com/questions/12859942/why-shouldnt-i-use-mysql-functions-in-php) – 2013-08-21 00:32:50

+0

感谢您的提示! – Greg

回答

2

你不能。你的两个选项也有根本的缺陷:

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

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


而且,is_numeric不是我喜欢的,因为它会返回true为十六进制和指数描述。我建议你用ctype_digit检查或干脆做一个(int)投,例如:

​​3210

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

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

之后,请检查您是否DB存在给定的ID。做适当的权限检查,就是这样。


不要紧,你的服务器是如何得到的数据,重要的是数据是有效的,并具有执行给定的操作权限的用户。您在前端/界面中执行的任何操作都可以轻松地由黑客或任何经验丰富的Web开发人员进行更改和操作。

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


毕竟,我不确定是否可以调用这个“SQL注入”。您的应用程序的功能需要一些包含整数值的输入。现在剩下的是检查是否提供了必要的输入并且是有效的。所有的用户输入必须被视为不安全,并在被扔进查询之前进行适当的验证和转义。

另外,看看PDO哪个处理价值逃逸很好。 mysql_*扩展名和mysql_real_escape_string函数已被弃用,并且非常容易出现人为错误。

至于预防SQL注入,linked thread在问题的评论是一个很好的阅读。

+0

非常感谢这个详尽的解释! 我几乎没有发现mysql API被弃用......我明白,现在,使用mysql还不是一个安全问题,而是在将来沟渠,对吧? – Greg

+0

@Greg实际上使用'mysql_ *'已被弃用了十多年,但是是的。它不是'mysql_ *'是*邪恶*,但它是人们如何使用它。误用它非常容易。你可以使用PDO连接到一个MySQL服务器,并且通过微软PDO教程只需要一两个小时的时间就可以了解答案,并且可以更快地学习它,这样可以在将来避免很多麻烦。 '=]' –

+0

一般的建议是,如果您正在开始一个新应用程序或刚开始学习,最好从最新的扩展开始,而不是那些旧的已弃用的东西。 ':)' –