94

我正在阅读在进入 SQL 查询之前是否需要转义 $_SESSION['username']?它说“您需要转义传递给 sql 查询的每个字符串,无论其来源如何”。现在我知道这样的事情真的很基本。谷歌搜索出现了超过 20,000 个结果。仅 Stackoverflow 就有 20 页的结果,但没有人真正解释什么是转义字符串或如何进行转义。这只是假设。你能帮助我吗?我想学习,因为我一如既往地使用 PHP 制作 Web 应用程序。

我看过: 插入转义字符Java中的所有转义字符是什么?, 不能用 addcslashes() 转义字符串, 转义字符, mysql_real_escape_string() 到底是做什么的?, 如何在 php 中转义字符串中的双引号?, MySQL_real_escape_string 不加斜线?从 php 中的字符串中删除转义序列我可以继续,但我相信你明白了。这不是懒惰。

4

3 回答 3

150

转义字符串意味着减少该字符串中使用的引号(和其他字符)中的歧义。例如,当您定义一个字符串时,通常用双引号或单引号将其括起来:

"Hello World."

但是如果我的字符串中有双引号呢?

"Hello "World.""

现在我有歧义 - 解释器不知道我的字符串在哪里结束。如果我想保留我的双引号,我有几个选择。我可以在我的字符串周围使用单引号:

'Hello "World."'

或者我可以逃避我的报价:

"Hello \"World.\""

任何以斜杠开头的引号都会被转义,并被理解为字符串值的一部分。

在查询方面,MySQL 有一些它监视的关键字,我们不能在查询中使用这些关键字,而不会造成一些混乱。假设我们有一个值表,其中一列名为“Select”,我们想要选择它:

SELECT select FROM myTable

我们现在在查询中引入了一些歧义。在我们的查询中,我们可以通过使用反引号来减少这种歧义:

SELECT `select` FROM myTable

这消除了我们在选择字段名称时使用错误判断而引入的混淆。

只需将您的值传递给mysql_real_escape_string(). 在下面的示例中,您可以看到我们正在通过此函数传递用户提交的数据,以确保它不会对我们的查询造成任何问题:

// Query
$query = sprintf("SELECT * FROM users WHERE user='%s' AND password='%s'",
            mysql_real_escape_string($user),
            mysql_real_escape_string($password));

转义字符串还有其他方法,例如add_slashes, addcslashes,quotemeta等,尽管您会发现当目标是运行安全查询时,大多数开发人员更喜欢mysql_real_escape_stringor pg_escape_string(在 PostgreSQL 的上下文中。

于 2012-05-18T03:01:43.300 回答
23

某些字符对您正在使用的 SQL 数据库具有特殊含义。在查询中使用这些字符时,它们可能会导致意外和/或意外行为,包括允许攻击者破坏您的数据库。为了防止这些字符以这种方式影响查询,需要对它们进行转义,或者换一种说法,需要告诉数据库不要将它们视为该查询中的特殊字符。

mysql_real_escape_string()它转义的情况下\x00, \n, \r, \,和这些',当不转义时,可能会导致前面提到的问题,包括 MySQL 数据库的 SQL 注入。"\x1a

于 2012-05-18T03:00:59.270 回答
1

为简单起见,您基本上可以将反斜杠“\”想象为运行时对解释器的命令。

例如,在解释此语句时:

$txt = "Hello world!";

在词法分析阶段(或将语句拆分为单独的标记时),这些将是标识的标记 $, txt, =, ", Hello world!, ", 和;

然而,字符串中的反斜杠将导致一组额外的标记,并被解释为对紧随其后的字符执行某些操作的命令:例如

$txt = "this \" is escaped";

产生以下标记: $, txt, =, ", this, \, ", is escaped, ", 和;

\解释器已经知道(或者已经预设了它可以采用的路线)基于令牌之后的字符要做什么。因此,在"它继续将其视为字符而不是字符串结尾命令的情况下。

于 2020-06-01T14:27:44.573 回答