Fun with addslashes()

Discussions of secure PHP coding. Security in software is important, so don't be afraid to ask. And when answering: be anal. Nitpick. No security vulnerability is too small.

Moderator: General Moderators

User avatar
shiflett
Forum Contributor
Posts: 124
Joined: Sun Feb 06, 2005 11:22 am

Fun with addslashes()

Post by shiflett »

In the past few years, I've listened to many debates about the merits of mysql_real_escape_string() versus addslashes(). A disturbing number of people assert that there is absolutely no difference between the two, and that both are sufficient safeguards against SQL injection in any context.

Although the difference may not matter to you, I decided to write an example of an SQL injection attack that is immune to addslashes():

http://shiflett.org/archive/184

I thought it was a fun example and wanted to share. :-)
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

Thanks Chris, I'm going to link this thread in Useful Posts.
foobar
Forum Regular
Posts: 613
Joined: Wed Sep 28, 2005 10:08 am

Post by foobar »

Just as a side-note, your blog doesn't validate (69 errors):

http://validator.w3.org/check?uri=http: ... rchive/184

:?
User avatar
hawleyjr
BeerMod
Posts: 2170
Joined: Tue Jan 13, 2004 4:58 pm
Location: Jax FL & Spokane WA USA

Post by hawleyjr »

foobar wrote:Just as a side-note, your blog doesn't validate (69 errors):

http://validator.w3.org/check?uri=http: ... rchive/184

:?
Chris is pretty well known for his security. I don't really think anyone really cares about his site being 100% XHTML 1.1 compliant

Interesting article Chris.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

hawleyjr wrote:
foobar wrote:Just as a side-note, your blog doesn't validate (69 errors):

http://validator.w3.org/check?uri=http: ... rchive/184

:?
Chris is pretty well known for his security. I don't really think anyone really cares about his site being 100% XHTML 1.1 compliant

Interesting article Chris.
Yeah agreed.... I don't think that was entirely neccessary. What on earth did that have to do with this thread? :?
User avatar
Maugrim_The_Reaper
DevNet Master
Posts: 2704
Joined: Tue Nov 02, 2004 5:43 am
Location: Ireland

Post by Maugrim_The_Reaper »

I don't see why you should have called it a debate.

I mean in a debate both sides must have some merit to their arguments - since it should be obvious addslashes() does not perform database specific escaping (does it use '' for MSSQL rather than \' ? That one's spreading too...) one side lacks convincing evidence.

What debate? ;)

Good point though - its still a very common perception. I blame it on all the older PHP tutorials in dire need of updating you can find on Google for confusing new PHP users...
User avatar
shiflett
Forum Contributor
Posts: 124
Joined: Sun Feb 06, 2005 11:22 am

Post by shiflett »

hawleyjr wrote:I don't really think anyone really cares about his site being 100% XHTML 1.1 compliant.
Thank goodness. :-) The site structure is valid XHTML, but I think my blog entries mess it up.
d11wtq wrote:What on earth did that have to do with this thread?
He probably just doesn't know about private messages. Or email. :-)
Maugrim_The_Reaper wrote:I mean in a debate both sides must have some merit to their arguments.
I don't think so, but either way, I wanted to put an end to the arguments to the contrary. Some people don't appreciate theory, so a concrete example seemed best.
Roja
Tutorials Group
Posts: 2692
Joined: Sun Jan 04, 2004 10:30 pm

Post by Roja »

hawleyjr wrote:Chris is pretty well known for his security. I don't really think anyone really cares about his site being 100% XHTML 1.1 compliant
On the contrary, many people do, myself included. His knowledge of security doesn't change that. Worse, specifying that it is xhtml, and not html, means that browsers can reasonably refuse to display it if validation occurs. Unlike HTML, XHTML does not ask the vendor to display invalid code. Further, the linerarized version of the blog is non-ideal as well.

My blog isn't compliant either, many aren't. Its a particularly challenging field for programming to get right.

But none of that is on-topic. The article brings up an interesting point, and the delivery mechanism is close to ideal. Its not ideal, but perfection is usually hard to attain. :)
matthijs
DevNet Master
Posts: 3360
Joined: Thu Oct 06, 2005 3:57 pm

Post by matthijs »

