I have already created and refined both registration and login systems, However I am lead to believe the tricky part comes when you are creating a session. As far as I know this is due to both Hijacking and fixation. Which in all honesty I don't fully understand the concept of.

I have browsed the internet all day and done a large amount of research. he following articles have been useful to me so far:

I am using the $_SESSION['valid'] variable as a simple the user is logged in confirmation. I am assigning the session to a single User Agent and IP Address. I see how the User Agent is fairly useless as it can be easily forged but I feel it's better to have it rather than not have it.

It's apparent to me users with changing/dynamic ip's would be logged out... but everyone who has told me this has failed to present me with a better option, or explain it to me better.

I am then using the following function to match the current user agent to the original user agent logged at the creation of the session.

At the moment due to my lack of understanding, I don't know where I am vulnerable from and or where I can go and make improvements. This is all very new to me and at the moment at least I am trying to learn this in my spare time. It's all new to me, and I want to ensure the best work.

using the client IP in the session fingerprint is a recipe for malfunctioning sessions. IPs can change, for many legit reasons. think about mobile users, among others.
–
JaccoNov 13 '12 at 11:25

Wow people are still using md5 in a security context? Some people just want to watch the world burn.
–
rookNov 13 '12 at 15:58

PHPs session ID generation has been shown to be weak. That said you can improve the resulting IDs a little (to help prevent brute force hijacks), by using the session.hash_function and session.hash_bits_per_character ini settings. Creating your own session IDs from a purely random source would still be preferred though.
–
LeighNov 14 '12 at 11:55

3 Answers
3

First and foremost, STOP USING MD5! It is a broken hash function, and its been broken for many years. Also you have to use an hmac, calling md5 directly is vulnerable to a length extension attack.

Testing the ip address is problematic because this value can change if the user is behind a load balancer, which is commonly used by universes and corporate offices.

The attacker will always have the user-agent, and this value is very easy to brute force. Testing this value is in no way shape or form a "security measure". Its a lot like having a variable is_attacker=no and making sure this value is "no", which is A JOKE! When I see a programmer doing this I smell blood, if they actually think this helps improve security then they have likely made other mistakes.

I was just using MD5 for simplicity, I would never use it in production. I am going to switch out to something stronger soon, any recommendations I am thinking SHA-512 or BCrypt... That's what I have been told. I'll give the suggestions you gave above a go. Thanks for the help.
–
TuKriticalNov 13 '12 at 16:30

1

@TuKritical How about you just not check the UA and IP, and then you don't need to use a hash function. Every time i see someone checking the UA in a pentest i think the programmer is a naive. It's encouraging, its the smell of blood to a shark.
–
rookNov 13 '12 at 16:53

2

@TuKritical no, thats the problem, your not doing anything to prevent session hijacking. The weakness is that you think you are. The only way to prevent this attack is to stop it from happening in the first place. Thats why we have cookie flags and https.
–
rookNov 13 '12 at 17:10

2

@Brendan Long its trivial to avoid and its two cryptographic violations. sha1 is a few more bytes, but an hmac is really what he needs, otherwise its vulnerable to a length extension attack.
–
rookNov 13 '12 at 18:39

1

I agree with Rook - this reeks of security theatre. You're making it look like you're making it secure, but it doesn't provide any benefit. I do think that tying sessions to IPs increases the barrier to entry significantly though.
–
PolynomialNov 14 '12 at 8:32

I would store the session info in a database and reference it by a token stored in a cookie. you don't need the "valid" var anymore since the database would cross reference the token and make sure it is still within the allowed lifetime.

You can choose to work directly with the cookie or use the cookie to set session info if you want. Session is not really necessary. Simpler the better though.

Your token can be generated when the user logs in and if desired regenerated on any page load - if you want to keep it cycling.

user agent and remote addr are not a good base for a token since they can be very common for many people. Think like a proxy for a college or something. Everyone will have the same ip.
you could create any random string and it would suffice so long as it's unique.

Whatever you choose to do, the basic idea is to keep the amount of info in your session or cookies down to a minimum and as obscure as possible. It would be difficult to happen to guess a valid token if you set the expiration to a normal time. Plus you could keep track of failed attempts and block out attempts that pile up over a short time frame.

You can also boot people if one account tries to log in from multiple locations. In that case, user agent and IP may help to identify simultaneous access attempts.

So use a database to reference a token, remove the valid var, going to add a random string to the token to ensure each user has a unique token. Set a expiration to the session. Use the UA and the IP to block out simultaneous logins... Am I forgetting anything?
–
TuKriticalNov 13 '12 at 1:37

What if the session expires and someone has the random string from the cookie? Blocking out by IP is not secure, and to my knowledge, neither is the cookie.
–
KaoNov 13 '12 at 8:07

I am currently in a similar position, looking at all the different options and repercussions of session security and it is quite a challenge balancing usability and security with potential weakness on the server, in transport and on the client. SSL is the best way to protect the transport layer and a secure setting of cookies assists with the client protection.

In terms of using the $Server Remote Address there are problems. For some users this value does change quite regularly and a user having to reenter their password each time does get annoying. For other users that are on a fixed IP address or range of IP address this can help make it tougher to crack, especially if SSL is also used. Remote IP is not a magic bullet in terms of security, but nothing is in cyber space. Combining multiple security methods all helps. Trying to build up a user profile with which $server variables remain constant and which change can assist with knowing when to log out the user and ask for the password in a more timely and user friendly way. If the user is logged out then any brute force attempt at the other $server variables like user agent or language encoding will just have to wait until the real user logs back in.

How you handle multiple log in sources also has its problems, what if the user wants to check in from work, at home or while out and about? By having some information about how the user uses their account in the early days, it can help knowing when to close the session and ask for the password again later on. As administrators and even with perfect cyber security, how the users manage their passwords will continue to be a problem and require some facility to go in and clean up the mess when it happens.