2

I've started learning PHP by myself, and in the beginning, I would often choose the simplest way to do a task instead of the best way. Now that I'm developing important websites that need to be 100% secure, I hit this dillema,

I'm using cookies on my main page, to store the login session. Basically, the username and the hashed password is stored in a cookie and is loaded and checked against the database any time the user visits a mustbeloggedin page. For my main page, I'm using md5. Not because I want to, but because I have to. I know that poses a great security risk for the user because a keylog attack can basically freely take his password.

On this new website, I'm gonna use sha256, so that shouldn't be an issue. Here's my question: what other security issues does storing this kind of data in a cookie and not in a session pose?

Here's mine:

  • Anyone with physical access to the computer can get the user's hash and store it for later use, by manually setting his cookie.

  • Any infected computer does the same as the above

  • Data is loaded, parsed, checked every load (not a security issue but still optimization-wise, it's not very good, but I don't mind that)

Anything else?

Does the domain variable inside the cookie make it secure enough not to be read by any other site?

Edit:: I'm also reading about someone intercepting the data being sent from a client to the server. How are sessions different than this? If I store a session , can't the identifier cookie still be hijacked and used by someone else? Would also adding an ip address to the cookie, then when validating the cookie, also check the IP address and if it's different then print the login form again help?

Cârnăciov
  • 1,079
  • 1
  • 10
  • 21
  • 3
    "*I'm developing important websites that need to be 100% secure*" + "*I'm using cookies to store the login session - the username and the hashed password is stored in a cookie*" + "*I'm using MD5*" = Disaster! First question is, why do you "need" to "store" passwords in cookies or sessions? You should not know what the password is, nor "remove" it from the "secure" DB. A script checks login, does password(hashed+salt) == db password? – James Mar 17 '15 at 07:34
  • I'll probaly switch the other site to sha256 too. ATM it's like this because the same database is used by a website AND a game where players log in, the game only supports md5 encryption. Your question and statement makes no sense, you're describing a login page and I'm describing about how the website knows you're logged in. The cookie has the username and the hashed password, not plain text password. – Cârnăciov Mar 17 '15 at 07:36
  • 100% security is an illusion. Even if you would know what you are doing. – Kai Mattern Mar 17 '15 at 07:36
  • @KaiMattern it's obviously a figure of speech, problems always show up in the runtime, but I don't want to start building this new site this way if it's wrong. But only if it's wrong because it's unsecure, not because it's not everyone's preference. Also, I'm asking if there are security issues with it except physical access to the computer or the computer being infected, because in either one of those cases anyone can do much more than steal the hash, so it's already a done deal. – Cârnăciov Mar 17 '15 at 07:41
  • FIrst: If the client computer is compromised, the connection is as well. – Kai Mattern Mar 17 '15 at 07:44
  • 1
    Second: Do not use simply the hashed pw. This makes replay attacks a breeze, as you have pointed out. You could use the pw only at authentication, then hand back a session identifier. This is only valid for some time after the last interaction with the server. Each interaction, you reset the time of last interaction, and check if the session is still valid. – Kai Mattern Mar 17 '15 at 07:44
  • You could also hand back a changed session identifier at each interaction, so that replay attacks won't work until the attacker works parallel to the user. And then it will disconnect the user, which makes the attack noticiable. Lots of stuff you could do. – Kai Mattern Mar 17 '15 at 07:44
  • Having database interaction at each interaction with the server is a small price to pay. And if you have a server that can hold sessions in memory, you could even eliminate that. By the way, reauthentication is part of the idea of REST web services. If done right, the performance impact is less than you might think. Most modern databases do a good job here at caching objects. – Kai Mattern Mar 17 '15 at 07:48
  • @aron9forever - I've responded and given you a bit more info in my answer – James Mar 17 '15 at 08:05

4 Answers4

3

It seems you are trying to make some improvements, but not enough really.

There should never be a need to store passwords in a cookie, session, array, or anything else.
The password should be in the database and not be taken out to chance further access to it, or manipulation of the data holder in some way.

