tags:

views:

51

answers:

3
+1  Q: 

Secure Cookies?

I am slowly moving my (unreleased) CMS from $_SESSION to $_COOKIE. Content on the internet seems to be biased more towards $_SESSION (I assume because ease of use). I am looking for security tips on saving cookies. Currently, I am storing (somewhat similar WordPress) a cookie in the format:

'logged_in_%hash_key%' => "username | %hash_password%"

Where my %hash_key% is md5(MYSALT."something".UNIQUE_KEY) and UNIQUE_KEY is regenerated (if the user chooses) after each login to lock out other computers that might have a cookie stored. It is a random 6-character string.

%hash_password% is similarly generated with Salt and random key (hashed).

I must know the key of the $_COOKIE (obviously), then I split the string by "|" and look at the username and password. If something doesn't match, I destroy the cookies.

My question is: do you have any other tips on storing cookies in a secure format, or is this good?

I also generate a nonce for each requested action. For example, I create a nonce for 'delete' and I expect to get that nonce back in my $_REQUEST. I don't log the user out if I get an incorrect response, but I don't do anything.

As meagar pointed out, I know COOKIES are inherently unsafe, I am still trying to do my best to make it all secure.

+2  A: 

"Secure cookies" is an oxymoron. Stick with server-side sessions, this is exactly what they're suited to. What is your reason for leaving them in the first place?

meagar
Man, I want to so bad. But I am trying to make a better user experience (don't have to log in regularly).
Jason
@Jason Are you aware that your session already uses cookies? And that you can increase the time they take to expire?
meagar
You can instead create a longer session length (time) to keep the user logged in for a longer period of time.
thephpdeveloper
I keep reading places about $_SESSION injects, except no one seems to give an example. Do you know how this is done, so I can fight it?
Jason
@Jason By compromising the cookies used to pass around session IDs. You're only make it worse by moving more of the data client-side. Read more about [session hijacking](http://stackoverflow.com/search?q=[PHP]+session+hijacking).
meagar
Session injects are probably less common than cookies injects because cookies can be accessed and modified by the end user.
thephpdeveloper
OK. So go back to SESSIONs. I am pretty secure at storing the cookies, so I am not worried about them being modified. I guess I'll move back to SESSIONs and store the variables similar to how I with COOKIEs.
Jason
A: 

I'm all for using $_COOKIE over $_SESSION, because I believe it's more professional in regards to data privacy. But authorization is the one use case where it's inappropriate. Keep using $_SESSION.

The session fixation problem is avoided with a few simple steps. Most importantly ensure that session_start() doesn't blindly accept session ids. Ensure that the session was created by the server by giving it a default token:

if (empty($_SESSION["ok"])) {   // would be empty for injected ids
    session_regenerate_id();
    $_SESSION['ok'] = 1;
}

As second measure use a fingerprint. It's best to store the original request IP. But only verify e.g. the first 16 bits to work around proxy issues. Very commonly the HTTP_USER_AGENT is used as fingerprint. And you should additionally give each session a pre-defined expiry time.

mario
why should cookies have better privacy? anybody who uses a PC in an internet café will have his data sprinkled on the public PC, whereas they are perfectly safe on the server
knittl
@knittl: You are right from the technical point of view. Cookies can be spied out, whereas session stores are server guarded. When I said data privacy I was referring to user rights. Because in the same sense that session stores are safe from prying eyes, users won't know what sort of data or logs are amassed about them. With a session ID you only get an unreadable number/hash. And I believe 'true' cookies should be legible / for human consumption. Alas, even if there is generally little user interest about this issue. (Again: cookies aren't useful for authorization data.)
mario
+2  A: 

I saw from one of your comments that you wanted a login with Remember Me. A simple solution is just to increase the expiration time of $_SESSION (or implement your own session algorithm). However, that is generally considered unfavorable. This is a great article on how you would create a secure remember me:

http://jaspan.com/improved_persistent_login_cookie_best_practice

The basic idea is:

Cookies:

  • Username/Email/etc
  • Token
  • Series

The token is changed every time the user loads a page. However, the series remains the same for the entire duration of the remember me period. You would keep a table of the series and the token in a database (possibly MySQL).

I'm not very good at explaining it, so I highly encourage you to read the article.

Kranu
I will probably mix this method and @mario's method. I think I will keep the token (probably md5 of my nonce) in the cookies, attached the time. Then I will store the token with an IP address. I already implement a cookie purge as the author mentioned in 5. Though, I'm not seeing how this is any more secure than what I have (besides not transmitting username back and forth). Oh well.
Jason