我一直在做一些测试来保护我的网站免受SQL注入。我看到有几种方法可以做到这一点,转义我的用户输入,添加斜杠,或者更好地使用参数化的sql语句。
我有这个测试代码..
$q=$_GET["q"];
$game = mysql_query("SELECT * FROM `Games` WHERE `id` = '$q'");
$game = mysql_fetch_array($game);
echo "<h4>ID: ".$game[0]."<br /></h4>name: " . $game[1];
我尝试了几个SQLi请求,无法让我的测试页面出错,或显示任何额外的数据。
但是当我将我的sql语句代码更改为此时(删除$ q周围的单引号)..
$game = mysql_query("SELECT * FROM `Games` WHERE `id` = $q");
我可以执行简单的SQLi并获得一些结果。
那么只需将我的用户输入用单引号包装好吗?或者让我看看更复杂的SQLi技术?
答案 0 :(得分:3)
您提到SQL注入和参数化语句,但似乎没有跨越PDO? - 使用PDO http://www.php.net/manual/en/pdo.prepare.php
答案 1 :(得分:1)
您应该使用mysql_real_escape_string()
功能
在这种情况下,您必须使用单引号
$game = mysql_query("SELECT * FROM `Games` WHERE `id` = '$q'");
假设用户输入为1'
而不是escape_string输出为1\'
如果你没有使用引号而不是查询
SELECT * FROM `Games` WHERE `id` = 1'
//that is wrong or a injection
但在单引号案例中
SELECT * FROM `Games` WHERE `id` = '1\''
这很好,可以删除sql-injection
答案 2 :(得分:1)
尝试此输入:
abc' OR id <> '
它将导致以下声明:
"SELECT * FROM `Games` WHERE `id` = 'abc' OR id <> ''"
这将返回所有游戏,而不仅仅是一个。如果您的页面允许显示整个结果,那么我们肯定会看到太多......
出路是将PDO与预处理语句一起使用,在将用户输入插入SQL语句之前至少是mysqli_real_escape_string()
函数。
SQL-Injection可以做更多事情,在最坏的情况下,您甚至可以控制服务器。看看这个SQL Injection Cheat Sheet