我的 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 注入安全吗?的主要内容,如果未能解决你的问题,请参考以下文章