Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flagging cookies as "secure" in forms auth when the website is behind a load balancer serving the TLS cert

Recently I had a bit of a problem with a site on AppHarbor which I wrote about on their support forums: Request.IsSecureConnection always returns false

In short, because the load balancer is decrypting the HTTPS traffic before it hits the web app, attributes such as Request.IsSecureConnection and configuration like requireSSL on forms auth is not behaving as expected. In fact in the latter case, you can't even authenticate as the app thinks the request isn't coming over HTTPS.

It's the forms auth which is especially problematic because without it, cookies aren't set to "secure" and are sent back over HTTP if the site is accessed by domain name only and implicitly serves up the insecure URL scheme.

What would be the best workaround for this? I'd prefer to leverage the native security configuration, can anyone see a way to override the implementation which checks if the connection is secure? It's easy enough to detect whether the request was served over HTTPS (either based on Request.Url.Scheme or the X_FORWARDED_FOR header), it's just a question of neatly tying this in.

like image 625
Troy Hunt Avatar asked Nov 29 '11 07:11

Troy Hunt


2 Answers

Alternatively, you can use the URL rewrite module to trick ASP.NET into thinking that it is running under a HTTPS context, and leave the requireSSL flags in place (which means the cookies will be set as secure - and only available if you really are running under HTTPS)

You can set the following in your web.config:

    <rewrite>
        <rules>
            <rule name="HTTPS_AlwaysOn" patternSyntax="Wildcard">
                <match url="*" />
                <serverVariables>
                    <set name="HTTPS" value="on" />
                </serverVariables>
                <action type="None" />
            </rule>
        </rules>
    </rewrite>

You'll also need to add HTTPS to the list of allowedServerVariables in the applicationHost.config (or through the URL REwrite config)

        <rewrite>
            <allowedServerVariables>
                <add name="HTTPS" />
            </allowedServerVariables>
        </rewrite>

With thanks to Levi Broderick on the ASP.NET team who sent me in the right direction to this solution!

like image 152
James Crowley Avatar answered Oct 06 '22 00:10

James Crowley


Turn off the RequireSSL setting and add the following code to your app. This should secure your authentication/session cookies.

void Application_EndRequest(object sender, EventArgs e)
{
    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;
            }
        }
    }
}
like image 27
Chris Avatar answered Oct 06 '22 00:10

Chris