MySQL注入问题

时间:2011-06-16 19:29:37

标签: php mysql sql-injection

我最近用PHP编写了我的网站编码,在我在查询中使用它之前,我为自己的良好做法感到非常自豪。这一切都很顺利,直到我的朋友说我需要消毒我的输入。当我试图向他解释它已被消毒时,他告诉我他已经在我的数据库中的“用户”表中找到了所有内容。我不知道怎么样,所以我想我会发布我做错了什么让我的消毒不起作用。这是他正在利用的PHP代码:

start_mysql(); // Starts the databases stuff, etc.

$id = mysql_real_escape_string($_GET['id']);
$game = mysql_query("SELECT * FROM `games` WHERE `id` = $id LIMIT 0, 1");

他所做的只是更改id参数,使他能够在我的数据库上使用SQL注入。我以为mysql_real_escape_string逃脱了所有这样的角色,但显然我错了。我用一个普通的字符串做了一些测试,看看会发生什么,这就是它所说的

网址:/game.php?id ='或'=''

echo($_GET['id']); // This echo'd: \' OR \'\' = \'
echo(mysql_real_escape_string($_GET['id'])); // This echo'd: \\\' OR \\\'\\\' = \\\'

所以,我的简单问题是,我做错了什么?

8 个答案:

答案 0 :(得分:6)

您需要将转义字符串放在单引号中:

WHERE `id` = '$id' 

答案 1 :(得分:4)

由于id是一个整数参数,并且您没有在SQL中用单引号括起它,因此$id的值会直接发送到您的查询中。如果您期望一个整数id,那么您应该验证$_GET['id']的值是否为有效整数。

$id = intval($_GET['id']);

答案 2 :(得分:3)

马特,

mysql_real_escape_string()只会过滤某些字符,如果你真的想要防止注入攻击,请查看另一篇建议你使用Prepared语句的Stack Overflow文章:

Prepared Statements

PHP Manual entry on Prepared statements

编辑:还要查看Slaks和Michael关于用单引号包装变量的帖子。

祝你好运!

ħ

答案 3 :(得分:1)

您需要使用parameter binding api。问题在于这段代码:

WHERE `id` = $id

您正在将用户输入直接插入到SQL语句中。这是SQL注入攻击的开放式谷仓门。

答案 4 :(得分:1)

投射ID。如果它是一个字符串,它将转换为0。 $ id =(int)$ _ GET ['id'];

此外,MySQL支持在查询中引用字符串和数字。

$game = mysql_query("SELECT * FROM `games` WHERE `id` = '$id' LIMIT 0, 1");

答案 5 :(得分:0)

您没有使用参数化查询。

MDB2允许这样做,尽管该库可能会失宠。

答案 6 :(得分:0)

你的配置很可能有magic_quote_gpc,这是PHP中的一个古老尝试,可以让脚本神奇地保证安全。它被证明有多个缺陷,并且已被弃用,并且计划在我最后一次听到它时被完全删除。

如果您有权访问php.ini配置,则应禁用它。否则,您可以修改脚本以将其考虑在内并清理输入。

所有这些都记录在这里:http://www.php.net/manual/en/security.magicquotes.disabling.php

否则,mysqli_real_escape_string()没有任何问题。

答案 7 :(得分:0)

您无法使用mysql_real_escape_string()阻止SQL注入。它用于转义特殊字符,如单引号('),双引号(")等。

为防止SQL注入,您必须在PHP中使用PDO语句和过滤器函数来清理用户数据。