9

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

DotNet98
  • 727
  • 3
  • 12
  • 24

1 Answers1

17

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.

scottt732
  • 3,877
  • 2
  • 21
  • 23
  • Regarding session highjacking, will the AuthCookie be compromised, if some parts of my site is public and some secure ie https (only accessible to logged in users). I'm asking this because I know once the AuthCookie is created it goes back and forth on every client-server call. is there a way to avoid that on certain pages? My plan is to register the authentication step as a filter in my app_start; and make some actions [anonymous]... your thoughts (thanks for your wonderful answer btw!) – DotNet98 Apr 25 '14 at 19:56
  • You can use the Path option in system.web/authorization/forms to cause the cookie to only be presented for a certain path on your site. Unfortunately, you're limited to 1 path. So if you have a section of your site that you want to allow anonymous access to and another that requires authentication/authorization, you could put all of the secure content under a separate path and restrict the cookie to that path. You would still want to set it to secure and http only. The cookie path is the most reliable way to make sure that your cookie doesn't move over a clear channel. – scottt732 Apr 25 '14 at 20:22
  • yeah, seems like https is the way to go. I guess I can have https pages without authenticating the user; I presume this'll have a performance impact given the nature of https. Will you shed some light as to what happens with my AJAX calls then? will I need to do anything specific to protect my Ajax calls (will AuthCookie travel along with my ajax calls) – DotNet98 Apr 25 '14 at 20:38
  • I would try HTTPS out and see if you notice the performance impact. I run a handful of relatively low-traffic sites all 100% SSL and I don't notice anything. Your AJAX calls should pass the auth cookie over. It's ultimately the browser just making another HTTP request. You can make a simple service to verify and return User.Identity.IsAuthenticated. If you see 'true', Forms Auth should be working fine for your AJAX calls. – scottt732 Apr 27 '14 at 18:23
  • hmm, that's a good plan. I'm not sure if I should open up another question of if you have some insight on impact of putting 100% of the site under HTTPs and SEO? – DotNet98 Apr 28 '14 at 16:03
  • I'm not really an SEO guy, but it don't think you'd get penalized for doing SSL only. You can still leave port 80 open, but set it up as a redirect to 443. IIS has an option built in for this or you can use URL Rewrite tool if you need more control. With the formsAuth cookie set to requireSSL, the cookie won't go over an unsecure channel. Note that the web.config attribute is requireSSL="true", not secure="true" (sorry). I'd probably open another question about the SEO stuff so you can get someone with more expertise in that area to chime in. – scottt732 Apr 28 '14 at 17:12
  • ok will do. you've definitely provided valuable info here; thanks. I'll see what I can find out regarding SEO and SSL through another question. thanks again! – DotNet98 Apr 28 '14 at 17:25
  • So why do they say [here - last line](http://www.asp.net/web-api/overview/security/forms-authentication) _Forms authentication does not encrypt the user’s credentials._ – Royi Namir Oct 13 '14 at 20:00
  • The form post that typically results in a FormsAuthenticationTicket/Cookie being generated (clicking login after typing your username and password) is a standard HTTP POST. Your first & best line of defense here is to use HTTPS when submitting this form so that this goes between client & server encrypted. The discussion above has to do with properties of the FormsAuthenticationCookie, which gets created after this step & is what prevents you from having to login again on each subsequent request. The cookie recommendations are to help avoid session hijacking & increase overall site security. – scottt732 Oct 13 '14 at 20:35
  • @scottt732 Is it possible for you to put some light on "If the ticket hasn't expired, an IIdentity and IPrincipal are created and assigned to HttpContext.Current.User". I'm more interested to know at what time .NET assigns ticket data to IPrincipal and what information it takes from there(ticket). Also, can we store {userdata}(of ticket) in such a way that .NET itself takes that information from cookie to set roles in IPrincipal. – RollerCosta Jan 23 '17 at 11:27