Bug #22243 Unicode SQL Injection Exploit
Submitted: 11 Sep 2006 18:44 Modified: 7 Jul 2009 17:05
Reporter: Bryan Livingston Email Updates:
Status: Duplicate Impact on me:
None 
Category:Connector / NET Severity:S2 (Serious)
Version:1.0.2445.20017 OS:Microsoft Windows (Windows XP)
Assigned to: CPU Architecture:Any
Tags: Exploit, Injection, Unicode

[11 Sep 2006 18:44] Bryan Livingston
Description:
.net strings are a encoded in UTF-16.  Strings are converted to Windows-1252 (SBCS Encoding) to be sent over the network and during this conversion unicode characters that may not have been checked for will "become" single quotes.

These unicode quote characters are receivable over cgi and are not typically checked for.

There should be a managed API equivalent to mysql_real_escape_string().  http://dev.mysql.com/doc/refman/5.0/en/mysql-real-escape-string.html

How to repeat:
Run a sql command containing the text "Hui Min's Revision Timetable" or "Mαgđαlэи′s Đαяκиээs".  Specifically, In the second string the problem quote is unicode character 8242 ("\u8242").  When this string is received by the server the quote will be a single quote (ASCII 96) and break the query and could be used as a sql injection attack.

Suggested fix:
This AddSlashes method was originally created by some PHP->C# converter.  I've added the encoding fix that makes the problem go away.

I think something like this should be added to the managed library.  Maybe something like MySqlHelper.EscapeString().

        private static Encoding encoder = Encoding.GetEncoding(1252); // default windows code page

        /// <summary>
        /// Quotes the specified string with backslashes. 
        /// The characters to be quoted are: quote('), double quote("), backslash(\) and null(0).
        /// </summary>
        /// <param name="command">The string to be quoted with backslashes.</param>
        /// <returns>Returns the quoted string.</returns>
        public static string AddSlashes(string text)
        {
            string result = encoder.GetString(encoder.GetBytes(text)); // cleans unicode quote characters from other code pages
            result = result.Replace("\\", "\\\\");
            result = result.Replace("\'", "\\\'");
            result = result.Replace("\"", "\\\"");
            result = result.Replace("\0", "\\0");
            return result;
        }
[11 Sep 2006 19:03] Bryan Livingston
A better encoder is probably.  This is very simmilar but may have better support for the euro sign or may perform better.

        private static Encoding encoder = Encoding.Default; // default windows code page (1252)

And from the disassemble code of the Encoding.Default, it use the following 
code logic:

===========
private static Encoding CreateDefaultEncoding()
{
      int num1 = Win32Native.GetACP();
      if (num1 == 0x4e4)
      {
            return new SBCSCodePageEncoding(num1);
      }
      return Encoding.GetEncoding(num1);
}
===========
[18 Sep 2006 7:46] Tonci Grgin
Hi Bryan, can you please recheck answers posted by Reggie in BUG#10870 and get back with results?
[18 Oct 2006 23:00] Bugs System
No feedback was provided for this bug for over a month, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
[7 Jul 2009 17:05] Reggie Burnett
this is the same bug as bug #45941 which is getting fixed in 5.1.8+, 5.2.7+, and 6.0.5+