在 MySQL 中使用准备好的语句可以防止 SQL 注入攻击吗?
Posted
技术标签:
【中文标题】在 MySQL 中使用准备好的语句可以防止 SQL 注入攻击吗?【英文标题】:Does using prepared statements in MySQL prevent SQL injection attacks? 【发布时间】:2012-06-19 02:52:05 【问题描述】:我只是想验证在 mysql 中使用准备好的语句是否可以防止 SQL 注入。
下面的代码会阻止所有的 SQL 注入攻击吗?
$var = $_GET['q'];
$trimmed = trim($var);
if ($trimmed != NULL)
$get_fighters = $DBH->prepare(
'SELECT *
FROM fighters
WHERE name LIKE :searchTerm
OR nickname LIKE :searchTerm
OR born_in_city LIKE :searchTerm
OR born_in_state LIKE :searchTerm
OR born_in_country LIKE :searchTerm
ORDER BY name ASC');
$get_fighters->bindValue(':searchTerm', '%' . $trimmed . '%', PDO::PARAM_STR);
$get_fighters->setFetchMode(PDO::FETCH_ASSOC);
$get_fighters->execute();
$check_results_fighters = $get_fighters->rowCount();
$get_events = $DBH->prepare(
'SELECT *
FROM events
WHERE event_name LIKE :searchTerm
OR event_arena LIKE :searchTerm
OR event_city LIKE :searchTerm
OR event_state LIKE :searchTerm
OR event_country LIKE :searchTerm
OR organization LIKE :searchTerm
ORDER BY event_date DESC');
$get_events->bindValue(':searchTerm', '%' . $trimmed . '%', PDO::PARAM_STR);
$get_events->setFetchMode(PDO::FETCH_ASSOC);
$get_events->execute();
$check_results_events = $get_events->rowCount();
【问题讨论】:
Best way to prevent SQL Injection in php的可能重复 来自PDO::prepare
文档:“您不能在准备好的语句中两次使用同名的命名参数标记。” (尽管在某些带有 PDO/MySQL 驱动程序的 PHP 版本中模拟的预处理语句确实支持重复名称,但依赖此并不安全;另请参阅 "php pdo prepare repetitive variables"。)始终为 RTM。
eeek.. 这是否意味着我必须为每个单独的参数执行 searchTerm1、2、3、4 等...尽管它们的值都相同?
除了要求澄清之外,不应使用 cmets 提出其他问题。一方面,一个问题应该是可以理解的,无需阅读 cmets。另一方面,SO 是一个问答网站,而不是论坛,并且 cmets 不适合(也不适合)讨论。如果您有问题中尚未描述的其他要求,请编辑问题而不是发表评论。如果您有超出您最初提出的问题(如此处)的问题,请首先检查该问题是否已被提出(已提出),如果没有,则仅发布新问题。
【参考方案1】:
准备好的查询通过分离要运行的查询和要用于该查询的数据来防止攻击。这意味着不会发生一阶攻击,因为您没有将数据直接连接到查询中。
简而言之,如果您始终使用准备好的查询,并且您的所有数据都使用绑定参数发送(包括来自其他查询的数据!),那么就 SQL 注入而言,您没问题。
(我还应该注意,一些不支持准备好的查询的服务器的 PDO 驱动程序会使用传统的转义例程来伪造它。不要担心这个。这是安全的。)
【讨论】:
【参考方案2】:是的,根据 php 文档,使用准备好的语句将防止 SQL 注入。
见Link
【讨论】:
以上是关于在 MySQL 中使用准备好的语句可以防止 SQL 注入攻击吗?的主要内容,如果未能解决你的问题,请参考以下文章