Take the 2-minute tour ×

EDIT: Please view the revised question instead

The admin area has special access to the database (modifying orders, etc).

To help explain, I drew a diagram, so here is my process:

PHP Login System Diagram


  • I left out having a timed session from the diagram for sake of simplicity of the diagram, but I will actually set a last_login date in the database so that inactive sessions can be logged out automatically.
  • Passwords are stored with AES encryption
  • The secret key or "salt" is hard-coded out of the web root folder
  • All database queries are parameterized.

But what are your thoughts about this process? Am I missing anything out?

share|improve this question
Using AES for encrypting password isn't a good idea –  Andrey Botalov Apr 25 '12 at 21:14
@Ozzy The purpose of password hashing is to protect the passwords even if your database gets hacked. –  CodesInChaos Apr 25 '12 at 21:25
@Ozzy, where have you seen in MySQL docs recommendation to use AES_ENCRYPT for encrypting password? I see recommendation to use MD5 or SHA2 here –  Andrey Botalov Apr 25 '12 at 21:32
@Ozzy Nobody said that you should use md5. We typically recommend bcrypt or PBKDF2. You can keep part of the salt in a separate location(the config file) as a defense-in-depth measure. Such a scheme offers several advantages, and no disadvantage over encryption. So there is simply no reason to use encryption. –  CodesInChaos Apr 25 '12 at 21:46
@CodeInChaos Okay so I'll have to change the members table to store a hash, and I'll look into bcrypt and PBKDF2, so thanks. How about the authentication of the session (see diagram)? Am I doing it right? –  user9360 Apr 25 '12 at 21:49
show 12 more comments

3 Answers

up vote 8 down vote accepted

Don't implement your own session handler. Use $_SESSION, it was written and audited by people who very good understanding security. I don't even know the intricacies of how your session handler works, but based on the little information you have given us its insecure.

SQL Injection is useful to obtain data from the database. We HASH passwords because in the event of an attacker obtaining this data, they will be forced to crack the hash before its useful. However, in your case, it doesn't matter that you are vulnerable to CWE-257, the attacker can just pull the session id out of the database, and use that to authenticate.

I could also gain admin access because you have made no mention of OWASP a9 - Insufficient Transport Layer Protection. You are also vulnerable to Clickjacking, every web app is by default. CSRF or "session riding" was already mentioned.

Enable the security flags "httponly", "secure". You can do this for $_SESSION by configuring PHP.

A defense in depth strategy is to plan on failure and limit the access your administrator has. Don't allow file upload or code execution. This is the number 1 reason why Wordpress instances get hacked, once you have admin on a Wordpress site, you have remote code execution on the server. Wordpress also implemented their own session handler at one point, and you guessed it, it was very insecure.

share|improve this answer
Okay, you have given me a lot to think about, so big thanks! I suppose it's silly me trying to cover all of these aspects I have so little knowledge of myself - so I suppose it is best to use a package library for security? –  user9360 Apr 26 '12 at 0:44
@Ozzy probably, but you can't address everything with a library. Never re-invent the wheel, use whats given to you by the platform. That's not a security principle, that's true for all engineering problems. –  Rook Apr 26 '12 at 0:48
+1 @Rook! I totally forgot about session management. –  George Bailey Apr 26 '12 at 14:01
@Ozzy, Maybe you should just post a separate question and use the comments for linking to that question? –  George Bailey Apr 26 '12 at 14:18
@GeorgeBailey It's up here: security.stackexchange.com/questions/14215/… –  user9360 Apr 26 '12 at 21:33
add comment
  1. Passwords should be hashed, not encrypted. The most preferable routine would probably be bcrypt. The repetition parameter should be adjusted so hashing of the passwords takes... say... 200 milliseconds, to slow down offline brute force of the password. (offline meaning your system was compromised and the hash was obtained) (200 milliseconds means your hardware, rented clouds or clusters could run the hashes much faster)

  2. The diagram looks reasonable to me.

Additional suggestions

  • Prevent online brute force. (online meaning using your php programs, only would be used they don't have a copy of the hash (as in, if they couldn't use offline brute force))

  • Prevent CSRF attacks: any call to your program that has side effects should require a special random key that came from an earlier request with the same cookie, this is to prevent you from visiting a web page that has an invisible form with an action pointing to your website's delete command, that is executed immediately by javascript. Or in the case of get requests that cause side effects, you may only need to be viewing an email that has an image tag to be attacked in this way.

  • Prevent XSS attacks: Someone might inject JavaScript or HTML into some columns that causes external JavaScript to execute, possibly sending off cookies, current page content, or any other content on your site using your session, and it is possible stuff could be modified/deleted.

  • The Session Management described has shortcomings. See Rook's answer.

This is not an exhaustive list.

I recommend looking around in this IT Security website. It really expands your knowledge of security.

Disclaimer: I am a programmer in multiple languages, but not PHP. I am a security enthusiast, but not necessarily an expert.

share|improve this answer
Thanks for your answer. To prevent online brute force is simply setting a number of failed-login attemps which temporarily blocks an account right? –  user9360 Apr 25 '12 at 23:29
Oh and thanks for the mention of the CSRF attacks, thats the main thing I was worried about which I didn't know... a vulnerability of trusting a user from their cookie data, other than XSS attacks which I already read about. –  user9360 Apr 25 '12 at 23:40
Sounds reasonable. There are many ways to prevent online brute force. You may want to block the IP first, and only block the whole account if there are limits reached on several IPs. You may also want to do a silent block, so they keep trying, without knowing they reached a limit. That can be really annoying to legit users so unless you wait until ~10 failures. Suggested Countermeasures to Online Brute Force is not a question I have found yet. I did find this. Maybe you should ask your own, as that only touches on it. –  George Bailey Apr 26 '12 at 13:58
Haha thanks @George, I actually already read that question and all of the answers :). I think most people use captchas after 2 or 3 failed log-in attempts - probably the most effective way of stopping brute force attacks. –  user9360 Apr 26 '12 at 14:11
add comment

Don't forget to include non-technical controls as well, such as segregation of duties (requiring more than one admin's approval to make critical changes) and having an audit trail for accountability.

share|improve this answer
add comment

Your Answer

