views:

298

answers:

4

I have this function I'm using and I want to be sure that it fully protects against SQL injection attacks:

function MakeSafeForQuery($string)
{
    // replace all of the quote
    // chars by their escape sequence

    $ret = str_replace("\\","\\\\",$string);
    $ret = str_replace("'","\\'",$ret);
    $ret = str_replace("\"","\\\"",$ret);

    return $ret;
}

Am I missing anything serious?

Edit: I'm using MySQL by the way.

+1  A: 

Couldn't you just use mysql_real_escape_string or are you trying to do it without a database connection?

(Which seems to defeat the purpose....)

Chacha102
I'm trying to see if I can write something that works WITHOUT using `mysql_real_escape_string`. Does what I have protect me from problems?
George Edison
Why, George? If you take your car to a garage, would you want the mechanic to build his own tools and run-up your bill? No? Cause your clients/boss don't want YOU to waste THEIR time and MONEY.
Coronatus
No, it won't protect you from problems. Proper escaping is a good first step.
Xorlev
+3  A: 

To protect against SQL injections, you should not use a function you are writing yourself.

Instead, you should use a function that's provided by your database driver.

For instance :


The right way to escape strings depends on both the database system, and its configuration (which is why escaping functions generally require an active database connection) -- which means your function could/would work in most cases, but not necessarily always.

Pascal MARTIN
Escaping itself is not enough to protect anything
Col. Shrapnel
+7  A: 

In 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 ().

How does this help? If I want to attempt an SQL injection attack against a MySQL database, having single quotes escaped with a backslash is a bummer. If you're using addslashes(), however, I'm in luck. All I need to do is inject something like 0xbf27, and addslashes() modifies this to become 0xbf5c27, a valid multi-byte character followed by a single quote. In other words, I can successfully inject a single quote despite your escaping. That's because 0xbf5c is interpreted as a single character, not two. Oops, there goes the backslash.

This type of attack is possible with any character encoding where there is a valid multi-byte character that ends in 0x5c, because addslashes() can be tricked into creating a valid multi-byte character instead of escaping the single quote that follows. UTF-8 does not fit this description.

To avoid this type of vulnerability, use mysql_real_escape_string()

http://shiflett.org/blog/2006/jan/addslashes-versus-mysql-real-escape-string

Dan
+2  A: 

These days, you should use prepared statements, whose parameters aren't vulnerable to injection, rather than sanitizing functions. PDO supports them. Read "Writing MySQL Scripts with PHP and PDO" for more information.

Note that only scalar values can be parameterized with most DB drivers. Compound values (such as used in the IN (list) operator) and other parts of statements cannot usually be parameterized. For these, you still need to interpolate values into the statement. It's best not to ever use user input directly for anything other than values.

outis
Note that prepared statements won't help you with query identifiers. Nor any escaing function do.
Col. Shrapnel
@Col.: an important point, hence the (admittedly terse) phrasing "parameters aren't vulnerable". Answer updated to be more explicit.
outis