How to implement cookie based authentication - pingfederate

I am trying to implement "Remember Me functionality" in PingFederate. For doing this I am trying t implement cookie based authentication. Before working on this I want to know any of you already worked on this and what are your thoughts ?
Please let me know.
Thanks!

First off, just to get it out of the way, I work for Ping Identity. Always good to have that up front.
Second, there may be some clarification in order, but if you're wanting to configure "remember me" functionality... Doesn't that defeat the concept of authentication? Don't you want to protect the resources that PingFed enables access to? Allowing "remember me" may be fine for something like Facebook, or WordPress, but I sure wouldn't put it in front of anything financial or health related (in fact, there are regulations against such a thing).
Finally, to actually answer your question... You'll need to create your own authentication adapter, likely built around our OpenToken SDK. The way I would handle it is to authenticate a user against whatever user repository, and create a "long-lived" cookie, one that is good for X number of days, and refreshes every time it gets used. That cookie cookie can generate an OpenToken, providing access into PF and its protected resources. You should make it so that token is a hash of something... Like a salted hash of the machine's MAC address or something similar that ties the cookie to that machine.
Again, though, I want to caution you against "remember me". It just seems like you're reducing security.

Related

Best approach to implementing "Remember Me" on ASP.NET Web Forms

I'm working on a legacy application using ASP.NET Web Forms, and I need to implement the "Remember Me" functionality when the user logs in (as in, does not require the user to log in unless their username/password has changed). What is the best approach to doing this? I've found posts like this one or this one but these are incredibly old and was wondering if there is an updated practice to doing this. TIA!
I believe the standard generally speaking is to create some kind of unique/random token and store it in the customer's cookies. On the back end, you save that token associated to the username, so when the customer is browsing you can check the token in their cookies and compare it to what you have on file in the database. I'm sure there are a variety of opinions on how exactly to implement all that, as you can see in that first link you mentioned, but using some kind of token in a cookie is what I've seen in many places.

Can some hacker steal a web browser cookie from a user and login with that name on a web site?

Reading this question,
Different users get the same cookie - value in .ASPXANONYMOUS
and search for a solution, I start thinking, if it is possible for some one to really steal the cookie with some way, and then place it on his browser and login lets say as administrator.
Do you know how form authentication can ensure that even if the cookie is stolen, the hacker does not get to use it in an actual login?
Is there any other alternative automatic defense mechanism?
Is it possible to steal a cookie and
authenticate as an administrator?
Yes it is possible, if the Forms Auth cookie is not encrypted, someone could hack their cookie to give them elevated privileges or if SSL is not require, copy someone another person's cookie. However, there are steps you can take to mitigate these risks:
On the system.web/authentication/forms element:
requireSSL=true. This requires that the cookie only be transmitted over SSL
slidingExpiration=false. When true, an expired ticket can be reactivated.
cookieless=false. Do not use cookieless sessions in an environment where are you trying to enforce security.
enableCrossAppRedirects=false. When false, processing of cookies across apps is not allowed.
protection=all. Encrypts and hashes the Forms Auth cookie using the machine key specified in the machine.config or web.config. This feature would stop someone from hacking their own cookie as this setting tells the system to generate a signature of the cookie and on each authentication request, compare the signature with the passed cookie.
If you so wanted, you could add a small bit of protection by putting some sort of authentication information in Session such as a hash of the user's username (Never the username in plain text nor their password). This would require the attacker to steal both the Session cookie and the Forms Auth cookie.
The scenario where a cookie can be stolen happens in a public wireless environment. While you or I would never operate in such a setup, it may be impossible to prevent your customers from doing so.
If the attacker knows what secure site you're connected to, the idea is that your browser can be tricked into posting to a non-secure version of the same url. At that point your cookie is compromised.
That's why in addition to httpOnlyCookies you'll want to specify requireSSL="true"
<httpCookies httpOnlyCookies="true" requireSSL="true" />
I disagree with The Rook's comment, in that I find it unfair;
#Aristos i updated my answer. But to be honest, if your using a Microsoft development platform your application will be inherently insecure. – The Rook 22 mins ago
Security doesn't happen by accident and it doesn't happen "right out of the box", at least not in my experience. Nothing is secure until it's designed to be so, regardless of the platform or the tools.
There are many ways that a session id can be leaked to an attacker. XSS is the most commonly used attack to hijack a Session ID and you should test for XSS vulnerabilities in your application. . A common method of improving the strength of a session is to check the IP address. When the user logs in, record the ip address. Check the IP address for every request, if the IP changes then its probably a hijacked session. This secuirty measure could prevent legitimate requests, but that is very unlikely.
Do not check the X-Forwarded-For or User-Agent, its trivial for an attacker to modify these values.
I also recommend enabling httpOnlyCookies in your web.config file:
<httpCookies httpOnlyCookies="true"/>
This makes it more difficult for an attacker to hijack a session with javascript, but its still possible.
I don't know the specifics of the cookie in question but it's generally bad practice to store both the username and password in a user cookie. You generally want to only store the username in the cookie along with other non sensitive information. That way the user is prompted to provide their password only when logging in.
I am working on this, and I am coming up with an idea, that I am not sure if it is 100% safe, but is an idea.
My idea is that every user must pass from the login page.
If some one stole the cookie, is not pass the login page, but is go direct inside to the rest pages. He can not pass the login page, because did not know the really password, so if he pass he fail anyway.
So I place an extra session value, that the user have been pass with success the login page.
Now inside every critical page, I check that extra session value and if found it null, I login off and ask again for the password.
Now I do not know, maybe all that done all ready by microsoft, need to check it more.
To check this idea I use this function that direct make a user logged in.
FormsAuthentication.SetAuthCookie("UserName", false);
My second security that I have all ready fix and use, is that I check for different ips and or different cookie from the same logged in user. I have made many think on that, many checks (if is behind proxy, if is from different countries, what is look for, how many times I have see him, etc...) but this is the general idea.
This video show exactly what I try to prevent. By using the trick I have describe here, you can not just set the login cookie only.
Just sharing my ideas...

