handling username / password in cookie for login - cookies

Making a login script and I have the following cookies right now :
This is on every page, but expires on browser close.
session_name('Test_Login');
session_set_cookie_params(0, '/', '.test.com', false, false);
session_start();
This is stores the username if a successful login happens. When returning to the site it will fill out the username in the login form.
setcookie('Test_User', $_POST['username'], time()+365*24*60*60, '/', '.test.com', false, false);
This remembers the value of the 'remember me' option on the login form - true or false.
setcookie('Test_Remember', $_POST['rememberMe'], time()+365*24*60*60, '/', '.test.com', false, false);
This stores the user plain text password if they selected the remember me option above and lets them automatically login when visiting the site even after browser close within a day. If this and user cookie are present it checks if valid and creates the user session variables again.
setcookie('Test_Pass', $_POST['password'], time()+24*60*60, '/', '.test.com', false, false);
Other things to consider are if you log out the session pass cookie is destroyed.
My problems : I md5 and salt the user password for storage in the database. I actually never know the users pass. Problem is with the remember option I am storing their password in plain view in the cookie. What is the best way to store the pass in a cookie and it be useable in this fashion? What is the standard of doing so? Basically I just want this to act same as Facebook or any other login system. If you tell it to remember you it does - so how do they store the info to log back in without doing so in plain text in the cookie?
Is it best practice to have a separate cookie (4) for this? The session cookie makes sense, but is there not a more optimized way on my end to combine the other three?

You shouldn't store the password in a cookie it's not a good practice and can lead to security issues (somebody could "steal" the cookie for example and get the user password).
Instead, once the user has been correctly authenticated once, you could save the sessionId in a cookie and on next visit the sessionId will be passed to the server which will be able to retrieve the session. For additional security store the IP address too and check that it is the same when reopening the session. You could also make your server sessions expire after 2 weeks for example.
To do this you need to use a cookie, not a session cookie (which is deleted once the browser is closed).
Check session_set_cookie_params() and give session cookie a lifetime.
See the PHP manual for more info: http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-lifetime
In the end, if you really want more security, you should definitely have a look at SSL.

You should use session variables instead of storing the data in a cookie.
Here's an example in PHP
<?php
session_start();
$_SESSION['password'] = 'YOUR PASSWORD HERE';
//then you can reference the session variable in your code
echo $_SESSION['password'];
?>
You can set how long the sessions will stay for and the user cannot directly access the session variables because they are stored on the server. This is the way many secure login system works.

Multiple sources have pointed to http://jaspan.com/improved_persistent_login_cookie_best_practice as the best practice for my purposes.

Related

How to invalidate a users token in CouchDB?

The offical documentation states the following about deleting a users cookie:
Link
DELETE /_session
Closes user’s session by instructing the browser to clear the cookie. This does not invalidate the session from the server’s perspective, as there is no way to do this because CouchDB cookies are stateless. This means calling this endpoint is purely optional from a client perspective, and it does not protect against theft of a session cookie.
I can invalidate the cookie on the client but what if somebody siphons the AuthSession=123abc and uses it on the quiet? Isn't this a security problem?
I would like to know how I can avoid this behavior and really destroy the cookie because I would like to have a somewhat secure application with CouchDB.
I'm certain I've answered this question before, but I can't find the duplicate question, so here goes again:
The cookie is a simple hash of the user's login name, the time the cookie was created, the user's password salt, and the server's secret.
This means that to invalidate an existing cookie, you must either wait for enough time to pass that the created timestamp is far enough in the past that the cookie is not considered valid, or change one of the other parts of the hash.
In effect, this typically means it's impossible, because:
Changing the user name means the user will no longer be able to log in.
Changing the user's password salt will also mean the user can no longer log in, unless you also store the user's plaintext password, so that their password hash can be re-calculated. (probably a very bad idea)
Changing the server secret will render all sessions invalid for all users, not just the one you're targeting.
If invalidating active sessions is a hard requirement of your application, it's best done in a reverse proxy server that handles authentication, and uses proxy authentication to interact with CouchDB.

