Double转义字符串是错误的吗?

Sho*_*hoe 3 php mysql string escaping

我有一个数据库类,在使用mysqli_real_escape_string()构建查询之前自动转义输入字符串.但可能是在脚本中,字符串被转义然后传递给再次转义它的数据库类.这可能是错的吗?怎么会发生什么?

Amb*_*ber 6

由于你没有很好的方法告诉另一端(当你从数据库中提取数据时)它被转义了多少次,不一致的双重转义字符串将最终导致你在最终数据中丢失了数据之前没有 - 因为你将添加两层逃逸但只有一层.

基本上,你需要有一个恒定的转义级别 - 要么总是逃避一次(并且一次性转移它们),要么总是逃避它们两次(并且两次转换它们)等等 - 但从不混合.


Kri*_*rdy 5

在第一次传递时,通过在每个危险字符之前mysqli_real_escape_string插入一个字符来转义以下\字符:

NUL(ASCII 0),\n,\ r,\,',"和Control-Z:

NUL (chr(0)) becomes "\0" (chr(92).chr(48))
\n (chr(13)) becomes "\n" (chr(92).chr(110))
\r (chr(10)) becomes "\r" (chr(92).chr(114))
\ (chr(92)) becomes "\\" (chr(92).chr(92))
' (chr(39)) becomes "\'" (chr(92).chr(39))
" (chr(34)) becomes "\"" (chr(92).chr(34))
Control-Z (chr(26)) becomes "\Z" (chr(92).chr(90))
Run Code Online (Sandbox Code Playgroud)

在第二次通过时mysqli_real_escape_string,\再次逃脱:

"\0" (chr(92).chr(48)) becomes "\\0" (chr(92).chr(92).chr(48))
"\n" (chr(92).chr(110)) becomes "\\n" (chr(92).chr(92).chr(110))
"\r" (chr(92).chr(114)) becomes "\\r" (chr(92).chr(92).chr(114))
"\\" (chr(92).chr(92)) becomes "\\\\" (chr(92).chr(92).chr(92).chr(92))
"\'" (chr(92).chr(39)) becomes "\\'" (chr(92).chr(92).chr(39))
"\"" (chr(92).chr(34)) becomes "\\"" (chr(92).chr(92).chr(34))
"\Z" (chr(92).chr(90)) becomes "\\Z" (chr(92).chr(92).chr(90))
Run Code Online (Sandbox Code Playgroud)

双重转义字符串不会产生任何类型的漏洞,但它会在您保存到数据库中的字符串中插入许多额外的"\"字符.

转义的最佳方法是:1)关闭魔术引号2)仅使用带有命名参数的查询,在将其传递给查询之前不要转义任何内容.MySQL(以及所有其他数据库供应商)将正确地逃避字符串.(但是,您可能会遇到chr(0)终止字符串的问题).

如果您绝对必须使用字符串查询,请在将数据插入查询之前将数据转义一次,并且只转义一次.不要逃避整个查询.