Poor Man's Authentication

I'm developing an ASP.NET web site for some small business. The site needs a password-protected area where the site owner will manage the site content. For the rest of the world, the site is completely read-only.
I've designed and implemented the following scheme:
A user wants to access some protected page.
Every protected page inherits "AdminIface" master page, that alters the UI so that user knows he's on a protected page, and checks the security cookie. If no cookie or wrong cookie: redirect to auth.aspx.
Auth.aspx generates a big random number using RNGCryptoServiceProvider, then sends it to the client + password form.
User enters the password.
Client-side JavaScript combines random seed + password, calculates MD5 of the resulting string, posts MD5 to the server.
Server compares the random seed with the value hold by Session, if OK it combines random seed + password, calculates the MD5, compares MD5.
If the checksum matched – the server generates one more big random number to be used as a security cookie.
Server stores the security cookie in Session object, and sends the cookie to the client who's now considered authorized.
The correct password is stored as a string constant in the auth.aspx source.
Is this scheme OK?
P.S. I know AD+Kerberos is much better, however on the godaddy's shared hosting I've got no privileges even to create one more application.
I would just hard code the user authentication into the web.config. This means you can still use the Membership controls. A really good example can be seen here. No database required, nor Membership provider. If you have one user (or very few users) then this is a pretty good option.
If you are worried about the authentication details sitting in the web.config, then you can encrypt specific sections of the web.config.
This would appear to be a much simpler solution than you have implemented.
It sound ok. Standard HMAC stuff. However your weaknesses:
Application: relying on javascript and sessions
Security: using a new codebase
Depending on your requirements you might be ok. having said that I strongly suggest using forms authentication, which overcomes these issues and much more.. and it is fairly easy to use.
Ummm, why not http://en.wikipedia.org/wiki/Basic_access_authentication with https (or even without)?
-- What's the real scenario of a threat?
Your method seems a bit hand-rolled. The usual rule is to try to use an existing security system rather than inventing your own. Inventing a new authentication mechanism that is really secure is known to be a very hard problem.
Many intelligent people (namely the Software Engineers who created WEP) have tried and failed at creating their own security authentication mechanisms and failed. The possibilities for screwing up your own "custom" security authentication are endless (no offense, but it is an extremely difficult problem to handle even for security experts).
I think it's best to use something that is proven to work such as an SSL certificate based authentication method.
What is wrong with TLS/SSL? It would provide many benefits here, the least of which is some thread of site->user authentication.
As kind of already mentioned, why not just use forms authentication with an SSL cert - dead easy to set up (particularly for one user) and you know that it's been tested... You don't know what you've potentially missed.