Cookie :: Need suggestion regarding Cookies

I have an authentication form and for 'remember me' functionality, I want to use cookies which will store username and password.
Here is my question - If I want to keep a cookie for a month, will it be a good idea to store password inside cookie ? Can someone see cookie values and edit them using cookie manager etc tools ? How wise would it be to store passwords in cookies ?
Please suggest. Thanks in advance.
Cookies can easily be viewed and modified by users, for example by the Chrome extension EditThisCookie. Therefore, storing passwords in cookies is probably not a good idea.
You could encrypt the cookie using a server key that is somehow affected by the user name. You would have a base key for cookie encryption/decryption and then maybe salt it with the username stored. Crypto operations would obviously have to be performed on the server.
Probably better is storing a session key in the cookie, still encrypted to prevent theft of cookies from allowing the thief to log in. Have the session key include some information about the user-agent and whatever other info the browser supplies, maybe. Of course, you'll have to keep a table of valid session keys on the server.

Use cookie locally by using a random path (security)

Classic problem, a web app has secure and insecure pages (ie. account page is secure (HTTPS) and faq page is insecure (HTTP)), as a developer, I want the user to see a customized login button on the insecure pages (ie. it says 'click to login' if you are new to the site and 'Welcome User click to see your account' if you have a session.
To do this, I have secure cookies set by the server sent only when on the account page, but that account page (via jQuery) will also set an insecure cookie based on the secure one. The insecure cookies can be used by the browser to update the login button (via Javascript).
I am using a random string (randomized on the server each time) for the path to prevent the cookie from ever being sent over the wire. This data is just a username so it's not critical that it is completely locked down, however, it should still be guarded.
Cookie set here using jQuery (jQuery cookie plugin):
$.cookie('userLoggedIn', 'username', { domain: '.example.com', httpOnly: false, path: 'DFKLJGHDFDLFKHGAFDAKDJFH', expires: [one year], secure: false });
So far so good, but to a hacker, does path randomization work to prevent the stealing of insecure cookies?
I know that this is a very old question, but I will try to answer it.
Yes and No.
It doesn't necessarily need to be completely random - the only reason for it to be random is to make sure user never tries to get to that url, nor any ajax request goes there. To make sure that happens, you can use e.g. an UUID in the path.
You also need to make sure you control ALL of the JS on your domain.
That way the cookie will never get sent over the wire (the only way for it to get sent over the wire is for your JS to read it off document.cookie property and attach it or somehow send a request for that randomised URL).
A hacker won't be able to read the cookie, because browsers protect cookies from JS executed from other domains (protocol://domain:port combination has to match).
So the only way left to read off the cookie is to have access to the machine, then cookies can be read from disc as it is saved as plain text. But there are way more security vulnerabilities that come with having access to the user account.
So to answer your question, it is quite secure, but you have to keep in mind the vulnerabilities that come with such a solution.

How to implement the automatically sign in functionality in JSF 2.0

I have a login form on which there is an option "Keep me sign in" in. If user check this option and press the login button. Then i think i can save the username and password in a cookie and send it to user computer. Then when user open the site again , i can check whether that cookie is present in user computer or not , if it is then get the username and password from the cookie and sign in the user. But the problem is how can i send cookie to the user computer? As far as i know. You can set the cookie in that way
Cookie userCookie = new Cookie("userCookie", "loginUser");
//sessionCookie.setMaxAge(60 * 15);
userCookie.setPath("/");
httpServletResponse.addCookie(userCookie);
If i don't set the setMaxAge then it's a browser level cookie, i.e., when user closes the browser then the cookie will be deleted. How can i send that cookie to user computer and get from the user computer to automatically sign in?
Thanks
Either way, you should never, never, NEVER store the password in a cookie!
Here is a nice article about persitent cookies : Persistent Login Cookie Best Practice http://fishbowl.pastiche.org/2004/01/19/persistent_login_cookie_best_practice/
The essentials from the article:
Premises
Cookies are vulnerable. Between common browser cookie-theft
vulnerabilities and cross-site scripting attacks, we must accept that
cookies are not safe
Persistent login cookies are on their own sufficient authentication to access a website. They are the equivalent of both a valid username and password rolled into one
Users reuse passwords. Hence, any login cookie from which you can recover the user's password holds significantly more potential for harm than one from which you can not
Binding persistent cookies to a particular IP address makes them not particularly persistent in many common cases
A user may wish to have persistent cookies on multiple web browsers on different machines simultaneously
The author suggests to associate the username with a large random number, which is a common practice.

Automatic cookie single sign on on multiple domains - like google

I don't understand how google achieve the following mechanism of single sign on:
I login in gmail for example (I suppose this creates a cookie withmy authorization)
I open a new tab and direct type the url of "youtube"
Then I enter youtube logged in.
How can this second site detect that I've already been logged in.
They are different domains. Youtube can't read the cookie of Gmail.
All the solutions I've read about Single sign on don't allow this. The client always ask permission to a central login app.
In my example YouTube doesn't know I am the same user logged in Gmail (actually it does know, but I don't understand how)
Note that I type the url of "youtube" by hand. I don't clic the youtube icon from the upper toolbar of gmail (In that case gmail may pass some auth params through the url for example).
The cookies are set on specific domains. Ex:
setcookie(name,value,expire,path,domain)
When you log in on gmail, before "mail.google.com", you have been redirected to "accounts.google.com" then to "mail.google.com" so the cookies are on "accounts.google.com" too.
In this case, the domain is "accounts.google.com" and the path is "/" (the home path).
When you request "www.youtube.com" then you click on "connection" it requests
"accounts.google.com" fast so you can't see this redirection and checks if you have cookies on "accounts.google.com". If so, it checks if the cookies are valid and not expired, or user not banned... Then it redirects you to "www.youtube.com/signin?loginthisSession=Sessionid". This request contains the value of the of sessionid cookie catched from the cookies of "accounts.google.com".
In the last step, "www.youtube.com" logs you and set its own cookie on the domain "www.youtube.com" and saves them.
So the trick is on the 302 HTTP redirect.
Update
i do not know why people keep mentioning iframe take a look at the date whene this questions was posted on 2016 google was not using then iframe as i mentioned the capture of web traffic as you can see SetSID wich means set the cookie of SESSION_ID from accounts.google.dz(com) then redirects to youtube.com it can not be used trought iframe differant domains security measure you can not be redirected from domain to domain trought iframe neither please read this before posting
Cookies and localStorage can be shared between domains using an intermediate domain. On the home page is embedded an "iframe ', which accesses cookies and sends messages to the main.
mail.google.com and youtube.com can share the cookies using accounts.google.es. Open Chrome->Inspect->Resources->Local storage and you will see in accounts.google.com the authentication token in JWT format.
I have detailed the technical steps in this answer: https://stackoverflow.com/a/37565692/6371459. Also take a look at https://github.com/Aralink/ssojwt to see an implementation of a Single Sign On using JWT in a central domain
Check this out.. http://www.codeproject.com/Articles/106439/Single-Sign-On-SSO-for-cross-domain-ASP-NET-applic.
The article consist explanation and sample of SSO cross domain.
As far as I remember, if I am not wrong, cookies contains a specified field that contains the domain that can read and get such cookie. That is made in order to prevent certain web sites to read all your cookie list and make your own business. You should be able to see which kind of sites can 'see' your gmail cookie.
Correct me if I am wrong, this should compile the answer given regarding the SID and gmail-YouTube example..
While evaluating this cross domain SSO topic, I have come up with possible a new SSO synchronization flow using cookie with timestamp. Although it is not a flow used by Google, I think this flow is possible to implement for system with limited number of domains.
This flow do not use 3rd party cookie
This is going to be a long post :)
domains
To make an example, let say we have these domains for our example pet forums:
https://account.domain1.com (For SSO Login)
.domain1.com (e.g. https://cat.domain1.com)
.domain2.com (e.g. https://dog.domain2.com)
.domain3.com (e.g. https://rabbit.domain3.com)
Change to https://account.domain1.com:
Add https://account.domain2.com and https://account.domain3.com, route both host name traffic to the server hosting https://account.domain1.com
Login Steps:
User go to dog.domain2.com, user have not sign in yet.
User click the Login button in dog.domain2.com
User get redirect to account.domain1.com for login
This step can be any Login protocol, OAuth, OIDC, SAML, CAS, etc
So, it is important for user to be redirected back to original page after login
Let say this https://account.domain1.com?redirect_uri=https://dog.domain2.com
redirect_uri as in the URL to go back after login success
User Input username & password, login success
New step, before redirect back to https://dog.domain2.com, set cookies on all domains
Redirect browser to https://accounts.domain2.com?...
Set a cookie on the .domains2.com domain (More on the cookie value later)
Redirect browser to https://accounts.domain2.com?...
Set a cookie on the .domains3.com domain
Redirect browser to https://accounts.domain1.com?...
Set a cookie on the .domains1.com domain
Redirect back to original flow
Redirect user back to their original service, i.e. https://dog.domain2.com
Now, right after login flow we have cookies over all 3 domains. Any of our service (e.g. https://cat.domain1.com / https://dog.domain2.com / https://rabbit.domain2.com ) can access this cookie under their own domain.
Cookie Content
The content of the cookie, should allows for any webpage to look at it, and determine if SSO sync is needed
Different types of cookie content can be stored, including
Boolean indicate user logined or not
User ID
Expired At timestamp
Boolean indicate user logined or not
Storing have_user_login = true / false have sync issue
Suppose User A login, visit https://cat.domain1.com, User A Logout, and User B login
Now, from https://cat.domain1.com standpoint, no sync is needed
However, https://cat.domain1.com is storing User A instead of User B, hence the sync issue.
User ID
While it is tempting to just stored the user_id on those cookie, and let all the domain to see them and set the user accordingly.
This is way too dangerous, since the cookie is set at the parent domain,
if any of the website under your domain been hacked, impersonation might happen (Copying any of the user_id, pasting it to their own browser cookie).
Expired At Timestamp
What I suggest, is for the cookie value to set as the SSO expired time, and set the type as session cookie, this have the following benefits:
An expired time have minimal security impact if leaked / altered
Our website can check the expired time to know if user need to relogin
As for why session cookie, is for when user close them browser, and tried to login again, the cookie will be deleted hence logout the user as well
Any webpage that use the SSO, should also stored a cookie themselves with the same expired time
There will be cases that, User A Login, visit https://cat.domains1.com Then User B Login
Since User A and User B will have a different login expired time, storing and compare that timestamp will tell the user to sync with SSO again
Example checking implement for your service
E.g. On https://cat.domains1.com, you can add this to the top of your page load
<?php
$sso_expired_time = $_COOKIE["sso_expired_time "] ?? 0;
$website_expired_time = $_COOKIE["website_expired_time "] ?? 0;
if( (int) $sso_expired_time < time() || $sso_expired_time !== $website_expired_time ) {
// User not sync, perform sync
setcookie("website_expired_time", $website_expired_time,0,"/", $_SERVER['SERVER_NAME'], true, true);
// Redirect to https://account.domain1.com for Login
// Or, Initiate the login sequence for your selected login protocol
header("Location: https://account.domain1.com/.....")
exit;
}
// User is sync
// Page load success, continue other operation
Logout
Login is very similar to Login, basically:
Before logout goes through, redirect to all 3 domains just like login
Remove the SSO cookie
Continue the normal logout flow
Pro and cons for the methods:
Pro: All domain sync possible
Pro: No need to relies on 3rd party cookie
Cons: First time login longer (around 50ms longer)
Cons: Customization on every website is needed for the sync to works