如果插入用户输入而不修改SQL查询,则应用程序容易受到SQL注入的攻击,如下例所示:
$unsafe_variable = $_POST['user_input'];
mysql_query("INSERT INTO `table` (`column`) VALUES ('$unsafe_variable')");
Run Code Online (Sandbox Code Playgroud)
这是因为用户可以输入类似的内容value'); DROP TABLE table;--,查询变为:
INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--')
Run Code Online (Sandbox Code Playgroud)
可以采取哪些措施来防止这种情况发生?
不久前开始使用PDO准备好的语句,据我所知,它可以为您完成所有的转义/安全性.
例如,假设$ _POST ['title']是一个表单字段.
$title = $_POST['title'];
$query = "insert into blog(userID, title) values (?, ?)"
$st = $sql->prepare($query);
$st->bindParam(1, $_SESSION['user']['userID'], PDO::PARAM_INT);
$st->bindParam(2, $title);
$st->execute();
Run Code Online (Sandbox Code Playgroud)
这真的很安全吗?我还要做别的吗?还有什么需要考虑的?
谢谢.
我正在重新设计一个使用最小数据库的PHP驱动的网站.原始版本使用"伪准备语句"(PHP函数进行引用和参数替换)来防止注入攻击并将数据库逻辑与页面逻辑分开.
用一个使用PDO和真实预处理语句的对象替换这些ad-hoc函数似乎很自然,但在阅读它们之后,我不太确定.PDO似乎仍然是一个好主意,但准备好的声明的主要卖点之一是能够重用它们......我永远不会.这是我的设置:
SELECT foo,bar FROM baz WHERE quux = ? ORDER BY bar LIMIT 1.该批次中最复杂的陈述只是三个这样的选择与UNION ALLs 连接在一起.鉴于使用准备好的语句至少会使我正在进行的数据库往返次数增加一倍,我最好避免使用它们吗?我是否可以使用PDO::MYSQL_ATTR_DIRECT_QUERY以避免多个数据库跳闸的开销,同时保留参数化和注入防御的好处?或者,与执行我不应该担心的非准备查询相比,准备好的语句API使用的二进制调用是否运行良好?
编辑:
伙计们,感谢所有好的建议.这是我希望我可以将多个答案标记为"已接受"的地方 - 许多不同的观点.不过,最终,我必须给rick他应得的......如果没有他的答案,我会幸福地离开并完成错误的事情,即使遵循了所有人的建议.:-)
仿真准备好的陈述吧!
我有一个页面来激活用户点击我发送的电子邮件中的激活链接,该电子邮件包含一个使用GET方法发布电子邮件地址的网址,我的代码如下,但我要求的是这是一个安全的方法或者是有什么方法可以改进吗?谢谢
$username = $_GET['email'];
mysql_query("UPDATE users SET active = 'yes'
WHERE email = '$username'") or die('oops!');
echo "<meta http-equiv=\"refresh\" content=\"0;URL=/index.php?msg=active\">";
Run Code Online (Sandbox Code Playgroud)