Pdo包装功能安全吗?

时间:2016-12-08 21:20:48

标签: php pdo

我正在构建一个具有select, insert, delete, update功能的PDO包装器,实际上我做了更新功能,看起来像这样:

/**
 * @param string $table name of the table
 * @param array $data data to update
 * @param string $where where clause
 * @return bool result
 */
public function update($table, $data, $where)
{
    ksort($data);

    $fieldDetails = NULL;
    foreach($data as $key=> $value)
    {
        $fieldDetails .= "`$key`=:$key,";
    }
    $fieldDetails = rtrim($fieldDetails, ',');

    $sth = $this->prepare("UPDATE $table SET $fieldDetails WHERE $where");

    foreach ($data as $key => $value)
    {
        $sth->bindValue(":$key", $value);
    }

    return $sth->execute();
}

用法示例:

$postData = array(
        'username' => 'foo',
        'role' =>'admin'
    );

$this->db->update('login', $postData, "`id` = {$data['id']}");

我不知道这是否安全,或者我错过了重要的事情,有人建议改善这一点吗?

提前致谢。

2 个答案:

答案 0 :(得分:2)

不,这不安全,原因有两个。

  • 首先,$data['id']直接放入查询,因此不安全。它也必须受到约束。
  • 其次,$key直接放在查询中,因此不安全。我写了一篇文章来演示这样一个漏洞,并提供了一个解决方案:An SQL injection against which prepared statements won't help
  • 第三,$table直接放在查询中,因此不安全。我知道意味着在函数调用中被硬编码,但你在这里问这个函数是否安全,而我们不知道你是怎么调用它的。
    此外,随着项目的增长,很难对数据流保持手动控制。因此,最终表名将成为变量,并且可以从用户输入接受某一天。因此,最好让你的功能本身无法穿透,与任何外部事务无关。就像准备好的陈述一样。

要修复后两个漏洞,您应该将密钥列入白名单,或者至少正确格式化它们。并且应该在这个功能中完成。否则你绝对不能称之为安全。

答案 1 :(得分:-1)

我偶然发现了来自https://laurent22.github.io/so-injections/的问题,这是关于SO的SQL注入漏洞的php相关问题的统计数据。

所以,不。这不像现在这样安全。

这是报告为易受攻击的内容,我在此引用它以供将来参考。

$sth = $this->prepare("UPDATE $table SET $fieldDetails WHERE $where");

毫无疑问,这在许多软件中都被用于很多代码中。希望这对其他人也有用。