这个代码在 PDO 中是​​ sql-injection-safe 吗?

Posted

技术标签:

【中文标题】这个代码在 PDO 中是​​ sql-injection-safe 吗?【英文标题】:Is this code sql-injection-safe in PDO? 【发布时间】:2011-08-18 17:31:24 【问题描述】:

代码(新手):

        if(isset($_POST['selection']))
        
            include_once 'pdo_init.php';
            $params_str = str_repeat('?,',count($_POST['selection']));
            $params_str = substr($params_str,0,-1);
            $res = $pdo->prepare('DELETE FROM funcionario WHERE codigo in ('.$params_str.')');
            if($res->execute($_POST['selection']))
            
                return json_encode(array(
                    'success' => 1,
                    'msg'     => 'os registros foram deletados com sucesso!'
                ));
             else 
                return json_encode(array(
                    'success' => 0,
                    'msg'     => 'nao admitimos sql-injection aqui seu safado!'
                ));
            
         else 
            # error out
            break;
        

【问题讨论】:

【参考方案1】:

学究式地,不,它不是 100% 安全的(您通常从准备好的语句中得到)。那是因为使用 mysql,PDO emulates prepared statements 在内部。这意味着数据被转义,因此在涉及 PDO(至少使用默认设置)时,使用准备好的语句而不是转义没有任何好处。

您可以通过在连接上设置PDO::setAttribute(PDO::ATTR_EMULATE_PREPARES, 0) 来更改此设置。

MySQLi 确实使用真正的预处理语句,所以我建议使用它。

【讨论】:

【参考方案2】:

看起来您正在动态进行参数化查询。

参数化查询是注入安全的。

但也要注意content itself

【讨论】:

【参考方案3】:

看起来注入是安全的,只要允许用户删除表中的所有行(因为如果她愿意,她可以发送包含表中所有 codigo 的 POST)。

不可能诱使您的查询触及其他表。

【讨论】:

【参考方案4】:

您使用?prepare 做得正确。请注意,PDO 不会保护您免受的一种情况是动态表/列名。 PDO(和 mysql_real_escape_string)不会逃避反引号,`,所以尽量不要使用动态表或列名。

【讨论】:

以上是关于这个代码在 PDO 中是​​ sql-injection-safe 吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 pdo 作为 getter 来最好地获取数据

PDO类基本应用二

SQL-inject

使用 sql-injection 创建数据库触发器,无需堆叠查询

使用PDO执行基于另一个查询结果的查询的函数

这个 PDO 代码对 SQL 注入是不是足够安全? [复制]