围绕in子句的PHP安全性问题是串联字符串

时间:2013-09-04 12:41:58

标签: php sql security

鉴于以下code

 <?php
$values = array('Foo'  =>'Foo'  ,'Bar'  =>'Bar'  );
$separated = "'" . implode("','", $values)."'";
$sql = 'SELECT NAME,AGE FROM CATS WHERE TITLE IN('  .$separated.')'  ;

print_r($sql);

产生

 SELECT NAME,AGE FROM CATS WHERE TITLE IN('Foo','Bar')

使用这种类型的查询构建器,我需要了解有关SQL注入的任何内容吗?如果是这样,可能发生的攻击是什么?

2 个答案:

答案 0 :(得分:2)

SQL安全的唯一规则:

应该直接向查询添加NO值,但仅通过占位符

因此,您必须使用支持占位符的库。

假设您的数据库是mysql,最好的选择是safemysql,这将让您拥有如此简单的代码:

$sql  = 'SELECT NAME,AGE FROM CATS WHERE TITLE IN(?a)';
$data = $db->getArr($sql, $values);
print_r($data);

或者你可以使用PDO,但它会带你a lot more trouble

答案 1 :(得分:2)

您不应该在查询中使用任何变量,无论它们来自何处。 PDO和参数化查询的解决方案是将占位符添加到查询中。

我这样做:

function getPlaceholders ($array) {
  return !empty($array)
    ? implode(',', array_fill(0, count($array), '?'))
    : null;
}

$userIds = array(1,2,3,4);

$sql = 'SELECT FROM users WHERE id IN (' . $this->getPlaceholders($userIds) . ')';
$result = pdo_query($sql, $userIds);

通常情况下,你会采用OOP格式。

$userIds = array(1,2,3,4);

$sql = 'SELECT FROM users WHERE id IN (' . $this->getPlaceholders($userIds) . ')';
$result = $this->db->query($sql, $userIds);


// common file which is extended
public function getPlaceholders ($array) {
  return !empty($array)
    ? implode(',', array_fill(0, count($array), '?'))
    : null;
}

这将生成如下查询:

SELECT FROM users WHERE id IN (?,?,?,?)