mysqli_real_escape_string
重用数据库中的数据进行查询时是否需要使用。数据之前已转义,因此可以安全地插入数据库。我知道在将数据插入数据库时,会删除反斜杠。谢谢。
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:你可以很容易地给自己注射。
是的,你需要它。转义仅用于使查询在语法上有效,它们不是存储在表中的数据的一部分。每当您将字符串插入查询时,都需要对其进行转义。
例如,假设您有一个全名表,并且有一个姓氏的人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 ...
这也可能更有效,因为数据不必在数据库和应用程序之间移动。
这不是逃避的意思。
转义文本意味着插入转义字符,以便可以将其插入到 SQL 字符串中并被解释为原始文本。
它对实际值没有影响,除非您使用了错误的转义字符。
每次将文本连接成任何类型的结构化语言时,都需要正确转义文本。
使用 SQL 时,最好使用参数而不是串联。
关于这个话题有很多误解。
人们一直在使用不恰当的词,而这种混乱带来了真正的危险。
转义与安全
数据混淆与字符串
格式混淆与信任混淆
必须解决这些问题。
否则,我们仍然有一个可接受的答案,暗示 usingmysql_real_escape_string
确实会产生“安全”变量。虽然不是。
请记住正确验证您计划使用的所有用户输入数据,并且不允许插入 html 或 javascript 代码。您还需要记住 XSS 攻击,而不仅仅是 MySQL 注入。防止 xss 的一个好方法是使用 htmlspecialchars() 将 HTML 字符转换为 HTML 实体。