使用requireSSL = true表单身份验证不返回具有Secure属性的cookie

Lee*_*eco 12 asp.net security iis asp.net-mvc

我现在看到我们的IIS站点出现了一个奇怪的响应,我们已经将主机从Win2K3/IIS6升级到Win2k8R2/IIS7.5.ASP.Net 4.0版

我们有一个非常复杂和成熟的Web应用程序,它使用带有以下配置的Forms Authentication:

<authentication mode="Forms">
  <forms loginUrl="~/Login" timeout="2000" domain="xx.xx.com" requireSSL="true" />
</authentication>
Run Code Online (Sandbox Code Playgroud)

登录URL指向为SSL正确配置的ASP.Net MVC 3页面.

该站点在IIS6中的行为符合预期,但自主机迁移以来,在成功登录后,响应头中的auth cookie缺少Secure和HttpOnly属性.这是有问题的,因为我们有一个包含许多HTTP页面的混合内容站点.auth cookie现在在每个请求中发送,而不仅仅是在通过HTTPS的请求中发送,现在对会话窃取漏洞开放.

我们的Logoff链接成功发送了包含Secure和HttpOnly属性的零长度cookie.

这是成功登录并从Fiddler注销后的原始响应,编辑以保护无辜者:)

Login Response:

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: application/json; charset=utf-8
Set-Cookie: .ASPXAUTH=83FCCA...102D; domain=xx.xx.com; path=/
Date: Fri, 25 Jan 2013 22:53:31 GMT
Content-Length: 84

{...}


Logoff Response:

HTTP/1.1 302 Found

Cache-Control: private
Content-Type: text/html; charset=utf-8
Location: http://xx.xx.com/?...
Set-Cookie: .ASPXAUTH=; domain=xx.xx.com; expires=Tue, 12-Oct-1999 04:00:00 GMT; path=/; secure; HttpOnly
Set-Cookie: logoff=; path=/
Set-Cookie: ...
Date: Fri, 25 Jan 2013 22:57:01 GMT
Content-Length: 64053

<html><head><title>...
Run Code Online (Sandbox Code Playgroud)

更改应用程序池的"集成管道"设置无效.

以下是cookie创建代码的重要部分:

    var ctx = HttpContextFactory.Current;

    var cookie = new HttpCookie(
        FormsAuthentication.FormsCookieName,
        FormsAuthentication.Encrypt(
            new FormsAuthenticationTicket(
                SessionId,
                false,
                Convert.ToInt32(FormsAuthentication.Timeout.TotalMinutes)
            )
        )
    ) { Domain = domain };

    ctx.Response.Cookies.Add(cookie);
Run Code Online (Sandbox Code Playgroud)

有关从哪里开始寻找造成这种情况的想法?

Dar*_*rov 12

当您发出表单身份验证cookie时,您设置的所有内容都是域名.我看不到你在任何地方设置安全标志.因此,如果您希望使用secure和httponly标志设置cookie,请确保在创建此cookie时指定了它们:

var cookie = new HttpCookie(
    FormsAuthentication.FormsCookieName,
    FormsAuthentication.Encrypt(
        new FormsAuthenticationTicket(
            SessionId,
            false,
            Convert.ToInt32(FormsAuthentication.Timeout.TotalMinutes)
        )
    )
) 
{ 
    Domain = domain,
    HttpOnly = true,
    Secure = FormsAuthentication.RequireSSL
};
Run Code Online (Sandbox Code Playgroud)

由于您是手动创建表单身份验证cookie(而不是使用FormsAuthentication.SetAuthCookieFormsAuthentication.GetAuthCookie内置方法),因此web.config中的设置无效.您需要显式设置它们,如我的示例所示.