不使用mysqli_real_escape_string()输入sanitizaton

I want to strip user input of SQL executable statements, but the way the codebase is I don't want to establish a DB connection which mysqli_real_escape_string(connection, string) requires.

What is an elegant regex/replace one-liner to sanitize the strings?

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

---UPDATE---- Example solution. Thanks for the input guys.

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

While I definitely agree with the comments and answer that using prepared statements, and not doing this yourself is both smarter, better in many ways and always recommended when you can use them. While you may not have a security problem now, one may suddenly appear in the future; and the risk with prepared statements is just much, much lower. If you can find a workaround for it, do it!

I feel like I have to give that disclaimer, in order to be taken seriously here.

Because, I also believe it's definitely possible to do all the escaping manually; given that the environment is controlled. This is no different than escaping for other formats, such as javascript. Sometimes this is needed. I, for one, once had a need to create a SQL export script with no database available.

To do this correctly, the following must be assumed:

  • The input string is UTF-8. You validated this.
  • When you execute the mysql string later down the road, the full sql statement is in UTF-8, and so is the connection.
  • No crazy stuff is going on with php's mbstring function overloading.
  • You don't trust my untested code, and verify what I'm saying ;)

Why is UTF-8 so important? Read this article

Given those two points, to emulate mysql_real_escape_string, you must escape the following characters:

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

Source: php.net

To do this, this should be sufficient:

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

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

As you can see, I did still make sure that my output was surrounded by quotes. Without that, this escaping technique (nor mysqli::real_escape_string) would not be sufficient.

Alternative techniques I've seen:

  • Splitting up every byte, and surrounding it with MySQL's CHAR function.
  • Base64-encoding the string in PHP, and base64-decoding it with MySQL 5.6's FROM_BASE64 function.

You cannot properly escape query data without having a connection, and therefore knowledge of the character set.

Do not try to do this yourself. Your implementation is bound to be insecure. You should be using prepared queries to separate the data from the query anyway.