这将如何影响阻止SQL注入的机会?

时间:2011-11-27 21:14:05

标签: php security code-injection

我之前已经发布了这个,但从来没有这方面,所以请看看:

我被告知进行sql注射的一种方法是使用1 = 1,其中有人可以看到所有不属于他们的条目。

但是,让我说我构建我的查询,以便它也选择当前用户的user_id,这样可行:

  $userid = Current users stored id in database;
  $postid = mysql_real_escape_string($_GET['id']);

现在假设我输入:domain.com/page.php?id='' OR '1'='1'

Select article_name from table where user_id=$userid and post_id=$postid

由于我添加了User_id屏障,查询是否仍会返回所有内容或不会返回?

4 个答案:

答案 0 :(得分:4)

如果您使用PDO,则无需担心转义数据(在这种情况下):

$stmt = $pdo->prepare('SELECT article_name FROM table WHERE user_id = :userid AND post_id = :postid');
$stmt->execute(array(
    ':userid' => $userid,
    ':postid' => intval($_GET['id'])  //Just to be safe
));

// You could also do this instead (thanks @Digital Precision)
//$stmt->bindValue(':postid', $_GET['id'], PDO::PARAM_INT);
//$stmt->execute(array(':userid' => $userid));

while($row = $stmt->fetch()) {
    //Work with data
}

有关PDO的更多信息,请参阅PHP docs

使用mysql_real_escape_string()的问题在于它的名称表明它只会转义字符串。它会转义可用于终止字符串的字符,以便攻击者无法关闭字符串并输入恶意SQL。 如果你很顽固并拒绝使用PDO,你可以在任何未经过整理的整数上使用intval()之类的函数来确保它们只包含数字。

$post_id = intval($_GET['id']); //Now $post_id can only be a number

答案 1 :(得分:3)

mysql_real_escape_string()仅用于清理字符串。它不会保护SQL注入没有用引号括起来的整数,所以你的观察是正确的:尽管mysql_real_escape_string(),上面所示的内容确实不安全。

您需要将值包装在引号中:

Select article_name from table where user_id='$userid' and post_id='$postid'

或在运行查询之前确保$userid$postid是整数。

答案 2 :(得分:1)

不确定你是什么意思"我被告知进行sql注射的一种方法是使用1 = 1,其中有人可以看到所有不属于他们的条目"。

1 = 1始终评估为true。当应用程序生成的查询只有条件where子句没有root where子句时,我才见过这种情况。不确定它与保护您进行sql注射有什么关系。

答案 3 :(得分:1)

您的查询如下:

Select article_name from table where user_id=$userid and post_id=\'\' OR \'1\'=\'1\'

正如我在输入时提到的那样,最好引用你的值。所以你将拥有:

Select article_name from table where user_id=$userid and post_id='\'\' OR \'1\'=\'1\''

如果没有具有此类ID的帖子,则不返回任何内容。

因此,您的查询不会返回当前用户的每个帖子。但请记住引用你的价值观。