我理解保护数据库免受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
答案 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