I'm confused as to what this setting actually does.
According to MSDN, "Gets or sets a value indicating whether the support for the browser's HttpOnly cookie is enabled."
But I'm struggling to understand what this actually means.
The problem I am having is that in my MVC application, the session cookie is not being sent with the secure flag. I've put the RequireSSL="True" attribute in both forms and cookies sections of the web config, but the session ID cookie is still not sent under SSL. I was wondering if this other attribute was connected with it.
If you've implemented requireSSL="true", your cookies should only be transmitted over the HTTPS protocol. Nothing more should be required for that. The HttpOnly flag tells the browser that the cookie should only be accessed by the server -- not by any client-side script. This prevents certain XSS attacks in modern browsers that respect this flag (should be pretty much all at this point).
Related
My question is different it's rather conceptual - As when a user login, session is created on server and it stores a unique id to client(browser) what if I copy that cryptographically signed cookie and any associate data from browser like token whatever app uses to recognize the machine, paste it or create it on another machine?
How would server recognize that? could someone Explain me as much you can? that would be a help
I tried finding the solution.
or how can I secure that? :)
As far as I know, only the user-identifying token in the Rails session cookie identifies the user. By sending that token (which happens automatically on each request), the server knows who you are. Anyone having that token will be treated by the server as if it were you. This is called Session hijacking.
There are a few things you can do to protect your user's cookies. First of all, secure your cookies by setting two flags:
secure tells the browser to send that cookie only over HTTPS, so it is protected against someone reading your traffic (and your cookie).
HttpOnly tells the browser to hide that cookie from Javascript, which improves protection against XSS (Cross Site Scripting). An attacker may find a way to inject some malicious Javascript, but the browser won't give it your session cookie.
On setting these flags, see the Rails API. For custom cookies it's basically:
cookies[:my_cookie] = { value: '...', secure: true, httponly: true}
For configuring the Rails session cookie, see this answer.
Recently, I have written a middleware that sets both flags automatically to any cookie in the application. It is called safe_cookies and we're using it in order to protect our applications.
Question #1:
Is setAuthCookie any less safe than FormsAuthentication.Encrypt(ticketVariable)?
I mean if anyone tries to modify the cookie created by setAuthCookie, by modifying the username, I suppose that'll violate the authentication on subsequent calls?
Question #2:
for those using iphones and tablets to access the site, I suppose FormsAuthentication will fail? Given that I don't want to use cookieless option, is there another approach to make the site secure on both smart phones web browsers and ummm none-smartphone web browsers?
cheers
SetAuthCookie basically creates a new FormsAuthenticationTicket with the supplied username & persistence options, serializes it, FormsAuthentication.Encrypt()'s it, and sets it in the Response.Cookies collection. SetAuthCookie and GetAuthCookie both call FormsAuthentication.Encrypt indirectly.
On subsequent requests, the FormsAuthentiationModule handles the AuthenticateRequest event. If it sees a cookie (it may have expired), it attempts to decrypt it's value with the machineKey (it may have been tampered with) and deserialize it back into a FormsAuthenticationTicket (it may be corrupt). If none of that (bad stuff) happens, the ticket contains the username, issue date, expiration info, etc.. If the ticket hasn't expired, an IIdentity and IPrincipal are created and assigned to HttpContext.Current.User and Thread.CurrentThread.Principal. In .NET 4.5 and later (I think), this is Claims-based (ClaimsIdentity, ClaimsPrincipal). Prior to that, it was a (GenericPrincipal, FormsIdentity) I think.
Any tampering at all on the user side will cause the request to be treated as anonymous. It will fail to decrypt. The only things that would compromise this validation would be if the machineKey in web.config/machine.config somehow got into the hands of an attacker or if there was a bug in the framework code (search for Padding Oracle for a historical example of this).
Aside from that, the other thing to watch out for would be session hijacking. If someone steals your cookie on a public wifi for example, they can present it to the server and the server will behave as if it's you. This generally involves network traffic sniffing. For these reasons, best practice is to use SSL for your entire site and set the cookie to HTTP only and Secure (only presented over https connections) in web.config/system.web/authorization/forms. HTTP only means that it will not be available to client-side Javascript. HTTP Only and Secure effectively means HTTPS only. This will only work if you use SSL on your entire site.
FormsAuthentication will work fine on mobile web browsers. It simply requires the client to accept cookies. As far as I know, all mobile devices will allow this.
I want to track a user's logon session from the time they login to my site, to the time they logoff.
Is there a pre-existing cookie I should use, or variable? I thought of using ASP.NET sessionIDs but read on StackOverflow that these numbers may change.
I would save my own Session cookie, but I don't want to do something that could be done more efficiently another way. I'm using Windows Identity Foundation (WIF) to handle my authentication layer.
The only cookie I see in fiddler is a FedAuth cookie so I assume that I might be able to derive some valuable information from it, but I don't know where / how in the WIF framework to gain access to such information.
WIF gives a bunch of events you can subscribe to. See these:
http://msdn.microsoft.com/en-us/library/microsoft.identitymodel.web.wsfederationauthenticationmodule_members.aspx
http://msdn.microsoft.com/en-us/library/microsoft.identitymodel.web.sessionauthenticationmodule_members.aspx
You can control some of the cookie characteristic via the config - A Hidden Gem: The WIF Config Schema. In particular, note the cookieHandler section and
hideFromScript - Boolean - default true Controls whether the
"HttpOnly" flag is emitted for any cookies written. Certain web
browsers honor this flag by keeping client-side script from accessing
the cookie value.
In terms of WIF, there is a Deserialize in Tokens.SessionSecurityTokenCookieSerializer and a CookieHandler (Delete / Read / Write) in IdentityModel.Web.
If I receive a request to the url host.com/site-directory/page-slug.html?session={someValidNonExpiredSessionGuid} and I detect a session cookie with the value: {someOtherValidNonExpiredSessionGuid}, then
Which session is the correct session to associate with the request?
Here's some background:
The pattern I am using for maintaining state across HTTP requests is to store a unique ID in the querystring, form collection and/or cookie. Then, on each request, I locate the unique Id and pull date from a database table. If the id is not valid, or the session is expired, a new session will be created (with a new id, a new cookie, etc).
The default behavior is that all forms will have a field:
<input type="hidden" name="session" value="{someGuid}" />
All links to other pages on the site will have an appended querystring parameter
a sample link
And, if the user's browsing device supports cookies, a cookie will be set having the session's value.
If I have validated that the user's browsing device supports cookies, then my form and querystring will no longer require the the session id field/parameter.
However, I am having a conceptual issue in deciding whether the session parameter of the querystring should take precedence over the cookie value or vice-versa. It seems like I could potentially get bad data in either circumstance. I could get data with a bad querystring parameter if the user bookmarked a page with the session parameter included in the URL. I could also get bad data from the cookie, if a user closes the browser without terminating the session, and the session expire-window has not yet closed. It also seems like both options could be vulnerable to a malicious user intercepting the request and sending a request with the same session information.
So, once again, my question is
If I receive a request to the url host.com/site-directory/page-slug.html?session={someValidNonExpiredSessionGuid} and I detect a session cookie with the value: {someOtherValidNonExpiredSessionGuid}, then Which session is the correct session to associate with the request?
I am leaning towards the cookie session, because it seems like the most common scenario will be a bookmark with the session included. I've already decided that the form post data should take the greatest precedence, because a page will always render the form with the correct ID, and the only possible situation with a wrong, non-expired ID is a very quickly implemented XSS attack, which is circumvented by including a request-scoped anti-forgery token field.
In addition to the primary question I appreciate any insight to any security-related or logical oversights I have expressed in this description. I apologize for the long post, but felt it was necessary to explain the situation. Thank you very much for your input.
Also, it is not necessarily relevant to the question, but I am using ASP.NET MVC in most situations, and setting my cookies manually with Response.Cookies.
From a security standpoint sessions should not be stored in query strings.
For example:
If sessions are stored in queries and you link to a remote host on the same page, the users valid session could be sent to the remote host via the referer header.
Sessions should always be stored in cookies.
You should try to store it in the cookie (looking the the browser caps to see if the browser supports cookies) and then have a fall back for query string.
I too would lean towards using the cookie session ID in case of ambiguity. This primarily because I'd trust the cookie implementation to be more well baked, more well tested, and more idiot-proof than my own home brewed session tracking implementation. For e.g. there are cases where ASP.NET automatically knows to clear the session cookies, renew them etc.
Also, I would design it so the cookies aren't persistent to minimize the edge cases. If the user closes the browser, then the session is closed.
The other simplification I would consider is to have either cookies or URL based tracking and not both. If the browser supports cookies, there is really no reason to also track the session through a URL.
Thoughts?
Curious ... What were your reason to rule out using the stock ASP.NET cookieless session implementation? - http://msdn.microsoft.com/en-us/library/aa479314.aspx#cookieless_topic2
If I receive a request to the url
host.com/site-directory/page-slug.html?session={someValidNonExpiredSessionGuid}
and I detect a session cookie with the
value:
{someOtherValidNonExpiredSessionGuid},
then Which session is the correct
session to associate with the request?
To answer your specific question, I'd recommend putting session management in the cookies as opposed to the querystring. As has been mentioned, cookies can be set to expire whereas the querystring cannot. This allows your thin-clients to assist in their own session maintenance by removing their own expired cookies. Moreover, since cookies are dropped to specific browsers, you reduce the chances of another browser spoofing the original browser session.
The only way I would use the querystring to pass session information would be as a backup method to re-establish a browser session onto a new browser instance. Here's a scenario: you have an active session using browser A on machine A which suffers some catastrophic error. You want a way to re-establish that same session on another browser instance on either the same machine or on another machine. If your code-behind can recognize that the session cookie doesn't exist, but that a valid session id exists in the querystring, you could initiate a challenge-response to verify the integrity of that session id and then drop a new session cookie on the new machine. Kinda extreme in my humble opinion, but the functionality might be useful in certain situations.
ADDED: I understand that you may want to accommodate users who have turned cookies off on their browsers, and while you can use the querystring to hold the session id I'd recommend against it. But if you must, encrypt that sucker using browser-machine specific information.
I'm an old hand at C but a raw newbie at Java/Tomcat.
I'm fine with Tomcat session management in http alone. Its when I've come to look at switching to https that I've had problems.
I gather for Tomcat that you have to start with an http session if you want to maintain a session as you switch from http to https and back to http. This works fine for me when the browser is enabled for cookies.
But when the browser is disabled for cookies (and URL rewriting is being used) then switching http to https or back again causes a fresh session to be started each time. I'm assuming this is a security thing.
Q1 - Is it possible/desirable to maintain a session between http and https using URL rewriting?
Q2 - If it isnt possible then what do e-commerce developers do about non-cookie users?
I dont want to prevent non-cookie people using my site. I do want some flexibility switching between http and https.
thanks for any help,
Steven.
It doesn't seem desirable to maintain session between HTTP and HTTPS using the same cookie or URL token.
Imagine the case where you're user is logged on, with a given cookie (or URL token) passed back and forth for every request/response in an e-commerce website. If someone in the middle is able to read that cookie, he can then log on to the HTTP or HTTPS variant of the site with it. Even if whatever the legitimate user is then doing is over HTTPS, the attacker will still be able to access that session (because he too will have the legitimate cookie). He could see pages like the cart, the payment method, perhaps change the delivery address.
It makes sense to pass some form of token between the HTTP session and the HTTPS session (if you're using sessions), but treating them as one and the same would cause some vulnerability. Creating a one-off token in the query parameter just the transition could be a solution. You should however treat them as two separate authenticated sessions.
This vulnerability can happen sometimes with websites that use mixed HTTP and HTTPS content (certain browsers such as Firefox will give you a warning when that happens, although most people tend to disable it the first time it pops up). You could have your HTTPS session cookie for the main page, but that page contains images for the company logo, over plain HTTP. Unfortunately, the browser would send the cookie for both (so the attacker would be able the cookie then). I've seen it happen, even if the image in question wasn't even there (the browser would send the request with the cookie to the server, even if it returned a 404 not found).