Is it possible to authenticate on another website?

If I am on a website#1, and I enter my username/pwd for website#2 on a login page that is on website#1, and website#1, behind the scenes, makes a httpwebrequest to website#2 and posts to the login page. If I then navigate to website#2, should I be logged in?
website#2 uses formsauthentication and I call a httpHandler that is on website#2 and pass it the username/password via the querystring.
Should this work?
What you're trying to do is called Single Signon. The way you're doing it, posting values from one site to another, probably won't work because you're using the same technique a hacker might use to trick user into sharing their login information. It's called a cross-site request forgery attack. IIS is configured not to allow that.
Generally, you need a central authentication system that both sites use to share login information. This can be done in several ways, including a shared database-based login system. Google "asp.net single sign on" for more ideas.
Do site #1 and #2 want their users to have single sign on?
If so, read up on single sign on. It's a bigger project than can be addressed here. There is a good book on it though from Wrox :
http://www.amazon.com/Professional-ASP-NET-Security-Membership-Management/dp/0764596985/ref=cm_lmf_tit_10
Or are we imagining something sinister?
If we are imagining something sinister, then evil site #1 would collect the credentials, then automate a browser on the server side to start checking to see if site #2 uses the same password and user combination. Then the server would have an authenticated session. This wouldn't give the user who accessed site #1 an auth cookie, the HttpWebRequest object on the server would get the auth cookie. Site #2 couldn't really do anything to prevent this because a browser request from one computer looks much alike a browser request from another. A well crafted attack would spoof all elements of the browser's request so that it looks like it came from a browser instead of a primitative HttpWebRequest object, which may not even set the user-agent.
Site #2 should stop using passwords and user Id or use 2 factor ID if they are concerned abut this, or do something that requires javascript for logon because spoofing a browser that is executing javascript is harder than spoofing a browser that just sends and receives http requests and responses.
There are too many security issues trying to auto-authenticate between sites. There needs to be a central security provider that both sites belong to so that hand off is completed securely.
We use CA's Siteminder for cross site authentication. Effectively, web 1 creates a unique session id on the siteminder server and passes any credentials and info to it. Siteminder invokes web2 and passes the information by means of session variables. Web 2 retrieves the data from the session and uses it. There's much more going on there but that's the just of it.
To do something like this, I would strongly consider using an out of the box solution as generally coding up custom security generally falls short.
While this can be done on some cases, in the form of an HTTP request with POST parameters, you will not be authenticated once you browse to site #2.
This is because, generally, these sites store a cookie on your end and these are domain-based, which means that even if you grabbed that and stored it yourself from site #1, the cookie name would not match site #2.
Additionally, site #2 may not be easy to authenticate against and this is usually a security concern that developers are aware of. This can be considered an attempt of XSS as well.
In case you're simply doing this for yourself, I'd recommend LastPass and save most of your info in it.
Please reconsider your goals and how to achieve them, this is not the way.
Edit: Link text.
This could work, depending on the security measures in place on website #2. For a secure website, this would fail.
I would recommend against this purely on the basis of good security and good coding/design practices.
If you are unclear what security measures stop this, you should probably educate yourself so you can prevent the same issues on your own site. See http://www.owasp.org/index.php/Top_10_2007
Since both your sites are using FormsAuthentication you can easily configure both of them to share FormsAuthentication encryption schemes.
This will allow you to do Cross Application Authentication automatically :)

User roles - why not store in session?

