首页 > 解决方案 > 即使使用准备好的语句,PDO 查询也会因某些输入而崩溃

问题描述

我的网站上有一个与 PHP PDO MySQL 连接的搜索功能。

为了计算分页的结果,我正在执行如下查询:

SELECT count(*) FROM articles WHERE (`title` LIKE ? OR MATCH(`text`) AGAINST(? IN BOOLEAN MODE)) AND `active` = 1

但是,似乎有人正在尝试 SQL 注入(我假设),输入如下搜索词:

1"'`--

这似乎最终完全打破了我的查询。它使用的是准备好的语句,正如您在 ? 中看到的那样,所以我不确定它为什么会导致此错误发生:

SQL 错误 SQLSTATE[42000]:语法错误或访问冲突:1064 语法错误,意外的“-”

什么都不做,通常的 PDO 东西像:

$this->stmt = $this->prepare($sql);
$this->stmt->execute($data_array);

数据通过按空格分隔来排序,以环绕通配符,如下所示:

$search_array = array(explode(" ", $search_text));
$search_through = '';
$search_sql_text = '';
foreach ($search_array[0] as $item)
{
    $item = str_replace("%","\%", $item);
    $search_through .= '%'.$item.'%';
}

完整的查询基本上是这样结束的:

SELECT count(*) FROM articles WHERE (`title` LIKE %1"'`--% OR MATCH(`text`) AGAINST("+1"'`--" IN BOOLEAN MODE)) AND `active` = 1

防止此类事情发生的最佳方法是什么?

标签: phpmysqlpdo

解决方案


事实证明,这是 InnoDB 的一个问题,任何以运算符开头的输入即使使用准备好的语句,它也会将字符串输入作为运算符。最简单的选择是去掉运算符,因为文本搜索将正常工作。


推荐阅读