在MySQL中使用预处理语句能够防止SQL注入攻击吗?

4

我想确认在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(); 
}

2
可能是在PHP中防止SQL注入的最佳方法的重复问题。 - outis
PDO::prepare文档中得知:“在准备好的语句中,您不能两次使用相同名称的命名参数标记。”(尽管某些版本的PHP与PDO/MySQL驱动程序中的模拟预处理语句支持重复的名称,但依赖此功能并不安全。请参见"php pdo prepare repetitive variables")始终查阅手册。 - outis
哎呀..这是不是意味着我必须为每个单独的参数都做searchTerm1,2,3,4等,尽管它们都是相同的值? - zen
除了要求澄清外,注释不应用于提出其他问题。首先,问题应该可以在不阅读注释的情况下理解。其次,SO是一个问答网站,而不是论坛,注释不适合进行讨论。当您有尚未在问题中描述的其他要求时,请编辑问题而不是发布评论。如果您有比最初询问更多的问题(就像这里一样),请首先检查是否已经有人提出了该问题(是的),并且仅在没有时发布新的问题。 - outis
2个回答

7
准备好的查询通过将要运行的查询和用于该查询的数据分离来防止攻击。这意味着,由于您不直接将数据连成字符串,因此不会发生一级攻击。
简而言之,如果您始终使用准备好的查询,并且所有数据都使用绑定参数发送(包括其他查询中的数据!),则就SQL注入而言是安全的。
(我还应该注意一下,某些不支持准备好的查询的服务器的PDO驱动程序会使用传统的转义例程进行模拟。不必担心这个问题。这是安全的。)

3
是的,根据PHP文档,使用预处理语句可以防止SQL注入攻击。
请参考链接

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接