不使用mysqli_real_escape_string()输入sanitizaton

时间:2012-11-14 21:25:20

标签: php sql regex

我想删除SQL可执行语句的用户输入,但代码库的方式我不想建立mysqli_real_escape_string(连接,字符串)所需的数据库连接。

什么是优雅的正则表达式/替换单线程来消毒字符串?

<?php
$naughty = array("\\", "{", "}", ")", "(", "[", "]", "\"", ";", ":", ">", "&");
$sanitized = str_replace($naughty, " ", $input_string);
?> 

--- ---- UPDATE 示例解决方案感谢输入人员。

<?PHP 
      $testsql = "';\"\\ bork bork bork %A 0x33\n";
      echo $testsql;
     /* $translate = array("0x" => "[HEX]",  ";" => "[SEMICOLON]", "'" => "[QUOTE]", "%" => "[PERCENT]","\"" => "[DOUBLEQUOTE]",
      "\\" => "[BACKSLASH]" ); */
      $translate = array("0x" => " ",  ";" => " ", "'" => " ", "%" => " ","\"" => " ", "\\" => " ");
      echo "<br>";
      $testsql=strtr($testsql, $translate);
      echo $testsql;
?>

2 个答案:

答案 0 :(得分:3)

虽然我完全赞同使用准备好的陈述的评论和答案,而不是自己这样做是更聪明,在许多方面更好,并且在你可以使用它们时总是建议。虽然你现在可能没有安全问题,但未来可能会突然出现;准备好的陈述的风险要低得多。如果你能找到解决方法,那就去做吧!

我觉得我必须给出免责声明,以便在这里得到认真对待。

因为,我也相信绝对有可能手动完成所有的转义;鉴于环境受到控制。这与其他格式(例如javascript)的转义没什么不同。有时需要这样做。例如,我曾经需要创建一个没有数据库可用的SQL导出脚本。

要正确执行此操作,必须假设以下内容:

  • 输入字符串为UTF-8。你验证了这一点。
  • 当你稍后执行mysql字符串时,完整的sql语句是UTF-8,连接也是如此。
  • php mbstring function overloading没有疯狂的东西。
  • 你不相信我未经测试的代码,并验证我在说什么;)

为什么UTF-8如此重要? Read this article

鉴于这两点,要模拟mysql_real_escape_string,您必须转义以下字符:

NUL (ASCII 0), \n, \r, \, ', ", and Control-Z. 

来源:php.net

要做到这一点,这应该足够了:

$translate = array(
  "\x00" => '\\0',
  "\n"   => '\\n',
  "\r"   => '\\r',
  "'"    => '\\\'',
  "\""   => '\\"',
  "\x1a" => '\\Z',
);

$output = "'" . strtr($input, $translate) . "'";

正如您所看到的,我仍然确保我的输出被引号括起来。没有它,这种逃避技术(也不是mysqli::real_escape_string)是不够的。

我见过的替代技术:

  • 拆分每个字节,并用MySQL的CHAR函数包围它。
  • Base64-用PHP编码字符串,并使用MySQL 5.6的FROM_BASE64函数对其进行base64解码。

答案 1 :(得分:2)

如果没有连接,就无法正确转义查询数据,因此无法了解字符集。

不要试图自己这样做。你的实现必然是不安全的。您应该使用准备好的查询来将数据与查询分开。