Php 使用PDOAPI保护SQL注入?
可能重复:Php 使用PDOAPI保护SQL注入?,php,pdo,sql-injection,Php,Pdo,Sql Injection,可能重复: 我一直在开发一个新的API,我主要关心的是它的安全性 我是PDO用法的初学者,但知道主要结构。但是我不知道如何保护查询不受SQLInjection的影响 我的代码如下: <?php $Start = new Db(); class Db { private $dbh = null; public function __construct() { $this->dbh =
我一直在开发一个新的API,我主要关心的是它的安全性 我是PDO用法的初学者,但知道主要结构。但是我不知道如何保护查询不受SQLInjection的影响 我的代码如下:
<?php
$Start = new Db();
class Db
{
private $dbh = null;
public function __construct()
{
$this->dbh = new PDO('mysql:host=localhost;dbname=pdo', 'root', 'xxxxx');
}
public function PDOFetch($Var)
{
$sth = $this->dbh->prepare("$Var");
$sth->execute();
$result = $sth->fetchAll();
return $result;
}
public function PDONumb ($Var)
{
$sth = $this->dbh->prepare("$Var");
$sth->execute();
$count = $sth->rowCount();
return $count;
}
public function PDODel ($Var)
{
$Delete = $this->dbh->exec("$Var");
return $Delete;
}
public function PDOQuery ($Var)
{
$Query = $this->dbh->query("$Var");
return $Query;
}
}
?>
但后来,当我用这个来掩盖我的足迹时。我想更高级地使用它,因此它将传递用户定义的变量(因此SQL注入问题)
但目前,正在传递的查询是由管理员定义的。如果没有看到您正在传递的SQL,我们无法判断。如果您使用不受信任的数据创建不安全的SQL语句,那么它们是否在PDO中执行并不重要。您仍然可以接受SQL注入 例如,如果您从web获得
$userid
,并构建:
$sql = "SELECT * FROM users WHERE userid=$userid";
该SQL语句为SQL注入打开,因为如果$userid
的值为0;删除表用户代码>,则您将创建的SQL将
SELECT * FROM users WHERE userid=0; DROP TABLE users;
不管你是否通过PDO执行,你仍然在执行一个坏人发给你的代码
要正确使用PDO,您需要
与您的问题无关,但新手经常遇到的一个重要问题是:没有必要在单个变量周围加双引号。你的代码
$Delete = $this->dbh->exec("$Var");
最好写成
$Delete = $this->dbh->exec($Var);
防止sql注入确实是人们使用PDO的原因之一。它确实提供了保护。你为什么认为你必须自己做那件事?如果您没有错误地将其他sql语句标记存储在某个位置,以便在执行时将它们组合在一起,PDO就足够了。@arkascha我不熟悉使用api,我习惯使用mysql api,它需要手动输入,以便使用预定义函数进行保护。那么,你说PDO保护自己不被注入?PDO不保护自己,如果你使用“准备好的语句”,它会保护你的查询。首先准备一个包含占位符的语句。在执行期间将值绑定到这些占位符。这就是所谓的“绑定”。检查安迪·莱斯特下面的答案。请看一些关于如何使用占位符的例子。此外,您不必使用PDO来使用占位符变量。PDO需要将两件事彼此分开:准备的语句和运行时执行的参数。不要把它们混在一起。如果您通过创建一个包含就绪可执行sql语句的字符串来混合它,那么PDO将无法保护您。您可以包装PDO,您总是需要采取两个步骤:首先准备一个语句,让PDO将参数绑定到它。不要自己用字符串函数绑定它们,这是绝对正确的。我甚至从未想过有人会以这种方式使用PDO。说得对!看起来OP的代码就是这么做的。在我看来,它只是从调用方获取任意SQL代码并执行它。我基本上是为了最小化执行PDO查询的整个过程,将其减少到仅1行并将其传递到定义的函数中。请参阅我对post@DarylGill:您正在尝试抽象抽象层。不要。使用预先准备好的语句,建议的PDO方法已经足够抽象了。@AndyLester您是对的,那个包装器确实阻止了PDO的保护。下次我应该仔细看看。谢谢你睁大眼睛。
$Delete = $this->dbh->exec($Var);