我的PDO查询是否可以安全地从SQL注入

时间:2013-03-18 16:34:09

标签: php sql pdo sql-injection

我是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());
}

4 个答案:

答案 0 :(得分:8)

是 - 当以这种方式使用时,参数化查询可以安全地注入。

答案 1 :(得分:5)

只要你正确使用准备好的陈述,就可以安全地注射。但只要你 DIRECTLY 将任何外部数据插入查询中,即使它是一个准备好的语句,例如

INSERT INTO $table VALUES (:param)

你很脆弱 - 在这种情况下,$table可以被破坏,即使你正在使用准备好的陈述。

任何告诉你只需切换mysql-&gt; PDO或mysqli的人都会让你更安全是错误。您可能同样容易受到任何一个库的注射攻击。

答案 2 :(得分:3)

你也应该

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

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

答案 3 :(得分:0)

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

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应移动到单独的文件(未显示)
  • charset必须在DSN中设置