The Real Solution To Patching 2
I've done this challenge a long time ago and I pretty much disagree with the solution.
Just a little background that most people don't know about this addslashes exploit. What this exploit point out is that when you use multi-bytes encoding, slashes added to quote could be confuse with the rest of the data.
The way mysql_real_escape_string work is the same as addslashes except that it add slashes for more caracter that could affect the query.
So basicly, by saying addslashes ain't the right answer, mysql_real_escape_string shoudn't be either. Both of them have security hole when you use multi-bytes encoding.
The actual solution to this problem is to separate the query from the data. In this way the data can't affect the query. In MySQL, this isn't possible, but it is possible with PDO (an extension that is install with PHP 5).
So the official solution is to use PDO and to separate the data from the query.
whats there is the right answer. your mission is to prevent the injection, you use mysql_real_escape_string, you prevent the injection. done, mission accomplished. yes, there are other ways of preventing it, but this way works, is commonly used, is efficient, and cant (as of yet) be bypassed. So STFU, if you dont like the challenge make your own.
I actually propose some challenge long time ago, but I never hear of them at all. What I propose was for javascript challenge, it was mainly an encryption that could be reverse not like the last one who is a brute force challenge. Also patching ain't really a good type of challenge since there is always more than one answer and many way to make them. They should should be validated by admin just like logical.
Also in the challenge, it clearly says that if you use str_replace, addslashes, it's bad while it's not. These method can be as effective as mysql_real_escape_string, so why is this challenge saying it's wrong ? (Edit: That what I reffer as the wrong answer)
Addslashes : 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).
(Taken from PHP.net)
Mysql_real_escape_string :
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.
(Taken from PHP.net)
Str_Replace :
str_replace(Array('\'','"'),Array('\\\'','\\"'));
All the 3 methods listed bellow do the same exact thing on the way single quote and double quote are going to be replaced. It's simply that addslashes and mysql_real_escape_string are more effective than the str_replace, but that doesn't mean the str_replace method won't fix the problem. It's a patching challenge not an optimizing problem.
I don't have much time right now, but I'm gonna show you that the proof of concept with the addslashes also apply to mysql_real_escape_string.
I made mistake, I remember there was a function that was vulnerable as addslashes, actually it's mysql_escape_string not mysql_real_escape_string. The only difference between those 2 is that mysql_real_escape_string communitate with the server to transfer some information for the charset. mysql_escape_string will do the exact same thing as addslashes, but mysql_real_escape_string won't.
<?php mysql_connect('server','user','pass'); mysql_select_db('db'); mysql_set_charset('gbk');
addslashes(chr(0xbf) .chr(0x27) .' OR 1=1 –'); // This is a working // mysql_escape_string(chr(0xbf) .chr(0x27) .' OR 1=1 –'); // This is working // mysql_real_escape_string(chr(0xbf) .chr(0x27) .' OR 1=1 –'); // This is not working // ?>
mysql_real_escape_string willl only consider the current setting so if during the script you change the charset, it will now become vulnerable.
Still that doesn't change the fact, prepare statement with PDO are a better solution.
If you don't want that 2 things have an effect on each other, don't put them together.