为什么PHP PDO不保护我的查询不被注入?

时间:2011-11-23 20:28:36

标签: php sql pdo sql-injection prepared-statement

我仍然在全面学习PDO,但是当我今天晚上检查它是否适用于SQL Inject the URL参数时,我感到很惊讶,令我惊讶的是,它确实有效。所以我开始思考;发布的值应该使用PDO自动清理,这意味着我的SQL查询一定有问题,对吗?

我有一个需要GET变量的页面,以便使用该ID从我的数据库中收集相应的数据。我创建了一个函数,包括准备查询,以及执行它以简化编码过程。我现在编写的代码如下:

 $request = $_GET['movie'];
 $sql = "SELECT * FROM `movies` WHERE `url` = '$request'";
 $db = new database;
 $db->setDBC();

 $process = $db->executeQuery($sql);
 $cmd = $process->fetch(PDO::FETCH_NUM);

 $title = $cmd[1];

我得到的PDO异常是:

  

致命错误:带有消息'SQLSTATE [42000]的未捕获异常'PDOException':语法错误或访问冲突:1064 SQL语法中有错误;检查与您的MySQL服务器版本相对应的手册,以便在C:\ xampp \ htdocs \ filmvote \ include \ databaseClass.php中的第1行''21 -31282''附近使用正确的语法:33堆栈跟踪:# 0 C:\ xampp \ htdocs \ filmvote \ include \ databaseClass.php(33):PDOStatement-> execute()#1 C:\ xampp \ htdocs \ filmvote \ _ recension.php(9):databaseManagement-> executeQuery( 'SELECT * FROM` ...')在第33行的C:\ xampp \ htdocs \ filmvote \ include \ databaseClass.php中抛出#2 {main}

' or 1-1添加到网址时会出现此类错误。我该怎么办?真的很感激帮助。

2 个答案:

答案 0 :(得分:13)

  

应使用PDO

自动清理过帐的值

不。只有你使用这样的实际准备语句:

$stmt = $dbh->prepare("SELECT * FROM `movies` WHERE `url` = ?");
if ($stmt->execute(array($_GET['movie'])))  // <-- This sanitizes the value
  { 
    // do stuff
  }

将自动清理您插入的值,并保护您的查询免受SQL注入。

否则,您的SQL查询将像任何旧的mysql_query()一样执行,并且容易受到攻击。 PDO无法进行查询,然后自动清理易受攻击的部分。那是不可能的。

答案 1 :(得分:3)

尝试准备好的陈述:

$query = $db->prepare("SELECT * FROM `movies` WHERE url = ?");
$query->execute(array($request));
$result = $query->fetch(PDO::FETCH_ASSOC);