0

mysqli_real_escape_string重用数据库中的数据进行查询时是否需要使用。数据之前已转义,因此可以安全地插入数据库。我知道在将数据插入数据库时​​,会删除反斜杠。谢谢。

4

5 回答 5

5

是的,当您在另一个查询中重新使用来自数据库的数据时,您必须重新转义它。将逃跑视为礼物包装的等价物。您在一个查询中“包装”数据库的一些数据。它将解包数据并将其放入数据存储中。当您稍后再次检索该数据时,包装已经消失,数据再次“危险”。

例如考虑这样的事情:

$name = "Miles O'Brien"; 
$safe = mysql_real_escape_string($name);  // name becomes Miles O\'Brien
$sql = "INSERT INTO people (names) VALUES '$safe'";
$result = mysql_query($sql) or die(mysql_error());

现在该名称在数据库中,但是您执行的转义不再存在 - 它在处理查询时被数据库删除,因此如果您执行以下操作:

$sql = "SELECT name FROM people"
$result = mysql_query($sql) or die(mysql_error());
while($row = mysql_fetch_asssoc($result)) {
   $name = $row['name']; // get Miles O'Brien from the DB again

在这里,您将完全Miles O'Brien没有逃避地进行检索。

   $other_sql = "UPDATE ... WHERE name=$name";  <---INJECTION HERE
}

转义不是您仅对“外部”数据执行的操作...您插入到查询字符串中的任何数据都是“外部”数据,即使您只是在几行代码之前从数据库中获取了该数据。

TL;DR:你可以很容易地给自己注射。

于 2013-07-26T15:45:41.997 回答
3

是的,你需要它。转义仅用于使查询在语法上有效,它们不是存储在表中的数据的一部分。每当您将字符串插入查询时,都需要对其进行转义。

例如,假设您有一个全名表,并且有一个姓氏的人O'Reilly。您执行查询以将此名称输入$lname,然后您想在另一个查询中使用该变量,例如

$query = "SELECT username WHERE last_name = '$lname'";

如果您不转义字符串,则生成的查询将是:

SELECT username WHERE last_name = 'O'Reilly'

如您所见,报价没有正确平衡。您需要将其转义,以便它成为:

SELECT username WHERE last_name = 'O\'Reilly'

但是,如果您将准备好的查询与这些参数的占位符一起使用,则根本不需要担心这一点(实际上,将绑定到占位符的变量转义是错误的,因为您将存储反斜杠)。这通常是优选的。

此外,考虑根本不提取和重新存储数据,而是使用 SQL 本身移动数据:

INSERT INTO Table1 (last_name)
SELECT last_name
FROM Table2
WHERE ...

这也可能更有效,因为数据不必在数据库和应用程序之间移动。

于 2013-07-26T15:42:50.053 回答
1

这不是逃避的意思。

转义文本意味着插入转义字符,以便可以将其插入到 SQL 字符串中并被解释为原始文本。
它对实际值没有影响,除非您使用了错误的转义字符。

每次将文本连接成任何类型的结构化语言时,都需要正确转义文本。

使用 SQL 时,最好使用参数而不是串联。

于 2013-07-26T15:40:45.383 回答
0

关于这个话题有很多误解。

人们一直在使用不恰当的词,而这种混乱带来了真正的危险。

转义安全
数据混淆与字符串
格式混淆与信任混淆

必须解决这些问题。
否则,我们仍然有一个可接受的答案,暗示 usingmysql_real_escape_string确实会产生“安全”变量。虽然不是。

于 2013-07-26T16:09:54.727 回答
-2

请记住正确验证您计划使用的所有用户输入数据,并且不允许插入 html 或 javascript 代码。您还需要记住 XSS 攻击,而不仅仅是 MySQL 注入。防止 xss 的一个好方法是使用 htmlspecialchars() 将 HTML 字符转换为 HTML 实体。

于 2013-07-26T15:47:10.113 回答