嘿那里,我正在对涉及一些用户输入的MySQL数据库进行一些查询。我想知道如何防止注入攻击,例如,如果有人打字
"; a-MySQL query here;"
它将被执行,这将允许人们访问危害我的系统。我想知道如何防止这样的事情,可能会创建一个过滤掉查询查找错误语句的函数?或许不允许;字符?
答案 0 :(得分:3)
唯一的方法是正确转义用户提交的数据。其他人已经指出了一些方法。
还有另一种方式:准备好的陈述和占位符。每个现代 PHP数据库界面都支持准备语句,包括mysqli和PDO。
让我们使用PDO作为演示。假设我们想要更新用户提交的表foo
中的一些数据。
$sql = 'UPDATE foo SET bar = ? WHERE user_id = ?';
$sh = $db->prepare($sql);
$sh->execute(array( $_POST['bar'], $_SESSION['user_id'] ));
传递给execute
的数组中的变量替换查询中的问号占位符。发生这种情况时,它们会被自动转义并引用。您无需手动转义它们就可以安全地放入数据库!
另一方面,您仍然需要针对意外内容过滤它们,例如HTML,Javascript,您期望数字的字母等。使数据安全插入数据库only half of the battle。
答案 1 :(得分:2)
比调用mysql_escape_string
变体更好的方法是在PDO中使用绑定查询,这样就不可能忘记或遗漏一个案例,因为当情况需要时,PDO会为你进行转义。
了解更多信息: http://www.electrictoolbox.com/php-pdo-bound-placeholders/
答案 2 :(得分:1)
他们最好的解决方案是通过此函数PHP.net: MySQL Real Escape String运行来自wild(用户)的每一条输入。这将清除大多数 - 如果不是全部 - 今天看到的注入问题。您只需要执行以下操作:
$var = mysql_real_escape_string($_GET['var']);
$query = "INSERT INTO foo (var) VALUES (\"$var\");
在你知道应该是类型的变量上强制进行类型转换总是很好的做法。例如,数字标识符:
$id = (INT)$_GET['id'];
或
$id = ( is_numeric($_GET['id']) ? (INT)$_GET['id'] : -1; // replace -1 with FALSE, or NULL, etc
这将强制该变量为整数,因此您不会以$id
为“foo”或其他非数字变量。