Mysql动态查询[sql注入]

Mysql dynamic query [sql injection]

我通常使用准备好的语句,但在特定页面上我使用的是动态查询,我找不到可靠的方法来防止 SQL 注入。

if(isset($_GET['sub_cat'])){

    if($_GET['sub_cat'] != '')
        $conditions[] = 'ad_sub_cat='.$_GET['sub_cat'].'';
}

if(isset($_GET['ad_brand'])){

    if($_GET['ad_brand'] != '')
        $conditions[] = "`ad_brand` LIKE CONCAT('%','".$_GET['ad_brand']."','%') ";
}

if(isset($_GET['min_range'])){

    if($_GET['min_range'] != '')
        $conditions[] = 'ad_price >='.$_GET['min_range'].'';
}

if(isset($_GET['max_range'])){

    if($_GET['max_range'] != '')
        $conditions[] = 'ad_price <='.$_GET['max_range'].'';
}

if(isset($_GET['for_r_s'])){
    
    if($_GET['for_r_s'] != '')
        $conditions[] = 'for_r_s ='.$_GET['for_r_s'].'';
}

$query = "SELECT posts.ID, posts.ad_title, posts.ad_price, posts.ad_location, posts.ad_sub_cat FROM `posts` WHERE ". implode(' AND ', $conditions) .""; 

您可以像对待任何其他查询一样防止 SQL 注入:通过将 查询 与应始终基于硬编码值的查询分开数据。唯一的区别是您需要有条件地建立查询和数据参数列表。

所以代替:

if(isset($_GET['sub_cat'])){

    if($_GET['sub_cat'] != '')
        $conditions[] = 'ad_sub_cat='.$_GET['sub_cat'].'';
}

你应该写:

if(isset($_GET['sub_cat'])){

    if($_GET['sub_cat'] != '') {
        $sql_conditions[] = 'ad_sub_cat=:sub_cat';
        $parameters['sub_cat'] = $_GET['sub_cat'];
    }
}

或者如果使用位置参数而不是命名参数:

if(isset($_GET['sub_cat'])){

    if($_GET['sub_cat'] != '') {
        $sql_conditions[] = 'ad_sub_cat=?';
        $parameters[] = $_GET['sub_cat'];
    }
}

你所有的条件依此类推。

然后在最后,您从 $sql_conditions 构建您的 SQL - 其中根本没有用户输入,因此不会被注入 - 并将 $parameters 传递给PDO/mysqli 执行查询。

在将参数添加到查询字符串之前使用 mysqli_real_escape_string。 例如:

if(isset($_GET['sub_cat']) && $_GET['sub_cat'] != ''){

    $sub_cat = mysqli_real_escape_string($connection, $_GET['sub_cat']);

    $conditions[] = 'ad_sub_cat='.$sub_cat.'';
}