如果用户输入未经修改就插入到SQL查询中,则应用程序很容易受到SQL注入的攻击,如下例所示:

$unsafe_variable = $_POST['user_input']; 

mysql_query("INSERT INTO `table` (`column`) VALUES ('$unsafe_variable')");

这是因为用户可以输入类似值的内容);DROP TABLE表;--,并且查询变为:

INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--')

可以采取什么措施防止这种情况发生?


当前回答

我建议使用PDO(PHP数据对象)运行参数化SQL查询。

这不仅可以防止SQL注入,还可以加快查询速度。

而且,通过使用PDO而不是mysql_、mysqli_和pgsql_函数,可以使应用程序从数据库中抽象出一点,这是很少需要切换数据库提供程序的情况。

其他回答

不推荐的警告:这个答案的示例代码(与问题的示例代码一样)使用了PHP的MySQL扩展,该扩展在PHP 5.5.0中被弃用,在PHP 7.0.0中被完全删除。安全警告:此答案不符合安全最佳实践。转义不足以防止SQL注入,请改用准备好的语句。使用以下概述的策略,风险自负。(此外,在PHP7中删除了mysql_real_ascape_string()。)

参数化查询AND输入验证是一种方法。尽管使用了mysql_real_ascape_string(),但在许多情况下可能会发生SQL注入。

这些示例易受SQL注入攻击:

$offset = isset($_GET['o']) ? $_GET['o'] : 0;
$offset = mysql_real_escape_string($offset);
RunQuery("SELECT userid, username FROM sql_injection_test LIMIT $offset, 10");

or

$order = isset($_GET['o']) ? $_GET['o'] : 'userid';
$order = mysql_real_escape_string($order);
RunQuery("SELECT userid, username FROM sql_injection_test ORDER BY `$order`");

在这两种情况下,都不能使用“”来保护封装。

来源:意外的SQL注入(当转义不够时)

我建议使用PDO(PHP数据对象)运行参数化SQL查询。

这不仅可以防止SQL注入,还可以加快查询速度。

而且,通过使用PDO而不是mysql_、mysqli_和pgsql_函数,可以使应用程序从数据库中抽象出一点,这是很少需要切换数据库提供程序的情况。

对于那些不确定如何使用PDO(来自mysql_函数)的人,我制作了一个非常非常简单的PDO包装器,它是一个单独的文件。它的存在是为了显示应用程序需要做的所有常见事情是多么容易。适用于PostgreSQL、MySQL和SQLite。

基本上,在阅读手册的同时阅读它,了解如何在实际生活中使用PDO函数,从而使以所需格式存储和检索值变得简单。

我想要一列$count=数据库::列('SELECT count(*)FROM `user`');我想要一个数组(key=>value)结果(即,用于生成一个选择框)$pairs=数据库::pairs('SELECT `id',`username`FROM`user`');我想要单行结果$user=DB::行('SELECT*FROM`user`WHERE `id`=?',数组($user_id));我想要一系列结果$banned_users=DB::fetch('SELECT*FROM `user`WHERE `banned`=?',数组('RUE'));

有许多方法可以防止SQL注入和其他SQL攻击。你可以很容易地在互联网上找到它(谷歌搜索)。当然,PDO是一个很好的解决方案。但我想建议您一些防止SQL注入的良好链接。

什么是SQL注入以及如何防止

SQL注入PHP手册

Microsoft对PHP中SQL注入和预防的解释

还有一些类似于防止MySQL和PHP的SQL注入。

现在,为什么需要防止SQL注入查询?

我想告诉您:为什么我们要通过下面的一个简短示例来防止SQL注入:

查询登录身份验证匹配:

$query="select * from users where email='".$_POST['email']."' and password='".$_POST['password']."' ";

现在,如果有人(黑客)

$_POST['email']= admin@emali.com' OR '1=1

和密码。。。。

查询将被解析到系统中,直到:

$query="select * from users where email='admin@emali.com' OR '1=1';

另一部分将被丢弃。那么,会发生什么?未经授权的用户(黑客)可以以管理员身份登录,而无需密码。现在,他/她可以做管理员/电子邮件管理员可以做的任何事情。看,如果不阻止SQL注入,这是非常危险的。

一个简单的方法是使用像CodeIgniter或Laravel这样的PHP框架,它具有内置的过滤和活动记录等功能,因此您不必担心这些细微差别。