使用Laravel防止批量准备的原始查询的SQL注入

时间:2016-01-06 13:13:40

标签: php mysql laravel pdo

这是我的疑问:

<cfquery name="GetJoinedData" datasource="Master">
  SELECT t1.keyval AS foo1,
         t1.*,
         t2.keyval AS foo2,
         t2.*
  FROM   table1 t1
         FULL OUTER JOIN -- or LEFT or RIGHT OUTER JOIN
         table2 t2
         ON ( t1.keyval = t2.keyval )
</cfquery>

不使用PHP查询:

$last = count($list)-1;

$sql = 'INSERT INTO table (col1, col2, col3) VALUES ';
for($i=0; $i<$last; $i++) {
    $sql .= '("'. $list[$i]['col1'] .'", "'. $list[$i]['col2'] .'", '. $list[$i]['col3'] .'), ';
}
$sql .= '("'. $list[$last]['col1'] .'", "'. $list[$last]['col2'] .'", '. $list[$last]['col3'] .') ';
$sql .= 'ON DUPLICATE KEY UPDATE ';
for($i=0; $i<$last; $i++) {
    $sql .= 'col3 = '. $list[$i]['col3'] .', ';
}
$sql .= 'col3 = '. $list[$last]['col3'];

DB::statement($sql);

我查看了thisthis。我有点不清楚我应该怎么做。我应该这样做吗?

INSERT INTO table (col1, col2, col3) VALUES
    ( $list[$i]['col1'] , $list[$i]['col2'] , $list[$i]['col3'] ),
    ...
    ( $list[$i]['col1'] , $list[$i]['col2'] , $list[$i]['col3'] )

ON DUPLICATE KEY UPDATE
    col3 = $list[$i]['col3'],
    ...
    col3 = $list[$i]['col3'];

我也读过你可以沿着这些方向做点什么:

DB::connection()->getPdo()->quote($sql);

使用Laravel阻止上述查询的SQL注入的最佳和最简单的方法是什么?

3 个答案:

答案 0 :(得分:3)

防止SQL注入的最佳和最简单的方法是使用parameterised queries。如何对批量插入物进行多次回答,例如在这里:Insert multiple rows with PDO prepared statements

修改

为了清楚起见,要在Laravel中执行参数化查询,你可以

DB::insert($query, $params);

在纯PDO中的答案是

$stmt = DB::getInstance()->prepare($query);
$stmt->execute($params);

如何为批量插入准备$query$params的问题已经得到了回答,大量讨论了优缺点,并出现了边缘案例场景的一些替代解决方案。请阅读它们并了解它是如何工作的。

答案 1 :(得分:0)

我认为这是它,除非有人能用纯粹的Eloquent做到这一点。希望这有助于其他人尝试做类似的事情。

由于我使用col1 + col2作为键,我必须创建一个复合唯一键,如下所示:

CREATE UNIQUE INDEX col1_col2 ON table (col1, col2)

这是为了后代:

$last = count($list)-1;

$sql = 'INSERT INTO table (col1, col2, col3) VALUES ';
$values = [];

for($i=0; $i<$last; $i++) {
    $sql .= '( ?, ?, ? ), ';
    $values[] = $list[$i]['col1'];
    $values[] = $list[$i]['col2'];
    $values[] = $list[$i]['col3'];
}
$sql .= '( ?, ?, ? ) ';
$values[] = $list[$last]['col1'];
$values[] = $list[$last]['col2'];
$values[] = $list[$last]['col3'];

$sql .= 'ON DUPLICATE KEY UPDATE ';
$sql .= 'col3 = VALUES(col3)';

DB::statement($sql, $values);

干杯!

答案 2 :(得分:0)

使用原始查询时,

看起来像一个问题。找到了一篇很棒的文章,并希望将其传递给其他可能需要它的人。http://fideloper.com/laravel-raw-queries

Laravel确实使用了准备好的语句作为barry提到的,但看起来你需要专门传递一个绑定数组中的变量,以便在原始查询中发生这种情况。

 $someVariable = Input::get("some_variable");

$results = DB::select( DB::raw("SELECT * FROM some_table WHERE some_col = :somevariable"), array(
   'somevariable' => $someVariable,
 ));