繁体   English   中英

针对将查询生成器与DB :: raw()组合在一起的查询,防止SQL注入

[英]Prevent SQL injection for queries that combine the query builder with DB::raw()

在Laravel 4中,我想保护一些复杂的数据库查询不受SQL注入的影响。 这些查询使用查询构建器和DB :: raw()的组合。 这是一个简化的例子:

$field = 'email';
$user = DB::table('users')->select(DB::raw("$field as foo"))->whereId(1)->get();

我读过Chris Fidao的教程 ,可以将一系列绑定传递给select()方法,因此可以通过使用准备语句来正确地防止SQL注入。 例如:

$results = DB::select(DB::raw("SELECT :field FROM users WHERE id=1"), 
               ['field' => $field]
           ));

这样可行,但该示例将整个查询放入原始语句中。 它不会将查询生成器与DB :: raw()组合在一起。 当我尝试使用第一个例子时类似的东西:

$field = 'email';
$user = DB::table('users')->select(DB::raw("$field as foo"), ['field' => $field])
             ->whereId(1)->get();

...然后我得到一个错误: strtolower()期望参数1是字符串,给定数组

对于将查询构建器与DB :: raw()组合在一起的查询,阻止SQL注入的正确方法是什么?

我发现查询构建器有一个名为setBindings()的方法,在这个实例中很有用:

$field = 'email';
$id = 1;
$user = DB::table('users')->select(DB::raw(":field as foo"))
        ->addSelect('email')
        ->whereId(DB::raw(":id"))
        ->setBindings(['field' => $field, 'id' => $id])
        ->get();

Eloquent在引擎盖下使用PDO来消毒物品。 它不会清理添加到SELECT语句的项目。

但是, mysqli_real_escape_string方法对于清理 SQL字符串仍然很有用。

还要考虑(或者代替)保留users表中的有效字段名称数组,并检查它以确保没有使用无效值。

$allowedFields = ['username', 'created_at'];

if( ! in_array($field, $allowedFields) )
{
    throw new \Exception('Given field not allowed or invalid');
}

$user = DB::table('users')
            ->select(DB::raw("$field as foo"))
            ->whereId(1)->get();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM