Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

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:

How to Create Bulletproof Sessions

PHP Security Guide: Sessions

So far I have very little, I could really use some help and guidance. This is some of what I have got so far:

When a users password is matched and they have confirmed their identity using the login script the following function is called. The session is started at the top of the login script.

function begin_session()
{
session_regenerate_id();
$_SESSION['valid'] = 1;
$_SESSION['fingerprint'] = md5($_SERVER['HTTP_USER_AGENT'] . $_SERVER['REMOTE_ADDR']);
} 

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.

    function authenticate()
{
session_start();
if ($_SESSION['fingerprint'] != md5($_SERVER['HTTP_USER_AGENT'] . $_SERVER['REMOTE_ADDR'])) {       
    session_destroy();
echo 'die';
    header('Location: http://website login page/');
    exit();     
}
}

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.

share|improve this question

migrated from stackoverflow.com Nov 13 '12 at 8:03

This question came from our site for professional and enthusiast programmers.

    
I am planning for it to be used in something a little short of that level. The best is all I want. So any advice will help. –  TuKritical Nov 13 '12 at 1:24
1  
I'd recommend you watch this talk from DEFCON 18 youtube.com/watch?v=YDW7kobM6Ik - The first part is about PHP sessions. –  Gant Nov 13 '12 at 8:19
2  
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. –  Jacco Nov 13 '12 at 11:25
    
Wow people are still using md5 in a security context? Some people just want to watch the world burn. –  Rook Nov 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. –  Leigh Nov 14 '12 at 11:55
add comment

3 Answers

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.

Set your php session configurations as follows:

session.cookie_httponly = 1 (helps mitigate xss)
session.session.use_only_cookies = 1 (prevents session fixation)
session.entropy_file = "/dev/urandom" (better entropy source)
session.cookie_lifetime = 0  (smaller exploitation window for xss/csrf/clickjacking...)
session.cookie_secure = 1 (owasp a9 violations)
share|improve this answer
    
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. –  TuKritical Nov 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. –  Rook Nov 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. –  Rook Nov 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. –  Rook Nov 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. –  Polynomial Nov 14 '12 at 8:32
show 2 more comments

This may just be personal opinion...

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.

share|improve this answer
    
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? –  TuKritical Nov 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. –  Kao Nov 13 '12 at 8:07
add comment

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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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