While making my new site i needed new login script, so i can feel comfortable with my data. I made such scripts earlier, but who knew how secure they were. Hoping to find some anwer on the web i found such a tutorial that calls itself ‘super secure login script’. You can find it in this link
I wonder how secure it really is, and what kind of threats is it vulnerable.
I also found in code lines like this:
// Create Second Token
$tokenId = rand(10000, 9999999);
$query2 = “update users set tokenid = $tokenId where userid = ‘$_SESSION[userid]‘”;
$result2 = mysql_query ($query2);
$_SESSION['token_id'] = $tokenId;
How should it work? What is it preventing from? Should i compare $_SESSION[‘token_id’] with something later or what?
The code you posted is simply creating a random number, then storing it on the user record in the users database table, then storing it in the session.
Based on the link provided, the token or random number doesn’t actually get used for anything at all. You’ll have to ask the developer for the meaning of that.
I wouldn’t recommend the login script you linked to for these reasons:
1) The way it escapes user input to avoid SQL Injection
Here is the function that is used:
The above function has some problems. The biggest being that if it finds that
mysql_real_escape_string()does not exist, it falls back tomysql_escape_string(). You should never fall back to mysql_escape_string(). If mysql_real_escape_string() is not available and you’re relying on it to avoid SQL Injection, your application should stop.The other problem with this is it is uses
strip_tags(). Escaping for SQL Injection and escaping/encoding for XSS are two different things and shouldn’t be combined into one.I suggest using MySQLi prepared statements or PDO parameterised queries instead of this function, to avoid SQL Injection.
To avoid XSS, use
htmlentities()whenever content from the database (or direct user input) is printed out which originated from user input.2) This is bad practice
3) PHP logic and HTML are mixed in together, no effort is made to separate them.
4) CAPTCHA on the login form. This is just going to make users unhappy. Usually there is no need for a CAPTCHA on a login form.
Edit – here I’ve responded to some of your points in the comments.
Author’s intention for token
It’s anyone’s guess really but perhaps the random number was meant to be used in a password reset link.
For that sort of thing, hashing the random number/string is usually done rather than keeping a short random number. Also mt_rand() is better than rand().
Using a single function for SQLi escaping and XSS prevention
This is a bad idea because they are two very different things. Escaping for SQLi is done inbound to the database, XSS prevention should be done outbound if you see what I mean.
When storing data in the database, it is usually best stored in raw form rather than having it had strip_tags() or htmlentities(). What if at some point you want to allow HTML to be entered into the database for any reason?
The XSS prevention should be done as the data comes out of the database and onto the page or where ever it goes to. What if you want to output the data to another medium other than HTML, like XML or to a web service, and you’ve already processed it for HTML.
A single function for both XSS and SQLi doesn’t make the code cleaner, it applies processes to data that don’t need to be applied at that time.
Look at any popular framework such as Zend, or CMS such as WordPress, Joomla etc. None of them use a single function for both SQLi and XSS.
Mixing PHP and HTML
Yes you’re right it isn’t going to affect security but it just looks terrible. It is hard to read, hard to maintain, hard to extend and update, and definately remains a reason I would not recommend it.
Quotes in
$_SESSION['userid']Using
$_SESSION[userid]inside a query to solve the problem of the query breaking due to quotes, shows lack of knowledge/experience.You can use quotes, you just need to concatenate the variable into the query like
Of course you need to escape for SQLi (preferable using parameterised queries) if you’re unsure of the contents of the variable.
CAPTCHA
CAPTCHA is great when used in the right places. A login form like this is not one of them. You could use a CAPTCHA after X failed attempts (as Google do), but not like this where it is required all of the time.
There are other ways of dealing with brute force login attempts, several answers here on SO.
Another point that I didn’t mention is the password hashing. That is using SHA1 with no salt, which is not very strong. I would use SHA256 or higher and use a salt for passwords.