I'm porting an ASP.NET application to MVC and need to store two items relating to an authenitcated user: a list of roles and a list of visible item IDs, to determine what the user can or cannot see.
We've used WSE with a web service in the past and this made things unbelievably complex and impossible to debug properly. Now we're ditching the web service I was looking foward to drastically simplifying the solution simply to store these things in the session. A colleague suggested using the roles and membership providers but on looking into this I've found a number of problems:
a) It suffers from similar but different problems to WSE in that it has to be used in a very constrained way maing it tricky even to write tests;
b) The only caching option for the RolesProvider is based on cookies which we've rejected on security grounds;
c) It introduces no end of complications and extra unwanted baggage;
All we want to do, in a nutshell, is store two string variables in a user's session or something equivalent in a secure way and refer to them when we need to. What seems to be a ten minute job has so far taken several days of investigation and to compound the problem we have now discovered that session IDs can apparently be faked, see
http://blogs.sans.org/appsecstreetfighter/2009/06/14/session-attacks-and-aspnet-part-1/
I'm left thinking there is no easy way to do this very simple job, but I find that impossible to believe.
Could anyone:
a) provide simple information on how to make ASP.NET MVC sessions secure as I always believed they were?
b) suggest another simple way to store these two string variables for a logged in user's roles etc. without having to replace one complex nightmare with another as described above?
Thank you.
Storing the user's role information in a server-side session is safe providing a session cannot be hijacked. Restating this more broadly, it does not matter where user role info is stored if an authenticated session is hijacked.
I advise not putting too much faith in the article you linked to, but the 2002 vintage report linked to from your link is of interest. Here are my take-aways:
Don't accept session IDs embedded in URLs.
Focus your time on eliminating cross site scripting dangers i.e. scan all user supplied data and parse out executable java script.
Issue cookies for complete domains (e.g. myapp.mydomain.com)
Host your domain at a high class DNS operator e.g. one that only allows DNS changes from a preset remote IP address.
Don't issue persistent session cookies.
Reissue a session cookie if someone arrives at a login page with a sessionID already associated with an authenticated session.
Better still, always issue a new session cookie on successful authentication and abandon the prior session. (Can this be configured in IIS?)
The only way to make a secure cinnection is to use SSL. Anything less than that, and you simply have to make the evaluation when it's "safe enough".
A session variable works fine for storing a value, with the exception that the web server may be recycled now and then, which will cause the session to be lost. When that happens you would have to re-authenticate the user and set the session variable again.
The session variable itself is completely safe in the sense that it never leaves the server unless you specifically copy it to a response.
Have you considered setting up a custom Authorize tag in MVC. I gave an example of this in another question.
On initial authorization (sign-in screen or session start) you could seed a session value with the IP address also. Then in your custom authorization, you could also verify that IP's still match up as well. This will help make sure that someone isn't 'stealing' the person's session. Everytime you access your session data just make sure to pass the requester's IP and have some check on it.
Are you trying to control the access to functions at the client level? That is the only reason I would expose the roles and items to control client side functions.
Alternatively, you could create a function to obtain the items that the roles of the user are allowed to use, and then even if the function is called outside of the items given back to the web application, you can prevent the user from accessing them.
4Guys seems to show how to control functions with the roles.
The approach I have used in the past is to use symmetric encryption of a cookie alongside SSL. Encrypt the user information in the reponse and decrypt it in the request. I'm not claiming this is foolproof or 100% secure and I wouldn't want to do this on a banking application, but it is good enough for many purposes.
The main issue with session variables is that if you store them inProc rather than persisting them, then you need to apply 'sticky' sessions to your load balancing in a web farm environment. Guffa is correct that without this persistence session variables will occasionally be lost causing a poor user experience.
Sticky sessions can lead to uneven load balancing, perhaps reducing the value of being able to scale out.
If you are going to be be persisting the sessions so they can be accessed by all servers in your web farm, you may be better off using a Guid to identify the user, encrypting this in a cookie and retrieving the user record from your data store each time.
My obvious question is that why do you want to store a users role in session ?
Here is my answer to your query, how this helps. I have attached a small demo application for you to take a look at and understand my points. When you open this project in visual studio, click on the project tab on the top and select asp.net configuration. From the page that will show up you can do the user administration stuff.
You need to store the roles of a user in some secure manner ? The answer to this question is that there is no need for you to worry about storing the role for any user, when we have the asp.net membership, profiles and roles framework to help us out on this. All you need to do is create a role in the aspnet database and assign that role to the user.
Next you want to store two string in some secure manner. I suggest you user profile for storing user specific information. This way you have the information available to you where ever you want from the profilecommon class.
Also please see the attached demo application placed at the end of my blog http://blogs.bootcampedu.com/blog/post/Reply-to-httpstackoverflowcomquestions1672007user-roles-why-not-store-in-session.aspx
Just a suggestion, you might consider using this little library:
http://www.codeproject.com/KB/aspnet/Univar.aspx
It has a server side implementation of the cookie whereby all cookies can be stored on the server while asp.net authentification is used to identify the user. It supports encryption and is also very flexible making it very easy to switch from one storage type to another.

Resources