【问题标题】:Where should I place mysql_real_escape_string? [closed]我应该在哪里放置 mysql_real_escape_string? [关闭]
【发布时间】:2016-04-21 14:30:31
【问题描述】:

mysql_real_escape_string的最佳使用方式是什么,开头是这样的吗:

$email = mysql_real_escape_string($_POST['email']); 
$qemail = mysql_query ("SELECT email FROM ppl WHERE email='$email'"); 

或者在最后是这样的:

$email = $_POST['email'];
$qemail = mysql_query ("SELECT email FROM ppl WHERE email='". mysql_real_escape_string($email) ."'");

整个网站都在使用 mysql,所以我必须将它保存在 mysql 中。问题是,我不想到处使用 mysql_real_escape_string (代码看起来令人困惑和可怕)。我只想在 $_POST 的开头使用它,但这是否足够?

有些人建议最好在查询中使用它,但我不明白为什么。

【问题讨论】:

  • 这个强制是怎么回事?我还没有在 meta 上找到任何关于 @Carcigenicate 最近经常看到的内容。不这样做会受到惩罚吗? 哈哈
  • 主要基于意见
  • @Fred-ii- SO 不是强制性的,不。这是半个笑话。每次我看到 OP 使用已弃用的 mysql 的问题时,总会有人建议切换到 PDO 或 mysqli。
  • mysql_real_escape_string() 将在变量/值中转义引号。因此,如果这些变量(在这种情况下为 $email)用于查询,并且查询 only,则将 $_POST['email'] 传递给 mysql_real_escape_string($_POST['email']) prior 到查询很好。但是,如果您计划使用这些变量 post 查询,如果您的变量现在包含转义引号(如果适用),请不要感到震惊。
  • 然后拿起你的枪,把猫带进来。 ;-)

标签: php mysql security mysql-real-escape-string


【解决方案1】:

您应该将mysql_real_escape_string() 直接放入垃圾箱,然后迁移到mysqli 或PDO 和learn to use prepared statements

我之前在A Gentle Introduction to Application Security 中提到过,但是使 SQL 注入成为可能的根本问题是数据和代码的混淆。

准备好的语句将您的查询字符串 (SELECT * FROM foo WHERE column = ?) 和您的参数 (['foo']) 在单独的数据包中发送到数据库服务器。参数从不有机会接触到查询字符串,从而首先防止了导致 SQL 注入成为可能的条件。

转义输入和构建查询字符串没有相同的保证。当然,可以安全地执行此操作,但是如果您犯了一个错误并且an unskilled hacker 找到了它,那么您的整个数据库就完蛋了。 (请记住,SQL 注入是唾手可得的成果。)

TL;DR - Just use Prepared Statements.

【讨论】:

  • 谢谢,但不幸的是我注定要使用mysql。我只是不确定是否在开始时使用它,例如在定义变量时 ($email = mysql_real_escape_string($_POST['email']);) 就足够了。还是每次使用时都必须转义变量?
  • 是什么将您绑定到mysql_ 函数?
  • 全站都在用mysql_,没时间重写200页代码
  • 伙计们,冷静点。看起来 OP 已经知道准备好的语句。正如他所说 - 这是一个遗留代码。你并不总是可以选择如何编码,有时你需要调整你已经拥有的东西。我从不使用 mysql_ 编写新项目,但我仍然支持使用 mysql extension 编写的旧项目,而且我绝不会重写整个项目,至少现在不是。
【解决方案2】:

改用mysql_以外的更好的解决方案。

话虽如此,如果您必须使用已弃用的mysql_,我建议您使用 sprintf() 以提高可读性和易用性:

$qemail = sprintf('SELECT email FROM ppl WHERE email="%s"',
                  mysql_real_escape_string($_POST['email'])
                  );

$qr = mysql_query($qemail);

如果您有多个参数,则可以有多个 %s 和其他标签,请参阅 sprintf() 文档:

$str_qr = sprintf('SELECT * FROM table, WHERE val="%s", val2="%s", someIntegerField=%d',
      mysql_real_escape_string($val1), 
      mysql_real_escape_string($val2),
      mysql_real_escape_string($someNumberId),
);

$qr = mysql_query($str_qr);

【讨论】: