mysql - 如何在 Laravel 查询上添加条件而不可能允许 SQL 注入(inject)攻击?

标签 mysql laravel laravel-5.3 sql-injection eloquent

我的方法是这样的:

public function getTopProduct($num, $category_id, $price)
{
    if($category_id) {
        $cache_category_key = 'top-product-category-'.$category_id;
        if(cache($cache_category_key))
            return  cache($cache_category_key);

        $category_condition = 'AND d.category_id = :category_id';
        $price_condition = '';

        $param = ['category_id'=>$category_id, 'num'=>$num];
    }
    else {
        if($price)
            $price_cache = $price['min'].$price['max'];
        else
            $price_cache = '';

        $cache_price_key = 'top-product-price-'.$price_cache;
        if(cache($cache_price_key))
            return  cache($cache_price_key);

        $category_condition = '';

        if($price) {
            $price_condition = 'AND x.price >= :price_min AND x.price <= :price_max';
            $param = ['price_min'=>$price['min'], 'price_max'=>$price['max'], 'num'=>$num];
        }
        else{
            $price_condition = '';
            $param = ['num'=>$num];
        }
    }

    $query_top_product = '
        SELECT x.id, x.store_id, x.name, x.photo, x.price, x.total_sold, y.name AS store_name, y.address
        FROM products x
        JOIN stores y ON y.id = x.store_id
        WHERE x.id = (
            SELECT a.id 
            FROM products a
            JOIN stores b ON b.id = a.store_id
            JOIN users c ON c.id = b.user_id
            JOIN products_categories d ON d.product_id = a.id
            WHERE a.status = 1 AND a.stock > 0 AND a.deleted_at IS NULL AND b.status = 1 '.$category_condition.' AND a.store_id = x.store_id AND c.updated_at >= DATE(NOW()) - INTERVAL 3 DAY
            ORDER BY a.created_at DESC, a.updated_at DESC
            LIMIT 1
        )
        '.$price_condition.'
        LIMIT :num
    ';

    //see for protection in db raw http://fideloper.com/laravel-raw-queries
    $products =  DB::select(DB::raw($query_top_product),$param);

    if($category_id) 
        Cache::forever('top-product-category-'.$category_id,$products); 
    else {
        if($price)
            $price_cache = $price['min'].$price['max'];
        else
            $price_cache = '';

        Cache::forever('top-product-price-'.$price_cache,$products); 
    }

    return $products;
}

上面的方法有效。但是当我使用 https://insight.sensiolabs.com 检查我的项目时,存在这样的错误:

If provided by the user, the value of $category_condition may allow an SQL injection attack. Avoid concatenating parameters to SQL query strings, and use parameter binding instead.

而我使用参数绑定(bind)

我仍然很困惑如何解决我的问题。因为从我的案例来看需要这样的代码。我想使用 laravel eloquent。但从我的查询来看,这似乎很难

从上面的代码中,我还使用了缓存。所以如果它的缓存已经存在,它就会从缓存中抓取

如何解决该错误?

最佳答案

Laravel 默认带有 Mysql 注入(inject)保护,你只需要使用 Eloquent 或 Query Builder,例如:

$users = User::select('*');

if ($request->has('only_active')) {
    $users->where('active', true);
}

if ($request->has('search')) {
    $users->where('name', 'like', '%'.$request->search.'%');
}

// a lot of more filters you can add...

return $users->get();

Laravel 还提供 support for joins您可以使用 Eloquent 或查询生成器进行申请

关于mysql - 如何在 Laravel 查询上添加条件而不可能允许 SQL 注入(inject)攻击?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47513821/

相关文章:

php - 使用 Laravel Collection 获取重复值

mysql - 有没有办法在数据库中存储一个指向某个大文件的指针?

php - 如何在不重新索引的情况下将项目添加到 laravel 列表集合中?

php - 将数量或其他参数传递给Laravel播种机

mysql - Laravel 4.0 按钮功能每日限制

MySQL:代表第三列将两列相乘得到列的总和

mysql - 这是什么 MySQL 查询?

python - 在 RoR 和 python 中锁定数据库表

MySQL启动错误

laravel-5.3 - Laravel迁移错误