【问题标题】:questions about mysql_real_escape_string关于 mysql_real_escape_string 的问题
【发布时间】:2012-04-21 14:28:51
【问题描述】:

我正在使用 php 开发我的个人网站。一切都很好,但我刚刚阅读了php.net 中的mysql_real_escape_string 手册并发现了两件事:

  1. 在向 MySQL 发送查询之前,必须始终(除少数例外)使用此函数来确保数据安全。
  2. mysql_real_escape_string() 不会转义 % 和 _。如果与 LIKE、GRANT 或 REVOKE 结合使用,这些是 MySQL 中的通配符。

我有两个问题:
1-这些例外是什么?
2- 如何转义这些字符?

【问题讨论】:

标签: php mysql escaping wildcard


【解决方案1】:

在向 MySQL 发送查询之前,必须始终(除了少数例外)使用此函数来确保数据安全。

令我非常失望的是,手册页上写着完全是垃圾,还有they refuse to make it correct
因此,恰恰相反,只有少数情况下您需要此功能。所以只能说一个:当您将 a string 添加到 SQL 查询中时。

mysql_real_escape_string() 不会转义 % 和 _。如果与 LIKE、GRANT 或 REVOKE 结合使用,这些是 MySQL 中的通配符。

没关系。只要您故意使用 LIKE 运算符,这些字符就不会造成任何伤害。

但是如果你想转义到 LIKE 语句的字符串,你可以使用这个代码

$like = addCslashes($like,'\%_');

(注意斜线 - 它也需要作为手动说明进行转义。还要注意函数名称中的C 字母)。
在此过程之后,您可以使用生成的 $like 变量,无论您使用何种方式构建查询 - 引用并转义它们或在准备好的语句中使用。

【讨论】:

  • 只需使用相同的斜线即可。 addCslashes($data,"%_"); 会成功的
  • 但只对进入模式匹配上下文的片段执行此操作。否则,您将在 SQL 中看到文字 \%
  • @YourCommonSense 我还有一个问题:我使用正则表达式检查输入数据,并在我的 sql 查询中使用来自mysql_real_escape_string 的返回数据。是否足以防止sql注入?如果没有,你能给我一个关于这个主题的好资源吗?
  • 正则表达式和转义都与注入无关。如果您“在 sql 查询中使用从 mysql_real_escape_string 返回的数据”它不会使您的查询安全。一个足够好的资源是我对 cme​​ts 中 mario 链接的问题的回答:stackoverflow.com/a/9821406/285587 或者,如果你愿意,这里是另一个具有完全保护的方法:stackoverflow.com/a/2995163/285587
【解决方案2】:

我不确定手册在谈到确保数据安全时所指的例外情况。您可以说例外情况是数据已知是安全的。例如,我想到了以下几个案例:

  • 数据以数字形式输入(这实际上是下一项的特化)
  • 您已经知道它不包含任何需要转义的字符(例如,它来自在包含您硬编码的一些选项的“白名单”数组中查找某些内容)

例如,如果您有 $id = intval($_GET['id']),那么在将其注入查询之前,您无需转义 $id

但是!转义所有输入永远不会伤害您,这样做可以消除您在代码中引入漏洞的机会(例如,如果您忘记转义,如果需求发生变化,或者真的发生了什么变化)。所以我建议养成逃避一切并忘记“例外”的习惯。

至于作为输入的一部分的%_ 字符,这些不需要转义除非您将此输入提供给识别它们的命令。例如,如果您有这样的查询:

$term = $_GET['term'];
$sql = sprintf("SELECT FROM table WHERE column LIKE '%%s%'",
               mysql_real_escape_string($term));

在这种情况下,如果用户键入 % 作为 $term 的一部分,则可以合理地假设他们想要实际搜索文字 %。因此,在这种情况下,您应该转义 %,将其替换为 \%\ 是默认转义字符)。 str_replacestrtr 是两个不错的选择。

【讨论】:

  • mysql_real_escape_string 与 safety 无关。这是完全不同的事情(我不得不承认,PHP 的人大都误会了)。事实上,转义只是一个字符串格式化工具,仅此而已。即使任何“安全”数据都可能包含一个换行符,为了日志的可读性必须更换它。更不用说对不安全的标识符没有任何好处。
  • @YourCommonSense:用引号括起来 + mysql_real_escape_string = 安全。它一切都与间接的安全有关,因为它是直接(引用)提供安全的先决条件。无论如何,谢谢你的DV。
  • However! It can never hurt you to escape all input, 恭喜你,你刚刚发明了magic quotes 功能!
  • @YourCommonSense:我不会用一个答案来证明这一点。
  • 你只是证明你并不完全理解这件事。如果它是“逃避并引用所有输入永远不会伤害你” - 它至少是可以忍受的。但这样一来,它将成为一个诽谤性的魔术报价,具有所有的缺点、缺点和漏洞
【解决方案3】:

您可以write your own function ;) 请参阅this thread 了解更多信息。

否则,您可以使用 PDO library 或任何其他此类库。

【讨论】:

  • 第一个链接是给MSSQL而不是mysql:-)
  • 是的,这只是为了说明如何实现为 mysql 手动编写函数的逻辑。 MySQL 也可以实现相同的逻辑..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-11
  • 2011-06-08
  • 1970-01-01
  • 2012-03-06
  • 1970-01-01
  • 2010-11-04
  • 2021-11-29
相关资源
最近更新 更多