How to prevent an SQL injection in PHP?

What are the gaps in coverage for SQL Injection while using mysql_real_escape_string?

  • I have seen somewhere that although PHP provides this method, it still fails, at one point, to cover all of the bases when trying to avoid SQL Injection. This may have been a PHP 4 issue that was fixed in PHP 5 but I am not sure. Can anyone provide a definitive answer?

  • Answer:

    I'm assuming you are asking because you are building something using PHP and MYSQL and have security concerns.  If so: I suggest investigating the PDO interface to MYSQL (etc). Injection of data into queries, via  PDO->pepare, is inherently safe.

Sandro Pasquali at Quora Visit the source

Was this solution helpful to you?

Other answers

mysql_real_escape_string() only escapes characters that could terminate a string literal or date literal.  But you may want SQL queries to include dynamic parts other than those literals.  For example, say you have a query: SELECT * FROM MyTable ORDER BY column1 ASC But you want the give the user the option to choose which column to sort by, and which direction to sort (ascending vs. descending). SELECT * FROM MyTable ORDER BY $user_column $user_direction SQL support column identifier delimiters so you can have special words or characters in your column names.  MySQL uses back-quotes (or double-quotes if you set SQL mode ANSI_QUOTES). SELECT * FROM MyTable ORDER BY `$user_column` $user_direction But mysql_real_escape_string() doesn't escape these characters that could terminate a delimited column identifier.  So you have a risk of SQL injection because the user could submit a column name with back-ticks in it. SQL keywords like ASC aren't delimited by any type of quotes, so there's no way to use mysql_real_escape_string() to protect against SQL injection when you interpolate user input. The other PHP extensions for MySQL don't provide any better solution for these cases. The best solution is whitelisting.  That is, if the user enters a column to sort by, validate their input against a list of valid column names, which you keep in your app.  If the user enters something other than a known column name, ignore their input or give an error. Likewise for SQL keywords or other non-delimited elements you want to add to a dynamic query. See my presentation http://www.slideshare.net/billkarwin/sql-injection-myths-and-fallacies for more details and examples.

Bill Karwin

mysql_real_escape_string() does not escape % or _, because both are valid wildcard characters with some SQL commands. Otherwise, it escapes all special characters, taking into account the character set of the current connection. Although using mysql_real_escape_string() is an important security measure, it's no longer recommended to use the original MySQL extension for new projects. You should use MySQL Improved (MySQLi) or PDO. Both support prepared statements, which are much safer.

David Powers

This is that case: In http://en.wikipedia.org/wiki/GBK, 0xbf27 is not a valid multi-byte character, but 0xbf5c is. Interpreted as single-byte characters, 0xbf27 is 0xbf (¿) followed by 0x27 ('), and 0xbf5c is 0xbf (¿) followed by 0x5c (\). For more details look at this post http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string

Agajan Torayev

It might have to do with character mismatchs between the encoding of your SQL string, the payload you are sending and the connection encoding.

Armin Ronacher

Related Q & A:

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.