Otherwise, your highly secured database with hashes and salts on passwords, is only as secure as the framework/scripts and variable or cookie you store the password in (which is less secure than the aforementioned DB setup)!

From your comment:

Your question and statement makes no sense, you're describing a login page and I'm describing about how the website knows you're logged in. The cookie has the username and the hashed password, not plain text password

So you store Bob's password in a cookie, with hash etc.
I steal Bob's password cookie. It's hashed, so safe right?

Ok, so I (James) use it on your site. How does you site know I am James, not Bob? It cannot.
It checks the cookie I stole, and password hash/salt/whatever you do match in your checks (otherwise it wouldn't for Bob either so would be useless).
It thinks I am Bob.

So now you start to check other things, if I have another cookie, perhaps username.
I have already stolen that.
So now your site looks at my cookies, sees a username and password, checks them, and says "welcome Bob, here's your personal/sensitive details, do as you wish...".

Passwords stay in the database!

You could try checking user agent, IP, and a load of other arguably less than useful/sometimes useful things etc, but these are things you can do "as well" as password+has+salt, and at the same time not store passwords in cookies or Sessions.
If your only methods to stop a hacker from using that stolen golden password cookie (hashed or not) is to check user agent, IP, and something else that can easily be faked, then your site is not secure.

Also, anytime the user needs to do something like change their password or email address, or check their whatever sensitive data on your site, you ask them to re-type their password.

Possibly resetting their cookies/hash/hash+salt stored in the DB, but depends on scenario really.

EDIT {
Use a cookie to store the Session reference, and any sensitive data in the Session.
Again, what you should store in the session depends on what data it is, if you run your own server, or shared, etc. Shared hosting can have bad config, opening up other security issues, even extending Session security issues.
(Info is in the links below - as said in comments, reading is your friend ATM - and then some evaluating and considerations of your specific needs)
}

Here is some serious reading for you:

First, your MD5 and even SHA256 are not secure:
http://php.net/manual/en/faq.passwords.php#faq.passwords.fasthash

Hashing algorithms such as MD5, SHA1 and SHA256 are designed to be very fast and efficient. With modern techniques and computer equipment, it has become trivial to "brute force" the output of these algorithms, in order to determine the original input.

Because of how quickly a modern computer can "reverse" these hashing algorithms, many security professionals strongly suggest against their use for password hashing.

Also read the link for that quote - the bit about how you should hash, and the bit about salts.
Also, importantly, read about how to correctly store salts and hashes. There is a LOT of BAD advice out there which is misleading to the point you end up with barely any more security than if you just used MD5.
Storing the salt in the DB with the hashed password is fine, just also use unique salts etc (it's all there in the link, about mcrypt/blowfish etc)


A must read, even if you only take bits from it (and even if you ignore the rest of my answer):
The definitive guide to form-based website authentication

Faking Session/Cookies?

More reading:
What is the best way to prevent session hijacking?

Also read about:

Session fixation; Session sidejacking; Cross-site scripting;


And again, given you stated this:

Now that I'm developing important websites that need to be 100% secure

You should really spend a lot of time reading about all these things.
Cookie/session hijacking is real, and generally simple (script kiddie stuff). If you want to produce secure websites and applications, you really need to learn about quite a few attack methods, preventions, etc.

Best way is read the links I've given, then any "branches" which stem from that read about them too.
Eventually you'll have a larger picture of the vast range of security concerns and resolves to them.

Community
  • 1
  • 1
James
  • 4,317
  • 4
  • 33
  • 45
  • And what's the difference if you set your cookie to contain bob and his hash ; or set your cookie to contain his session id, use the same agent and also add any other crap you find inside his cookie? Your post is very well written , and I thank you for that. I've already read most of the links you posted, but I'll take a look at everything again and assimilate everything posted. For some reason, you're the only one that understood I'm not planning on using MD5 and didn't ciclebash me for it because everyone on the internet does, so thanks again. – Cârnăciov Mar 17 '15 at 08:12
  • Might I add that I have all the different security measures generally recommended(eg not printing if user or password is wrong, just saying wrong credentials) , I have recaptcha set up and the form can't be submitted in any way without doing the captcha, any change of account info requires password confirmation and e-mail confirmation afterwards. All I wanted to know is if there's any base - level security issues with cookies, not wrong implementations. – Cârnăciov Mar 17 '15 at 08:16
  • Basically, you should use a cookie to store a reference to a Session, but nothing more. And Sessions can be hijacked (lot harder than cookies) but whether this is a concern is again down to your scenario - are you running a bank? What data is stored etc. Do you run your own server/shared hosting sharing a tmp dir for sessions, bad shared hosting setup means possible "other" security issues. There is no simple and definitive answer really, as there are a lot of concerns which need consideration and addressing. There's a fair bit to learn, unfortunately, so reading is your friend at the moment. – James Mar 17 '15 at 08:20
  • I'm building a game hosting service website and server management on my own dedicated server. That means any configuration is up to me. I'm not scared of the potential damage being dealt to a client, because it's minimal and can be easily reversed , I'm just scared of getting a bad image because a security breach. – Cârnăciov Mar 17 '15 at 08:22
  • Well, server config is up to you which brings different pros and cons - and depending on your current knowledge, may be more reading. "*I'm not scared of the potential damage being dealt to a client, because it's minimal and can be easily reversed*" Depends on what happens. Never presume it will be something simple that can be reversed. All sorts of things can come from a breach - e.g. they get client logins from the breach, which they used on their own websites/other places or many other potentials. Hackers easily find other "things" *you* never thought about. Hackers are like that. – James Mar 17 '15 at 08:36
  • alright, I read everything, again, most of these stuff I already knew. Here's what I've come up with: I will continue storing the username and password in the cookie, but I will also hash the username on registration, and save the hashed username and hashed password. I will purchase a SSL certificate for my website to encrypt and prevent sniffers from hijacking a session. I will also add a "last IP" verification and relogin if the ip adresses don't match. Recaptcha will stay in place to disable bruteforce attacks. Secure 15 character number and symbol pass will be enfeorced. – Cârnăciov Mar 18 '15 at 08:08
  • I can fake my IP to anything I want it to be. I can steal someone's cookies. So I get someone who's logged into your site, to come to my (bad) site and steal their cookie, and get their IP. I set my IP to theirs, put their cookies where mine are stored, come to your site. Your site checks my IP - OK - checks my cookies - OK.... Just don't store password in cookies. Not username really, but certainly not password and certainly not as some way to ID if a user is logged in. Even checking user agent or IP etc - I can fake those! – James Mar 18 '15 at 18:26
  • In fact, it's not really "don't store password in cookies" - it's STRICTLY "There should never be a need to *store* password *anywhere* away from the secure database" - leave it in there and check it with your secure password check script whenever required. - Ask yourself this - for what purpose do you want the password in the cookie? When you answer that, you will see that it is not necessary as there is a better approach to it all. If you need me to comment am happy to do so. – James Mar 18 '15 at 18:30
  • And if you are going to purchase an SSL, then using Sessions it the way to go! (then cookies are only a reference holder to the Session). But still, password in cookies is not necessary or advised. – James Mar 18 '15 at 19:46
  • I don't get it man, the way you put it, you could also steal the session identification cookie. Doesn't setting a domain to a cookie make it only available to said domain? – Cârnăciov Mar 26 '15 at 13:29
  • Maybe we went of track. Cookies are not secure. Don't store passwords in them, hashed, encrypted, with salts, or otherwise. That's it really. When they fill out login form, check their details in the DB, if ok login them in by setting a $_SESSION to identify them. When they go to a page, check the session is set etc - ie whatever security approaches you feel is necessary for your scenario - Check session IP which matches their IP (not 100% reliable, but fairly) etc. The main point I was making, is there is no need to store passwords outside the DB. Why do you want/need password in cookies? – James Mar 26 '15 at 14:26
1

Some takeaways for cookies.

You want to limit any sensitive information saved within as it is not secure.

Cookies are perfect for session ids which you can then use to query your database and check if it is expired, matches an ip, matches user-agent and any other security/validation checks you want to do before you route to relogin or resume session.

http://php.net/manual/en/features.cookies.php

You mentioned user authentication. Most encryption protocols can be broken by using and md5 is considered 'broken' at this point due to completeness of lookup tables with all the hashes and the slight variations between hashes.

How can I make MD5 more secure? Or is it really necessary?

Salting your hash is crucial which adds another layer of security as is additional cdn/server restrictions to block/restrict brute force attacks:

https://crackstation.net/hashing-security.htm

http://www.cs.virginia.edu/~csadmin/gen_support/brute_force.php

If one is overly paranoid you can implement two factor authentication ( expensive? ):

https://isc.sans.edu/forums/diary/Implementing+two+Factor+Authentication+on+the+Cheap/9580/ http://www.twilio.com/docs/howto/two-factor-authentication

Community
  • 1
  • 1
Vladimir Ramik
  • 1,935
  • 2
  • 11
  • 23
  • 1
    Okay, but you either read my post very fast or without paying attention. I know about collisions in m5d and also how every password up to 8 chars can be checked in 1 minute. The truth is that except the IP address, any data stored in the cookie can be used by the attacked. If he uses his user and hash, the only difference from using his sid , agent and anything else I could add is the risk of the user using the same password in multiple places. And the IP can also be used if the PC is infected, via a simple sock proxy – Cârnăciov Mar 17 '15 at 08:07
  • Session ids stored in cookies are not sensitive information. – Vladimir Ramik Mar 17 '15 at 08:17
  • We're talking about unauthorized people accessing someone's account , not them finding out his password is "ismellmyfarts" – Cârnăciov Mar 17 '15 at 08:18
1

Don't store any credentials in cookies. There is session cookie and that is enough. In your database you can create a table where you will store PHP session ID together with user id. It is enough to check user's login and password once, at the logging, to establish a session.

I was doing the same as you do: storing login, password and session id in cookies and had many problems - occasionally for unknown reasons the browser was not deleting one of those cookies, or I had problems with paths of those cookies. I had to develop very complicated methodology for assuring that those cookies are properly set and that all of them are present in a given moment - I tinkered with removing and adding those cookies manually in the browser and had to come up with new ways of preventing the problems arising from such activities, but I was always able to make up new way of breaking that down and had to come up with new mechanism for preventing that.

All of this mess stopped when I finally decided to leave only one cookie - session ID, which I authenticate before every session_start() call - you can check if such a session exists and even compare current browser footprint with previously saved one. It is then very simple to foresee bad scenarios - when somebody deletes this cookie, session is over, garbage collection will clean it up. If somebody changes it or adds fake one - you can compare it against your sessions table and not start a session. To have better control over the sessions, use session_set_save_handler functionality.

n-dru
  • 9,039
  • 2
  • 25
  • 39
0

There is a lot wrong with your chosen implementation.

the username and the hashed password is stored in a cookie

Don't do that. You should consider the content of cookies insecure.

and is loaded and checked against the database any time the user visits a mustbeloggedin page

There is no need to do that at all, if you know the user is already logged in (session).

I'm using md5

Using md5 at all precludes any semblance of security.

On this new website, I'm gonna use sha256

That will make almost no difference if credentials are still stored in a cookie.

So what should you do?

  1. When a user authenticates themselves store their user info in the session. Any time you need to check if the current visitor has already authenticated check the session data. The session's data is stored on the server - it is secure. There's no need to call the db to find out who the user is on each page load, if the user's data is stored in the session.
  2. Do not use cookies to store user credentials, especially if you're storing the password hash as stored in the db.
  3. Don't use md5 - and if you're "forced" to do so change it at the very first opportunity.
AD7six
  • 56,182
  • 12
  • 84
  • 114
  • MD5 is used for my personal website, and I will change it to double authentification whenever I get the chance. That means using a very secure salted hash for the website, and md5 for the game, since the game only stores sessions server side - per connection, the only possible risk being a breach of the database and user mails and dehashed passwords being released. – Cârnăciov Mar 17 '15 at 08:20