在PHP中,PDO如何防止SQL注入?准备好的陈述如何运作?

时间:2010-10-28 12:21:38

标签: php security pdo

我理解保护数据库免受SQL注入的正确方法是使用预准备语句。我想了解如何准备好的语句保护我的数据库。

首先,准备好的陈述与“参数化查询”相同吗?

作为一个例子,我在我的代码下面粘贴了在用户表中插入新用户。这样安全吗? PDO如何确保其安全?还有什么需要做的,以保护数据库免受注入?

在'Class_DB.php'中:

class DB {
 private $dbHost;
 private $dbName;
 private $dbUser;
 private $dbPassword;   
 function __construct($dbHost, $dbName, $dbUser, $dbPassword) {
  $this->dbHost=$dbHost;
  $this->dbName=$dbName;
  $this->dbUser=$dbUser;
  $this->dbPassword=$dbPassword;
 }
 function createConnexion() {
  return new PDO("mysql:host=$this->dbHost;dbName=$this->dbName", $this->dbUser, $this->dbPassword);
 }
}

在'DAO_User.php'中:

require_once('Class_DB.php');

class DAO_User {
 private $dbInstance;
 function __construct($dbInstance){
  $this->dbInstance=$dbInstance;
 }
 function createUser($user){
  $dbConnection=$this->dbInstance->createConnexion();
  $query=$dbConnection->prepare("INSERT INTO users (userName, hashedPassword, userEmail) VALUES (?,?,?)");
  $query->bindValue(1, $user->userName);
  $query->bindValue(2, $user->hashedPassword);
  $query->bindValue(3, $user->userEmail);
  $query->execute();
 }
}

谢谢,

JDelage

4 个答案:

答案 0 :(得分:22)

好的,我在这个相关问题中找到了我的问题的答案:Are PDO prepared statements sufficient to prevent SQL injection?

感谢Haim指出这个Q给我。

在非技术术语中,以下是预备语句如何防止注入:

当查询发送到数据库时,通常将其作为字符串发送。 db引擎将尝试解析字符串并将数据与指令分开,依赖于引号和语法。因此,如果您发送“SELECT * WHERE”用户提交的数据'EQUALS'表行名称',引擎将能够解析该指令。

如果您允许用户输入将在“用户提交的数据”中发送的内容,那么他​​们可以在此类型中包含“...”或“如果1 = 1 ERASE DATABASE”。数据库引擎将无法解析这将把上面作为指令而不是无意义的字符串。

PDO的工作方式是单独发送指令(prepare(“INSERT INTO ...))和数据。数据单独发送,清楚地理解为仅数据和数据.db引擎不甚至尝试分析数据字符串的内容以查看它是否包含指令,并且不考虑任何可能具有破坏性的代码snipet。

答案 1 :(得分:3)

这是我对此事的看法有限......

在DB服务器上编译预准备语句,并使用占位符进行变量输入。

绑定参数时,您告诉DB在执行查询时要使用哪些值。然后它会将值传递给已编译的语句。

绑定参数和普通旧字符串注入之间的区别在于,对于前者,该值不是内插而是分配。在执行期间,DBMS命中占位符并请求使用该值。通过这种方式,引用字符或其他恶意软件无法潜入实际声明中。

答案 2 :(得分:2)

如果不使用预准备语句,则无法在查询中使用占位符(?)。

相反,您需要将要直接插入的值包含在SQL语句中。这会导致每个插入的SQL语句不同(对性能不利),如果你不小心你在语句中放入了什么字符串,你最终可能会得到一个声明,然后做你想做的事情(例如SQL注入可能会发生。)

这种情况有点类似于使用Javascript函数执行一些带有可变输入参数的固定代码,而不是将输入参数粘贴到Javascript源中,然后评估它。

答案 3 :(得分:-1)

您的来源免受sqli攻击。

这是示例,当您从数据库中选择一个用户时,该安全性并不安全。

// example: localhost/user.php?username=admin

$getdata = $_GET['username'];

$dbConnection=$this->dbInstance->createConnexion();
$query=$dbConnection->prepare("SELECT * FROM users WHERE username=".$getdata.");

// PHP simple