我的 PDO 查询对 SQL 注入安全吗?

Posted

技术标签:

【中文标题】我的 PDO 查询对 SQL 注入安全吗?【英文标题】:Is my PDO query safe from SQL injection [duplicate] 【发布时间】:2013-03-07 02:20:58 【问题描述】:

我对 PDO 还很陌生,想知道下面的查询是否可以避免 SQL 注入。如果是这样,我将在整个网站上使用此方法。

    // make connection to DB
$db = new PDO('mysql:host='.$dateBaseHost.';dbname='.$dateBaseName, $dateBaseUsername, $dateBasePassword);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);


//simple query and binding with results
$query = $db->prepare(" SELECT * FROM `profile` WHERE `fullname` = :fullname ");

$search = (isset($_GET['search']) === true) ? $_GET['search'] : '' ; // ? : shorthand for if else

// bind parameters - avoids SQL injection
$query->bindValue(':fullname', $search);

//try... if not catch exception
try 
    // run the query
    $query->execute();

    $rows = $query->fetchAll(PDO::FETCH_ASSOC);
    echo '<pre>', print_r($rows, true),'</pre>';

catch (PDOException $e)
    sendErrorMail($e->getMessage(), $e->getFile(), $e->getLine());

【问题讨论】:

只要你使用参数化,查询你的查询是安全的。 是的。您正在使用参数化,它将自动进行必要的转义。好东西! 【参考方案1】:

是的 - 以这种方式使用时,参数化查询不会被注入。

【讨论】:

它只是安全地抵御基本攻击......【参考方案2】:

只要您正确使用准备好的语句,您就不会被注入。但是只要您直接将任何外部数据插入到查询中,即使它是准备好的语句,例如

INSERT INTO $table VALUES (:param)

您很容易受到攻击 - 在这种情况下,$table 可能会被破坏,即使您使用的是准备好的语句。

任何告诉你简单地切换 mysql->PDO 或 mysqli 会让你更安全的人是彻头彻尾的错误。使用任一库,您都可能同样容易受到注入攻击。

【讨论】:

【参考方案3】:

是的,它相当安全,但整个脚本可以改进:

if (isset($_GET['search']) 
    // make connection to DB
    $opt = array(
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
    );
    $dsn = "mysql:host=$dateBaseHost;dbname=$dateBaseName;charset=$dateBaseCharset";
    $db  = new PDO($dsn, $dateBaseUsername, $dateBasePassword, $opt);

    //simple query and binding with results
    $query = $db->prepare("SELECT * FROM profile WHERE fullname = ?");
    $query->execute(array($_GET['search']));
    $rows = $query->fetchAll();
    echo '<pre>', print_r($rows, true),'</pre>';

您需要将 errmode 设置为连接选项 从不使用 try..catch 处理错误消息。如果您想针对每个错误发送电子邮件(这太疯狂了),您必须为此设置my_exception handler()。 将搜索设置为空字符串没有任何意义 应将连接到 PDO 的连接移至单独的文件(未显示) 字符集必须在 DSN 中设置

【讨论】:

为什么您应该从不使用try...catch 块来处理错误?他们在所有文档中都有它..? 我不是说“错误”而是“错误信息”。是的,他们都错了 我想知道您对 Marc B 的答案和解决方案的看法。【参考方案4】:

你也应该

$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

默认情况下,它使用模拟模式,它只是做mysql_real_escape_string 所做的事情。在某些边缘情况下,您仍然容易受到 SQL 注入的攻击。

【讨论】:

@YourCommonSense:但仍然很重要,请参阅骗子的答案,尤其是this one。 这实际上是做什么的? @user2183216:这已经在我的回答中了,它关闭了模拟模式。在模拟模式下,PDO 只是在变量周围加上引号并转义所有单引号,但这可能还不够。另请阅读重复的问题。

以上是关于我的 PDO 查询对 SQL 注入安全吗?的主要内容,如果未能解决你的问题,请参考以下文章

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

PHP - PDO 引用是不是对 SQL 注入安全?

防止 SQL 注入 - PDO,mysqli [重复]

这个查询注入证明吗?

PDO(预编译参数化查询)和安全问题

mysql PDO和存储过程动态SQL注入