6

I'm developing a website and I'm trying to secure the connection part.

I used the addslashes function on $login to stop SQL injection but some friends told me that's not enough security. However, they didn't show me how to exploit this vulnerability.

How can I / could you break this code? How can I secure it?

<?php

    if ( isset($_POST) && (!empty($_POST['login'])) && (!empty($_POST['password'])) )
    {
        extract($_POST);
        $sql = "SELECT pseudo, sex, city, pwd FROM auth WHERE pseudo = '".addslashes($login)."'";
        $req = mysql_query($sql) or die('Erreur SQL');
        if (mysql_num_rows($req) > 0)
        {
            $data = mysql_fetch_assoc($req);
            if ($password == $data['pwd'])
            {
                $loginOK = true;
            }
        }
    }
    ?>
5
  • 2
    google addslashes VS mysql_real_escape_string : sitepoint.com/forums/showthread.php?t=337881 Commented Jan 20, 2011 at 16:20
  • There're many outdated tutorials out there that suggest addslashes() as a mechanism to escape stuff in SQL queries. If you are learning from one of those, I suggest you try to find something more up-to-date and accurate. Also, extract($_POST) is a nice example of vulnerability; don't do it! BTW, welcome to StackOverflow. Commented Jan 20, 2011 at 16:20
  • almost exact duplicate of stackoverflow.com/questions/60174/…
    – jamesbtate
    Commented Jan 20, 2011 at 16:20
  • that's pretty enough as long as you're using single-byte or utb-8 encoding. Commented Jan 20, 2011 at 16:21
  • 2
    However you're suffering from much worst injection, out of extract() function. What if there will be loginOk field in the form?.. Commented Jan 20, 2011 at 16:22

6 Answers 6

14

You should use mysql_real_escape_string for escaping string input parameters in a query. Use type casting to sanitize numeric parameters and whitelisting to sanitize identifiers.

In the referenced PHP page, there is an example of a sql injection in a login form.

A better solution would be to use prepared statements, you can do this by using PDO or mysqli.

20
  • ok, but could you give me an example of SQL injection for this code? I don't understand how can I break this code whereas I'm escaping quotes in it.
    – Tom-pouce
    Commented Jan 20, 2011 at 16:18
  • @Tom: check out This article on the subject
    – ircmaxell
    Commented Jan 20, 2011 at 16:20
  • mysql_real_escape_string alone IS NOT ENOUGH to substitute addlashes. Most likely in your code there is no difference between these functions Commented Jan 20, 2011 at 16:24
  • I've already seen this article. But I didn't success to break my code. Could you give me examples?
    – Tom-pouce
    Commented Jan 20, 2011 at 16:24
  • 1
    You are wrong abut "not vulnerable to injections at all". What if you're going to make a query "ORDER BY $sort_field". and still, without mysql_set_charset your mysql_real_escape_string will behave exactly the same as addslashes. Commented Jan 20, 2011 at 16:32
5

You are storing your passwords in plaintext! That's a major security issue if ever I saw one. What to do about that: at least use a (per-user) salted hash of the password, as seen e.g. here.

1
  • (feel free to edit to a better explanation of hashing and salting, this is one I've found by quickly searching SO) Commented Jan 20, 2011 at 16:37
2

Use:

mysql_real_escape_string($inputToClean);
2
  • this function being called alone can do nothing better than addslashes Commented Jan 20, 2011 at 16:24
  • 1
    @Col. Shrapnel: It is an epsilon better than addslashes (Unicode representations and whatnot) - but you are right that a programmer using it as a abracadabra-it-is-now-secure magic dust is no safer than with addslashes. Commented Jan 20, 2011 at 16:36
2

There's another gaping security hole - extract. It may save you from typing a few characters, but opens up holes too numerous to mention, for it will overwrite any global variables.

What happens if I post this?

$_POST {
    'login' => 'Admin',
    'loginOK' => 1
}

Guess what, $loginOK is now == 1 , and I'll be logged in as Admin.

Save yourself a lot of grief later, and just use the variables you want to use, instead of relying on the horrible hack that is extract.

1
  • @Tom-pouce: You're welcome. btw, that's eeexactly the case against extract - it creates variables "out of thin air" (I've been bitten by this, and it is really hard to debug). Commented Jan 20, 2011 at 16:41
2

Apart from the usage of addslashes(), these are some random issues found in this code:

  • isset($_POST) is always TRUE, unless you run it from the command line. You can probably remove it.
  • empty() is very tricky. For instance, if $password = '0' then empty($password) is TRUE.
  • You can do this: if( isset($_POST['login']) && $_POST['login']!='' ){}
  • extract($_POST) is a huge vulnerability: anyone can set variables in your code from outside.
  • $password == $data['pwd'] suggests that you are storing plain text passwords in your database. That's a terrible practice. Google for "salted password".
  • You can also do $loginOK = $password == $data['pwd'];. Do you realise why? ;-)
1

Rather than addslashes you should use mysql_real_escape_string.

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