I read both articles from Chris and Ilia, but I'm sorry to say: they only confuse me more.
First, Chris says using addslashes leaves you vulnerable to injection.
Despite the use of addslashes(), I'm able to log in successfully without knowing a valid username or password.
But then Ilia points out the same can happen with mysql_real_escape_string, in certain situations.
So, to be on the safe side, I'd recommend using the PDO interface to talks with those databases or in the case of MySQL using the newer MySQLi (ext/mysqli) extension.
Can someone explain this to me? Thanks.
User avatar
shiflett
Forum Contributor
Posts: 124
Joined: Sun Feb 06, 2005 11:22 am

Post by shiflett »

matthijs wrote:But then Ilia points out the same can happen with mysql_real_escape_string, in certain situations.
The "certain situation" is a bit contrived, and I'm not sure that MySQL intends the behavior. What Ilia wanted to add was that setting the character encoding with a query rather than with my.cnf doesn't affect mysql_real_escape_string(). If you don't do the following, you've nothing to worry about:

Code: Select all

mysql_query("SET CHARACTER SET 'GBK'");
In fact, even the situation I brought up only applies to multi-byte character sets. If you're not developing an application for an international audience, you won't notice a difference between addslashes() and mysql_real_escape_string(). However, there is a difference, and it does matter to some people.

I tried to summarize everything:
To avoid this type of vulnerability, use mysql_real_escape_string(), bound parameters, or any of the major database abstraction libraries.
Hope that helps clarify the discussion a bit. :-)
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

I don't mean to be rude, but the guy who started the addslashes() vs mysql_real_escape_string() thread couldn't have looked far..
Returns a string with backslashes before characters that need to be quoted in database queries etc. These characters are single quote ('), double quote ("), backslash (\) and NUL (the NULL byte).
http://www.php.net/manual/en/function.addslashes.php
Escapes special characters in the unescaped_string, taking into account the current character set of the connection so that it is safe to place it in a mysql_query(). If binary data is to be inserted, this function must be used.

mysql_real_escape_string() calls MySQL's library function mysql_real_escape_string, which prepends backslashes to the following characters: \x00, \n, \r, \, ', " and \x1a.
http://www.php.net/manual/en/function.m ... string.php

:?
User avatar
shiflett
Forum Contributor
Posts: 124
Joined: Sun Feb 06, 2005 11:22 am

Post by shiflett »

Jenk wrote:I don't mean to be rude, but the guy who started the addslashes() vs mysql_real_escape_string() thread couldn't have looked far.
It's not just one person, and some documentation can be misleading:

http://dev.mysql.com/doc/refman/5.0/en/ ... tring.html
Strictly speaking, MySQL requires only that backslash and the quote character used to quote the string in the query be escaped. This function quotes the other characters to make them easier to read in log files.
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

I know it's not just the one guy, but it just occured that it was a little silly for them to post "addslashes() and mysql_real_escape_string() are an equal solution to cleansing data before it's inserted in a database."

When atleast some of the difference is highlighted upon reading the php manual. :)

All other points aside regarding injection, I'd take the logs as a key point.. wouldn't want some script kiddy messing about with the format of my reports now ;)
User avatar
shiflett
Forum Contributor
Posts: 124
Joined: Sun Feb 06, 2005 11:22 am

Post by shiflett »

Jenk wrote:I know it's not just the one guy, but it just occured that it was a little silly for them to post "addslashes() and mysql_real_escape_string() are an equal solution to cleansing data before it's inserted in a database."
I agree. This type of thing used to bother me a lot, but I've mellowed as I've gotten older. :-) The issue I take is when people who, uncertain of a particular topic, decide to challenge the status quo with hollow statements of fact. I think this is what Maugrim_The_Reaper was specifically addressing.

I should rephrase by saying that I appreciate people who challenge me - that's perfectly fine. I just wish people wouldn't state with certainty that I'm wrong when they're unsure. The "you're wrong until you prove to me that you're right" approach is disrespectful, in my opinion.

Anyway, I'll stop before I ramble on and annoy people. :-)
AGISB
Forum Contributor
Posts: 422
Joined: Fri Jul 09, 2004 1:23 am

Post by AGISB »

Who in their right mind can justify to only use addslashes anylonger for escaping a Database query if someone has proven that at least in some instance a security hole is there? In the future new versions of the DB might use internationalisation in a whole different way and your application might have a security hole all of a sudden.


I would even go further and state the following: Inserting data into a database requires a whitelist approach. Certain chars have nothing to do inside a username or password string. So filter them out. Problem solved. If you use addslashes or mysql_real_escape_string afterwards to make sure that the database saves the data right doesn't matter then.
Post Reply