So this sort of goes with my question: Authentication Cookie
Our current organization has a CAS SSO system. I manage multiple applications that all use their own sessions in ColdFusion. I could just use the SSO system to authenticate, but when a user logs out of one of my systems I want to make sure I log them out of ALL my systems, but I won't know which ones they are in necessarily. Trying to do this in a practical way. The good thing is all my applications are on the same sub-domain. SO...
I set three cookies at the sub-domain level with a 30 min expiration.
Cookie A: Contains the userid
Cookie B: Contains a string with the expiration date/time
Cookie C: Contains a HASH of the two with some SALT added in
My thinking is if the user tried to change the userid the HASH check would fail. If someone got on the machine and tried to change the expiration the HASH check would fail. Thus hopefully making this secure. And when someone logs out of my system I clear the cookie that's shared with all of them and if they return to any system they are forced to log in again. I verify the hash on each page load and refresh the cookie periodically to extend the expiration time.
EDIT: Additionally, if user logs into app1 and then goes to app2, I don't use the cookie to authenticate, I send them back to the SSO and only if they are still logged into the SSO do they get in. So I only use the cookie to log them out AND make sure they are still logged in.
END EDIT
Apart from the fact that the userid is "exposed" in the cookie is this secure/where could this fail or be compromised?
I don't want to store sessions or anything like that in a DB if it can be avoided.
Related
I'm building a basic website where a logged in user makes requests to a server. What are some good practices for the server to verify that the user is who he says he is? Right now I create a session key every time the user logs in which is then stored in the DB. the session key is the hash of the users username concatenated with the current time. Every time the user makes a request he sends along the session key to be verified. Are there any security flaws with this method?
Yes, this isn't real security. It is know as Security by Obscurity.
If an attacker wants to hijack a session, all they would have to do is hash the username along with the time and set it as their cookie value. Of course this would have to correspond with a valid user session being logged on at that time, but they could easily script this.
For example, if they wanted to log on as bob#example.com the could simply generate the hash of bob#example.com:00:00:00, bob#example.com:00:00:01, bob#example.com:00:00:02, etc, etc, until they find a session value that allows them to access privileged pages.
Currently on our web-based apps we don't allow users to save their login information. The login itself is simply a secure cookie with a random hash which points to session information on the back end. There are no issues like HIPAA to be had, we just never implemented saving credentials, because it doesn't seem like a good idea to me.
What are the pros and cons from a security perspective on this? I worry about users getting saved cookies taken, though we do check session against IP address as well. I just don't want to miss anything.
Never 'save' the credentials, always generate a secure token that you will store on the client side and treat it as if it was the user's password (it kind of is, actually).
But first:
High value applications MUST NOT possess remember me functionality.
Medium value applications SHOULD NOT contain remember me functionality. If present, the user MUST opt-in to remember me. The system SHOULD strongly warn users that remember me is insecure particularly on public computers
Low value applications MAY include an opt-in remember me function. There should be a warning to the user that this option is insecure, particularly on public computers.
Always give the user an overview of active sessions once he is logged in and give him the option to terminate certain sessions.
You could use this strategy described here as best practice:
When the user successfully logs in with Remember Me checked, a login cookie is issued in addition to the standard session management cookie.
The login cookie contains the user's username, a series identifier, and a token. The series and token are unguessable random numbers from a suitably large space. All three are stored together in a database table.
When a non-logged-in user visits the site and presents a login cookie, the username, series, and token are looked up in the database.
If the triplet is present, the user is considered authenticated. The used token is removed from the database. A new token is generated, stored in database with the username and the same series identifier, and a new login cookie containing all three is issued to the user.
If the username and series are present but the token does not match, a theft is assumed. The user receives a strongly worded warning and all of the user's remembered sessions are deleted.
If the username and series are not present, the login cookie is ignored.
I just started integration of OpenID in my website. All the examples I saw store the claimed IDs in cookies. How is it safe?
For example, myopenid.com returns a claimed ID that is {username}.myopenid.com
So if a hacker knows your claimed ID, he can easily hack your account.
Of course you encipher/md5 the ID before putting it into the cookies and using for authentication, but it's like storing a username without password!
Update
Now that I thought more about it, I realized, that you need to be logged in the OpenID provider, so even if the hacker gets the username, he still needs the provider's password to log in. Am I correct?
Update 2
No, update 1 is not correct :) My site cannot check whether the user is successfully logged in or not. All I receive is the claimed ID, and I just have to trust that the user is authenticated. That's really confusing...
Knowing the user's claimed identity isn't enough to authenticate.
Indeed, the user would have to be logged in to his provider, in order to authenticate with your website using that identity.
As for "trusting that the user is authenticated" -- no, you don't trust. As a final part of OpenID authentication you're supposed to verify that the authentication message comes from the provider. There are various security measures in place to ensure that the message is authentic, unaltered, etc.
If you do that, you're sure that your user is properly authenticated by the provider.
Now, since you don't want to do it every time your user makes a request, you store the session information in a cookie. However, you don't store only the claimed identifier (if you decide to store it at all), but a session id -- a pseudorandom number generated at the moment your user logs in. Since it's pseudorandom, no one can guess it, and therefore, knowledge of a claimed identifier itself doesn't mean anything.
If that answers your question, read about session management in your favorite language/framework, as it will tell you how to easily implement such mechanism, and how it works.
In summary: think of OpenID as a replacement for a password verification. You don't need to (and shouldn't) store logins and passwords in cookies, and you don't have to store claimed identifiers. Similarly, you don't verify that the login and password matches every time, but remember that the user is authenticated in a session.
We want to AutoLogin feature to allow user directly login using link into our Web Application. What is the best way achieve this?
We have following approches in our mind.
1) Store user credentials(username/password) in cookie. Send cookie for authentication.
e.g. http: //www.mysite.com/AutoLogin (here username/password will be passed in cookie)
OR Pass user credentials in link URL.
http: //www.mysite.com/AutoLogin?userid=<>&password=<>
2) Generate randon token and store user random token and user IP on server side database.
When user login using link, validate token and user IP on server.
e.g.
http: //www.mysite.com/AutoLogin?token=<>
The problem with 1st approach is if hacker copies link/cookie from user machine to another machine he can login.
The problem with 2nd approach is the user ip will be same for all users of same organization behind proxy.
Which one is better from above from security perspective? If there is better solution which is other than mentioned above, please let us know.
The only secure "auto-login" is a cookie that gets set after a normal login and is verified when the user comes back to the site. The cookie should expire after a reasonable amount of time. Your first approach is similar to this, but you haven't explained how their username and password get stored in a cookie in the first place. Instead of storing those in plaintext, store a series of cookies that contain, at the minimum:
their username
an expiration time
a SIGNED hash of the previous items. Signed means that the hash includes a secret that is known only to the site and never given out to anyone. When the cookies come back to you, re-sign the first two items, and compare the signature to the one in their cookie. If it matches, you know it came from you and wasn't tampered with, so you can let them in.
Which one is better from above from security perspective?
Both are bad, but storing passwords in the clear text is a sin. Please don't even consider it.
If there is better solution which is other than mentioned above, please let us know.
Don't implement auto-login. Its never going to be secure.
When a user logs in, I give them a cookie named auth with a value that is a GUID, which expires in 2 weeks. I save the hashed GUID in the database with a salt of their userID and then date when it expires. When a user accesses the site, I check for the cookie and log them in if it matches and hasn't expired in the database.
At some point before the 2 weeks is up I was thinking about updating the row and increasing the expire date.How often do you do this? Every page request seems too often since I will be constantly writing to the user table.
I was also considering changing the auth cookie value at this time. The downside of this is you cannot be authenticated at multiple computers / browsers.
I could accomplish this via a session cookie, so that it this rewrite only happens once per session. When a user accesses a page, I check for a session cookie named authenticated. If it's not there, I give them a new auth cookie value and authentication session cookie and bump the expiry times in the DB and auth cookie. If it is, I just validate off of the auth cookie.
It seems like StackOverflow never changes their auth cookie until you log out and log back in. This seems to make it more vulnerable to session hijacking- if you get the auth cookie, you have access to the users account until they log in again. Since their auth cookie won't expire or change the user will not be logged out by you logging in.
Do you allow a user to log in from multiple locations/browers?
If not, how often do you change their authentication tokens?
It depends on the level of security, places where I have worked it normally has to be kinda high.
No we do not allow people to log in from multiple browsers.
We make people login again after 20 minutes of inactivity. Depending on how accurate you want to be on timing the person out determines how often you want to update the token. I've been places where it the expiration time is updated everytime the user sends a post back to the system.
Hrm I found all of my answers here. Looks like I need a join table >.<.
http://fishbowl.pastiche.org/2004/01/19/persistent_login_cookie_best_practice/