保护PHP免受MySQL注入

时间:2013-03-05 00:54:29

标签: php mysql pdo sql-injection

我是一个完整的PHP菜鸟,当我读到MySQL注入并保护我的脚本时,我想我会发布到目前为止的内容。

以下是我目前的(工作但不好的做法)代码。有人可以提出我的弱点,以及我可以做些什么来修复?

<?php
require_once 'login.php'; //database information

$db_server = mysql_connect($db_hostname, $db_username, $db_password)
    or die("Unable to connect to MySQL: " . mysql_error());

mysql_select_db($db_database)
  or die("Unable to select database: " . mysql_error());

$email = $_POST['email'];

$sql="INSERT INTO users (email)
VALUES ('$email')";

$result = mysql_query($sql);

if($result){
header('Location: ../thankyou.php');
}
else {
echo "ERROR";
}

mysql_close();
?> 

1 个答案:

答案 0 :(得分:0)

正如你用自己的话说一个菜鸟,没有时间像现在一样养成一些好习惯:)

$email = $_POST['email'];
$sql="INSERT INTO users (email) VALUES ('$email')";

SQL injection漏洞的教科书示例,此代码迟早会bite you。原因是您信任您收到的变量,并将其交给SQL引擎。试想一下如果有人进入

会发生什么

'); drop table users; --

作为他们的电子邮件地址......

不是设计各种复杂的方案来清理输入,而是有一种铁定的技术可以让你的代码免受注入攻击:准备好的语句。由于您不应该开始开发php提供的已弃用的mysql_调用,您应该切换到PDO或mysqli_。我建议支持预备语句的PDO。更多关于准备好的陈述here。使用PDO和准备好的语句,您的样本将如下所示:

$stmt = $dbh->prepare("INSERT INTO users (email) VALUES (:email)");
$stmt->bindParam(':email', $email);
$stmt->execute();

您将拥有可以与MySQL以外的其他数据库系统一起使用的未来验证代码,并且不受注入攻击的影响。