86

I have set the .ASPXAUTH cookie to be https only but I am not sure how to effectively do the same with the ASP.NET_SessionId.

The entire site uses HTTPS so there is no need for the cookie to work with both http and https.

Pete
  • 1,388
  • 2
  • 13
  • 18
  • [How to mark Session Cookie Secure](http://anubhavg.wordpress.com/2008/02/05/how-to-mark-session-cookie-secure/) – Pankaj May 12 '11 at 13:33

7 Answers7

191

To add the ; secure suffix to the Set-Cookie http header I simply used the <httpCookies> element in the web.config:

<system.web>
  <httpCookies httpOnlyCookies="true" requireSSL="true" />
</system.web>

IMHO much more handy than writing code as in the article of Anubhav Goyal.

See: http://msdn.microsoft.com/en-us/library/ms228262(v=vs.100).aspx

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
Marcel Hoyer
  • 2,048
  • 2
  • 13
  • 10
  • 2
    http://msdn.microsoft.com/en-us/library/ms228262(v=vs.100).aspx (This MSDN topic is not available for .NET 4.5 at the moment.) – Lars Kemmann Nov 07 '12 at 20:59
  • 11
    Marcel Hoyer, I tried your method but somehow it just does not work. The `asp.net_sessionid` is still not in `secure`. Does your method apply to an MVC web application? – Blaise May 15 '13 at 18:42
  • @Blaise, I didn't try this for an MVC web app. Did anyone else? – Marcel Hoyer May 15 '13 at 22:38
  • 2
    I know this is old, but I had to implement this in an MVC4 project, and it works great. Added the secure; flag to the cookie. – puddinman13 Mar 06 '14 at 19:34
  • 23
    For those that configure web.config correctly and the ASP.NET_SessionId is still not flagged Secure, be sure to clear your cookies for the site before testing again. Just because you're signed out/not authenticated doesn't mean you'll get a new session cookie. – Adam Caviness Oct 27 '16 at 16:54
  • will this allow the cookie to work if the site is requested via http rather than https? – Doan Vu Jul 04 '17 at 04:37
  • @VuDoan I guess this makes no sense as `; secure` directive is meant to work only with SSL. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie#Directives – Marcel Hoyer Jul 04 '17 at 11:59
  • 1
    Confirmed still working with .NET 4.8 framework MVC 5 site. – seagulledge Jun 24 '22 at 18:22
51

Here is a code snippet taken from a blog article written by Anubhav Goyal:

// this code will mark the forms authentication cookie and the
// session cookie as Secure.
if (Response.Cookies.Count > 0)
{
    foreach (string s in Response.Cookies.AllKeys)
    {
        if (s == FormsAuthentication.FormsCookieName || "asp.net_sessionid".Equals(s, StringComparison.InvariantCultureIgnoreCase))
        {
             Response.Cookies[s].Secure = true;
        }
    }
}

Adding this to the EndRequest event handler in the global.asax should make this happen for all page calls.

Note: An edit was proposed to add a break; statement inside a successful "secure" assignment. I've rejected this edit based on the idea that it would only allow 1 of the cookies to be forced to secure and the second would be ignored. It is not inconceivable to add a counter or some other metric to determine that both have been secured and to break at that point.

Brian
  • 25,523
  • 18
  • 82
  • 173
Joel Etherton
  • 37,325
  • 10
  • 89
  • 104
  • 5
    Perfect, thank you. For anyone reading this who might think it looks like a dodgy work-around, as I did when I first saw it, I haven't found anything to suggest there is a better option and this seems to work well! – Pete May 13 '11 at 08:58
  • 1
    note that the sessionState cookie name might not always be `ASP.NET_SessionId`. It can be overridden http://msdn.microsoft.com/en-us/library/h6bb9cz9.aspx – kenwarner Jun 09 '11 at 03:04
  • @qntmfred: The link you provided is no longer available. Can you provide some search hints, so I can find the original microsoft article, please? – Matt Oct 06 '14 at 10:48
  • Note that the Response.Cookies collection is empty at the beginning of every request. If you need to do this to pre-existing cookies, fetch them from Request.Cookies. http://www.chwe.at/2009/01/don-t-use-response.cookies-string--to-check-if-a-cookie-exists/ – EriF89 Dec 08 '15 at 16:37
  • 1
    @EriF89: This functionality is not useful in the BeginRequest. When used in the EndRequest the cookies collection should not be empty (if it is you have bigger problems than securing a cookie). Your comment really has no bearing on the topic. – Joel Etherton Dec 08 '15 at 16:40
  • 1
    this requires a reference to system.web.security. also it is the Application_EndRequest event handler (or similar) so protected void Application_EndRequest(object sender, EventArgs e) { etc... – nuander Mar 13 '17 at 17:25
  • 2
    Updated link to Session State configuration documentation is here: (bizarrely the 3.0 version is not archived, but most of the others are) https://msdn.microsoft.com/en-us/library/h6bb9cz9(v=vs.85).aspx. On top of that, as [Marcel Hoyer notes in his answer](https://stackoverflow.com/a/8968880/33051) you should be able to set `requireSSL="true"` in the `httpCookies` element and this will work - you may need to clear your existing cookies first before you see the change. – Zhaph - Ben Duguid Jan 23 '18 at 15:07
  • You may also want to do the same for `Roles.CookieName` – David De Sloovere Apr 18 '18 at 09:20
  • 2
    It may be tempting to bypass the loop in favor of somehow using the indexing operator. However, calling the indexing operator on `Response.Cookies` actually creates a cookie, if one does not already exist. Note that, per my post edit, it is not possible to use the safe navigation operator as an assignment target. – Brian Aug 27 '19 at 13:52
17

Going with Marcel's solution above to secure Forms Authentication cookie you should also update "authentication" config element to use SSL

<authentication mode="Forms">
   <forms ...  requireSSL="true" />
</authentication>

Other wise authentication cookie will not be https

See: http://msdn.microsoft.com/en-us/library/vstudio/1d3t3c61(v=vs.100).aspx

Raghu A
  • 411
  • 4
  • 4
  • 2
    This secures the Form Auth. cookie only right? It is not suppose to secure the session cookie which was the actual question here. – Rahatur Feb 11 '19 at 11:35
11

Found that setting the secure property in Session_Start is sufficient, as recommended in MSDN blog "Securing Session ID: ASP/ASP.NET" with some augmentation.

    protected void Session_Start(Object sender, EventArgs e)
    {
        SessionStateSection sessionState = 
 (SessionStateSection)ConfigurationManager.GetSection("system.web/sessionState");
        string sidCookieName = sessionState.CookieName;

        if (Request.Cookies[sidCookieName] != null)
        {
            HttpCookie sidCookie = Response.Cookies[sidCookieName];
            sidCookie.Value = Session.SessionID;
            sidCookie.HttpOnly = true;
            sidCookie.Secure = true;
            sidCookie.Path = "/";
        }
    }
Doug Domeny
  • 4,410
  • 2
  • 33
  • 49
3

It is also worth considering:

Using cookie prefixes

__Secure-, which signals to the browser that the Secure attribute is required.

__Host-, which signals to the browser that both the Path=/ and Secure attributes are required, and at the same time, that the Domain attribute must not be present.

A good article on why this helps

https://check-your-website.server-daten.de/prefix-cookies.html


Renaming your cookies

Instead of using names that clearly identify programming language.

e.g

ASP.NET_SessionId = __Secure-SID


Using samesite settings

sameSite="Lax"

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite


Make cookie https secure

requireSSL="true"


SECURE EXAMPLE

<sessionState cookieless="false" cookieName="__Secure-SID" cookieSameSite="Lax" />
<httpCookies httpOnlyCookies="true" sameSite="Lax" requireSSL="true" />
DreamTeK
  • 32,537
  • 27
  • 112
  • 171
2

Adding onto @JoelEtherton's solution to fix a newly found security vulnerability. This vulnerability happens if users request HTTP and are redirected to HTTPS, but the sessionid cookie is set as secure on the first request to HTTP. That is now a security vulnerability, according to McAfee Secure.

This code will only secure cookies if request is using HTTPS. It will expire the sessionid cookie, if not HTTPS.

    // this code will mark the forms authentication cookie and the
    // session cookie as Secure.
    if (Request.IsSecureConnection)
    {
        if (Response.Cookies.Count > 0)
        {
            foreach (string s in Response.Cookies.AllKeys)
            {
                if (s == FormsAuthentication.FormsCookieName || s.ToLower() == "asp.net_sessionid")
                {
                    Response.Cookies[s].Secure = true;
                }
            }
        }
    }
    else
    {
        //if not secure, then don't set session cookie
        Response.Cookies["asp.net_sessionid"].Value = string.Empty;
        Response.Cookies["asp.net_sessionid"].Expires = new DateTime(2018, 01, 01);
    }
Jonathan Harris
  • 403
  • 6
  • 10
-4

If the entire site uses HTTPS, your sessionId cookie is as secure as the HTTPS encryption at the very least. This is because cookies are sent as HTTP headers, and when using SSL, the HTTP headers are encrypted using the SSL when being transmitted.

Nick Berardi
  • 54,393
  • 15
  • 113
  • 135
  • 17
    Keep in mind though that if a user were to type the URL into the browser "www.securesite.com", the initial request to that server (including any cookies) would be unsecure; The server will presumably respond with a redirect to the SSL site, after which you are correct. – Chris Shaffer May 12 '11 at 14:20
  • 3
    This makes sense but unfortunately the testers our client use do not see it that way :) – Pete May 13 '11 at 08:58
  • "the HTTP headers are encrypted using the SSL when being transmitted" does this mean that the channel is encrypted or that the actual cookie content is encrypted? – Larry Hipp May 25 '11 at 19:05
  • Example header: Set-Cookie: Cookiekey=CookieDate Is CookieKey=CookieData encrypted? – Larry Hipp May 25 '11 at 19:07
  • 2
    This is only true if HTTP access is denied, or redirected. Even if this is the case, setting the cookie is an added fail-safe. – Spongeboy Apr 09 '13 at 05:23
  • Though potentially a good point, this doesn't answer the question – Liam Oct 02 '15 at 08:21
  • 4
    @Spongeboy Actually it's not even true in those scenarios. If there were a man-in-the-middle, they'd already have a copy of the cookie before the server returned a redirect status code. – Richard Szalay Sep 25 '17 at 04:41