1

I have two versions of a website. The first one has no security precautions against sql injections. So if I try something like:

Username: hello_world
Password: ' or ' 1=1

I'll be signed in as the user hello_world.

The second version of the website escapes single quotes to two single quotes. So the first attack I used on the first version doesn't work. When I get a successful login on the first version, I get a response that says:

username = hello_world & password = %27%20or%20%27%201%3D1

So all of the special characters are being replaced by their hex value. When I try something like this:

Username = hello_world
Password = %27%20or%20%27%201%3D1

In the second version of the site, it doesn't work (because the % is being changed to its hex value).

Is there a way I can log in as the user hello_world?

NOTE: I do, in fact, have permission to perform tests on this site.

  • "The second version of the website escapes single quotes to two single quotes." What does that mean? ' -> "? – Tryth Feb 9 '15 at 6:57
  • It would be two single quotes together, like ' to ' and ' together. – Bob John Feb 9 '15 at 7:23
3

The second version of the website escapes single quotes to two single quotes.

Is there a way I can log in as the user hello_world?

Yes, because this kind of protection is not secure at all (I also would not call it escaping).

Attack

Imagine an attack like this:

Username: hello_world
Password: \' OR 1=1 #

Which would be transformed to:

Password: \'' OR 1=1 #

Which would probably look like this in a query:

SELECT * FROM users WHERE username='hello_world' AND password='\'' OR 1=1 #'

Which is then executed like this, because the comment (#) cuts of the rest of the query:

SELECT * FROM users WHERE username='hello_world' AND password='\'' OR 1=1 

So it checks if your password is \' or if 1=1 (which it does) to authenticate the user hello_world.

Further Damage

Note also that login bypass isn't the only attack that can be done here.

Data can also be retrieved via blind SQL injection (true = logged in, false = not logged in):

SELECT * FROM users WHERE username='hello_world' AND password='\'' OR ascii(substring((SELECT password FROM mysql.user LIMIT 0,1),1,1))<100
[ etc. ]

It is a noisy attack on a login page, but still, it could cause serious damage.

Prevention

Filtering is the worst kind of protection against SQL injections. Escaping (eg via mysqli_real_escape_string) is better, and using prepared statements is best (they are harder to mess up than escaping).

0

This depends on your understanding of "special characters". If you filter out every character that's not alphanumeric, you might be safe, but I can't answer a "yes" on this for sure.

Generally, it is not a good idea to implement your own security checks for database queries.
Instead, use built-in functions like mysql_real_escape_string() (if you're using PHP for example).
Also, you should use prepared statements. Those are SQL queries with placeholders for user input. This guarantees that user input is not interpreted as a SQL keyword/function/separator.

Not the answer you're looking for? Browse other questions tagged or ask your own question.