【问题标题】:Search query dynamically created is unsafe动态创建的搜索查询不安全
【发布时间】:2015-02-24 03:24:54
【问题描述】:
// Check and set search
if($_POST['searchQuery'] !== "null"){
    $search = $_POST['searchQuery'];

    $search = explode(' ', $search);


    //long words are more than 4
$longwords = '';
$shortwords = '';


$searchCount = count($search);

foreach ($search as $word) {
    $word = trimplural($word);

    if ($searchCount > 1){

       if (strlen($word) > 3) {
           if (!in_array($word,array('sale','brand','lots'))){
                  $longwords.=' +'.$word;
                    } //check for words
        }else{ //else 3 letters
                    if (strlen($word) == 3) {
                        if (!in_array($word,array('and','the','him','her','for','new','you'))){
                               $shortwords.= " OR (fname LIKE '%$word%' OR lname LIKE '%$word%') ";
                            } //search for words
                     }//strlen == 3
        }

    }else{//else searchcount == 1
                            if (!in_array($word,array('and','the','him','her','for','new','you'))){
                               $shortwords.= " OR (fname LIKE '%$word%' OR lname LIKE '%$word%') ";
                      } 
     }


}



}else{
    $search = null;
}

Sql:

$sql = "SELECT * FROM people WHERE MATCH (lname,fname) AGAINST (:longwords IN BOOLEAN MODE) $shortwords LIMIT " . $postnumbers . " OFFSET ".$offset;
    $q1  = $conn->prepare($sql) or die("failed!");
    $q1->bindParam(':uniid', $uniid, PDO::PARAM_STR);
    $q1->bindParam(':longwords', $longwords, PDO::PARAM_STR);
    $q1->execute();

我有一个使用上面显示的代码生成的搜索查询,我想结合使用 mysql 全文搜索和 LIKE 查询。为了做到这一点,我将 SQL 查询的一部分添加为变量 $shortwords 以使 LIKE 部分工作,但是,我知道这不是最佳选择,因为 sql 注入。

在实施到 SQL 之前,如何使这个查询“更安全”或清理输出?

【问题讨论】:

    标签: php sql pdo sql-injection


    【解决方案1】:

    创建子句时,在 $word 变量上使用 PDO::quote,然后再将其添加到字符串中,它会清理并转义该值。这样您就不需要使用短词绑定Param,但您可以获得相同的功能。

    这样的事情应该可以工作:

    if (!in_array($word,array('and','the','him','her','for','new','you'))){
        $safe = $conn->quote('%'.$word.'%');
        $shortwords.= " OR (fname LIKE $safe OR lname LIKE $safe) ";
    } //search for words
    

    虽然 offset 和 postnumbers 不是很容易被注入,但绑定它们还是不错的,这将使查询更具可读性,但这只是我的意见。

    另外,您可能需要考虑在 foreach 之外定义单词列表数组。目前,解释器在循环的每次迭代中重建数组。同样,不是什么大不了的事,但值得一提。

    【讨论】:

    • 感谢您的回复!不幸的是,短词列表从最终结果中排除了这些词,这会稍微改变一下吗?
    • 再次感谢!你能提供一个我将如何使用 PDO::quote 的例子吗?大声喊我也将绑定其他参数!
    猜你喜欢
    • 2010-09-21
    • 2014-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-28
    相关资源
    最近更新 更多