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

我啥时候应该使用准备好的语句?

是否可以在没有准备好的语句(Node.js 和 MSSQL)的情况下防止 SQL 注入

PHP:使用准备好的语句并防止 SQL 注入与逃逸

创建 MySQL 准备好的语句

这个准备好的语句可以防止 SQL 注入吗? [复制]

在 PHP 中使用准备好的语句/存储过程时如何保护自己免受 SQL 注入?