在重新使用数据库中的数据进行查询时,是否需要使用mysqli_real_escape_string
?数据先前已转义,因此可以安全地插入数据库。我知道在将数据插入数据库时,会删除反斜杠。
感谢。
答案 0 :(得分:5)
是的,当您在另一个查询中重新使用数据库时,必须重新转义来自数据库的数据。考虑逃避相当于礼物包装礼物。您在一个查询中“包装”数据库的一些数据。它会将数据UNWRAP并将其放入数据存储中。当您稍后再次检索该数据时,包装已经消失,数据再次“危险”。
e.g。考虑这样的事情:
$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:你可以轻松注射自己。
答案 1 :(得分: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 ...
这也可能更有效,因为数据不必在数据库和应用程序之间移动。
答案 2 :(得分:1)
这不是逃避的意思。
转义文本意味着插入转义字符,以便将其插入到SQL字符串中并解释为原始文本。
它对实际值没有影响,除非你使用了错误的转义字符。
每次将文本连接成任何类型的结构化语言时,都需要正确地转义文本。
使用SQL时,理想情况下应使用参数而不是连接。
答案 3 :(得分:0)
对这个话题存在很多误解。
人们继续使用不正确的词语,以及来自这种混乱的真正危险。
逃避与安全混淆
数据与字符串相混淆
格式化与信任
人们必须解决这些问题
否则,我们仍然会得到一个可接受的答案,暗示使用mysql_real_escape_string
会产生“安全”变量。虽然不是。
答案 4 :(得分:-2)
请记住正确验证您计划使用的所有用户输入数据,并且不允许插入html或javascript代码。您还需要记住XSS攻击,而不仅仅是MySQL注入。防止xss的一个好方法是使用htmlspecialchars()将HTML字符转换为HTML实体。