如何保护ASP.NET或ASP.NET MVC免受相关域cookie攻击?

时间:2012-03-09 15:44:40

标签: asp.net security cookies ssl same-origin-policy

related domain cookie attack (more info)允许同一DNS域中的计算机添加其他Cookie,这些Cookie也将发送到同一域中的其他计算机。

这可能会导致身份验证问题,或者最糟糕的情况是混乱的副攻击中的一个组成部分。

问题

如何保护ASP.NET或ASP.NET MVC免受此类攻击?

一种可能的攻击方案

  1. 我登录“安全”网络应用
  2. 我获得了帐户的凭据
  3. 我欺骗用户访问我在同一DNS域中的网站
  4. 我插入了cookie(我的信用卡)
  5. 用户返回您的应用。
  6. 两个cookie(或被覆盖的cookie)都被发送到服务器
  7. 用户正在我的帐户下执行操作
  8. 这是一个简化的例子,但这个想法可以移植到其他类型的攻击中,我只是选择看起来并不“太糟糕”的场景。

    如果这是两步攻击的第一步,那么它是如何“变坏”的一个想法。假设用户上传了一个只能在他的帐户中访问的错误文件;然后另一个用户无意中下载该文件,运行那里的任何可执行代码。

    还有很多其他可能的场景......而不是在这里列出所有场景我试图找出如何保护我的服务器免受此类攻击。

7 个答案:

答案 0 :(得分:7)

频道限制Cookie

以下提议的RFC来自Google员工,描述了客户使用自签名浏览器证书的方式(因此不需要为最终用户带来混淆和#34;弹出"这也可以解决cookie安全问题称为"相关域Cookie"

下面是http://www.browserauth.net/的摘录,RFC的一部分,一些有趣的评论,以及对此扩展的一些批评。

渠道约束Cookie概述

一旦底层TLS通道使用TLS客户端身份验证(使用TLS-OBC扩展),服务器可以通过将其与客户端的公钥相关联来将其cookie绑定到TLS通道,并确保cookie是仅使用通过公共(客户端)密钥验证的TLS通道。

这意味着如果这样一个通道绑定的cookie从客户机器上被盗,那么该cookie就无法从其他机器验证到服务器的HTTP会话。这包括将自己注入客户端和服务器之间连接的中间人攻击者,可能是通过欺骗用户点击证书不匹配警告:这样的中间人将不得不生成自己的TLS会话与服务器,它不匹配cookie绑定它的频道。

频道绑定

由服务器决定是否将Cookie绑定到TLS通道。如果客户端不支持TLS-OBC,或者即将设置的cookie将用于不同的origins,则服务器不会对Cookie进行通道绑定。如果确实决定对cookie进行通道绑定,则应将cookie与客户端的公钥相关联。这是similar to RFC 5929,,但在这种情况下,服务器不是客户端binding data to the server's public key,,而是将数据(cookie)绑定到客户端的公钥。服务器可以通过简单地在后端数据库中存储某个HTTP会话预期使用某个客户端公钥进行身份验证的事实来实现这一点,或者它可以使用合适的加密来编码cookie本身哪个TLS客户端公共cookie绑定的密钥。

Illustration of a secure session between a server and browser

在上图中,服务器将客户端的公钥包括到加密签名的数据结构中,该数据结构还包括经过身份验证的用户ID。当服务器从客户端收回cookie时,它可以验证它确实发出了cookie(通过检查cookie上的签名),并验证cookie是否通过正确的通道发送(通过将TLS客户端密钥与cookie中提到的密钥)。

要继续...... http://www.browserauth.net/channel-bound-cookies


RFC Snip

  

TLS Origin-Bound Certificates RFC Draft

     

(摘录)

     

<强> 4.3。 Cookie强化

     

TLS-OBC可用于加强基于cookie的一种方式   身份验证是通过&#34;绑定&#34;饼干到原产地   证书。服务器在为HTTP发出cookie时   会话,将客户端的原始绑定证书与   会话(通过编码有关证书的信息   在cookie中不可伪造,或通过将证书与   通过其他方式进行cookie的会话)。那样的话,如果和   当一个cookie从客户端被盗时,它不能被用于   由不同客户端发起的TLS连接 - cookie小偷   还必须窃取与之关联的私钥   客户端的原始绑定证书,这项任务要困难得多   特别是当我们假设存在可信平台时   可以存储的模块或其他安全元素   origin-bound-certificate的私钥。


  

Additional Commentary from public-web-security@w3.org

另外,请注意,有些反直觉的是,通道绑定cookie可防止许多相关域攻击,即使客户端证明它们受到限制的范围也比Web源更广。

想象一下,用户代理创建了一个单一的自签名证书,它用作所有服务器的所有连接的TLS客户端证书(在隐私方面不是一个好主意,但请关注我这个思想实验)。然后,服务器在各自的顶级域上设置cookie,但将它们绑定到用户代理的唯一客户端证书。

所以,让我们说应用程序app.heroku.com在我的浏览器上为域.heroku.com设置一个(通道绑定)cookie,并且在attacker.heroku.com上有一个攻击者。我们可能关注的一个攻击是,攻击者只是通过引诱我到attacker.heroku.com从我的浏览器中收集.heroku.com cookie。然而,他们无法实际使用 Cookie,因为Cookie是通道绑定到我的浏览器的客户端证书,而不是攻击者的客户端证书。

我们可能关注的另一个攻击是,attacker.heroku.com 在我的用户代理上设置了 .heroku.com cookie,以便让我自己登录app.heroku.com。同样,假设攻击者获取cookie的唯一方法是从app.heroku.com获取cookie,这意味着他所拥有的cookie将被通道绑定到他的客户端证书,而不是我的客户证书 - 因此,当我的浏览器将它们发送到app.heroku.com时,它们将无法生效。

当然,TLS-OBC提案假设更细粒度的范围&#34;为客户证书。然而,其原因纯粹是为了防止在不相关的域之间进行跟踪。即使我们使用粗粒度客户端证书和粗粒度(即域)cookie,相关域攻击也已得到缓解。至少,我起初发现这有点违反直觉,因为另一个提议防御它完全禁止粗粒度cookie并使用原始cookie代替。


  

Criticism from public-web-security@w3.org

TLS-OBC需要考虑许多问题;我会在这里强调一下我所知道的一对。

  1. 某些SSL握手逻辑可能需要稍微修改;请参阅https://bugzilla.mozilla.org/show_bug.cgi?id=681839进行技术讨论。

  2. 有潜在的隐私考虑因素;特别是如果在主秘密协商之前以明文方式发送唯一客户端证书,则被动网络观察者可能能够唯一地识别客户端机器。攻击者已经拥有客户端的IP地址,因此如果在IP地址更改时重新生成证书,这不是一个大问题,但这会使许多身份验证权益无效。建议允许在进行主密钥协商后发送客户端证书。 (现在无法找到错误,对不起)

  3. 有关#2如何解决的建议如下:http://tools.ietf.org/html/draft-agl-tls-encryptedclientcerts

  4. 与SPDY有棘手的互动。 browserauth.net上会有更新。

答案 1 :(得分:3)

修复RFC

这里的核心问题似乎是任何主机都可以编写一个可以被同一域中的任何其他主机覆盖的cookie。如果有一种方法可以将值写入客户端,绝对不能被任何其他主机覆盖,该怎么办?我还没有发现任何类似的东西也会自动包含在HTTP标头中(如cookie)

以下三种解决方案可能有效,但如果浏览器正确实现它,我喜欢解决方案2或#3


解决方案1:在将Cookie上传到服务器时添加更多信息

当客户端向服务器发送cookie时,还包括已发送的cookie的域。然后,服务器知道要查找的域和路径。这意味着客户端会在每个请求上添加新的HTTP标头Cookie-Details

GET /spec.html HTTP/1.1
Host: www.example.org
Cookie: name=value; name2=value2
Cookie-Details: name="value":"domain":"path":"IsSecure":"IsHTTPOnly"; name2="value2":"domain2":"path2":"IsSecure":"IsHTTPOnly"
Accept: */*

然后,服务器可以忽略详细信息字段,或者优先于不提供详细信息的字段。我在详细信息部分中包含“值”字段的原因是,如果两个Cookie都将域设置为example.comsecure.example.com,那么服务器将无法区分它们同名。大多数浏览器会以随机顺序发送值。

也许这可以进行优化,以便服务器可以告诉客户端是否支持这种新的cookie格式,并且客户端可以做出相应的响应。


解决方案2:扩展HTML5 LocalStorage,以便(可选)自动将数据插入HTTP标头

如果我们可以扩展HTML5的LocalStorage以允许安全/ HTTPOnly数据,我们可以模仿上面的解决方案#1中所执行的操作,但是由HTML5 LocalStorage W3C工作组驱动更改

这样做的好处是,与#1解决方案相比,开销更少,因为更详细的cookie详细信息仅在需要时才发送到服务器。换句话说,如果使用“新cookie详细信息”格式将敏感值保存到LocalStorage中,则可以明确区分需要发送的数据以及采用何种格式。


解决方案3 “Cookie验证”

  1. 用户访问启用了“特殊”验证模式的网络应用。
  2. 在HTTP响应中,一些cookie被发送到浏览器。 Cookie可以是HTTP Only,Secure,......任何内容)
  3. 除了Cookie之外,还会向Cookie发送另一个标头:Set-CookieValidationHash。它包含一个SHA-256散列cookie密钥和值的JSON数组,并指定值的到期时间
  4. 然后,浏览器在逻辑上将此标头绑定到具有以下行为的cookie
    • 此标头放入“Cookie验证jar”,只能由相同的DNS域和DNS范围写入
  5. 此标头对客户端不透明,并在每个HTTP请求(如cookie)上返回给服务器
  6. 服务器将使用此字段验证发送的cookie,并在校验和失败时发出错误(或其他)。

答案 2 :(得分:3)

  

来自:http://www.w2spconf.com/2011/papers/session-integrity.pdf

<强> 5.2。通过自定义标题完整性

我们可以实现会话完整性,而不是保护cookie 通过选择存储和传输会话的新方法 州。虽然这可以使用特殊的浏览器插件来完成 像Flash一样,我们宁愿选择最少的设计 依赖关系,所以我们只关注基本的HTTP工具。 HTTP请求的基本形式很少 适用于完整地发送数据。 URL中的数据 或者HTTP请求的实体主体没有完整性,因为 HTTP请求的那些部分可以跨源创建 因此攻击者可以欺骗。饼干也很薄弱 这方面,因为他们可以被我们的攻击者覆盖 威胁模型。但是,通过使用JavaScript API 称为XMLHttpRequest(XHR),我们可以自定义发送数据 报头中。

背景。 XMLHttpRequest(XHR)允许HTTP 请求包含要制作的自定义标头,以及 响应读取,但仅限于执行的起源 JavaScript。(参见注释5)因此,通过XHR发出的请求可以是 由服务器区分,必须源自 网站本身。

设计。我们根本不会使用Cookie,而是通过 在自定义HTTP标头中标识令牌的会话 只能通过XMLHttpRequest编写。服务器应该对待所有 请求缺少此自定义标头或包含无效 令牌,属于新的匿名会话。为了 持久化此会话,在浏览器重新启动时识别令牌 在同一个应用程序的不同页面之间,令牌 可以通过JavaScript存储在HTML5 localStorage中 验证成功。

安全性。请注意,在此模型中,会话标识令牌只会被发送到源服务器,并且 不包含在URL或实体主体中。这些属性 分别提供保密和完整性。不像 cookie,令牌不能被攻击者覆盖,因为 localStorage在源中完全分区数据 大多数浏览器(见注6)。使用HTTPS的站点可以确保令牌 只通过HTTPS发送,从而确保了保密 即使存在活动网络攻击者,也可以使用令牌。在 另外,因为这个令牌不是由自动发送的 浏览器,它还可以防止CSRF攻击。

缺点。然而,这种方法有几个缺点。首先,它需要所有需要访问的请求 使用XMLHttpRequest创建用户的会话。仅仅 向所有请求明确添加会话标识令牌, 更不用说在XHR上做这些了,需要做出重大改变 大多数现有的网站,并且会很麻烦 难以在没有框架的情况下正确实现。这个 如果要求子资源,则更加复杂 图像需要访问会话状态,因为它不是微不足道的 通过XHR加载图像。第三,由于这种设计取决于 HTML5 localStorage的存在和安全性,它将是 在某些传统浏览器上无法实现

(注5)如果受到支持,网站可以使用XHR进行跨站请求 浏览器并由目标服务器授权

(注6)在OS X上的Chrome,Firefox,Safari和Opera中都是如此,有几个Linux 分发和Windows 7.Internet Explorer 8不对HTTP进行分区 和HTTPS,但Internet Explorer 9可以。

答案 3 :(得分:2)

  

Source: W3C Mailing Lists

IETF TLS working group has a proposal to bind cookies to TLS client certificates,因此只要与证书对应的私钥仅在一台计算机上,cookie就只能在一台计算机上使用。

如果要模拟TLS客户端证书方法,可以使用localStorage存储私钥,并使用JS crypto 1将document.cookie替换为签名版本。它有点笨重,但它可能会起作用。 (显然,使用网络加密2

会更好

1例如:http://www.ohdave.com/rsa/

2 http://www.w3.org/community/webcryptoapi/

答案 4 :(得分:0)

来自http://www.codeproject.com/Articles/16645/ASP-NET-machineKey-Generator

  

每当您使用ViewState,Session,Forms身份验证或其他加密和/或安全值时,ASP.NET都会使用一组密钥来执行加密和解密。通常,每次应用程序回收时,这些键都会被ASP.NET隐藏并自动生成

如果两个网站是不同的网络应用程序,默认情况下它们将具有不同的密钥,因此一个人将无法读取另一个网站生成的加密令牌。例外情况是它们在全局web.config或machine.config中使用公共值。

从machineKey元素,decryptionKey:http://msdn.microsoft.com/en-us/library/w8h3skw9.aspx

  

AutoGenerate,IsolateApps指定自动生成密钥。这是默认值。 AutoGenerate修饰符指定ASP.NET生成随机密钥并将其存储在本地安全机构(LSA)中。 IsolateApps修饰符指定ASP.NET使用每个应用程序的应用程序ID为每个应用程序生成唯一的加密密钥。

因此,除非使用machineKey元素在全局级别设置decryptionKey,否则您描述的方法不起作用。如果已设置,则可以使用web.config文件在应用程序级别覆盖。

答案 5 :(得分:-1)

您可以在应用程序的web.config中设置唯一的machineKey。这样,只能解密该应用程序发出的身份验证cookie。如果用户访问同一域中的恶意站点,则该其他站点可能确实添加了具有相同名称但值不同的cookie身份验证cookie,但它无法使用您使用的相同计算机密钥对其进行加密和签名。应用程序以及当用户导航回来时,将抛出异常。

答案 6 :(得分:-2)

答案很简单:始终将会话绑定到特定的客户端IP(这应该在任何现代Web应用程序中完成),不要将cookie用于任何其他目的。

说明:您总是将一个SESSIONID cookie发送回客户端,该客户端不包含任何信息 - 它只是一个非常长的随机字符串。您将SESSIONID与经过身份验证的用户IP一起存储在您的webapps范围内 - 例如数据库。虽然相关的cookie攻击可以用来在不同的客户端之间交换SESSIONID cookie,但是没有客户端可以伪装成另一个用户或执行任何操作,因为SESSIONID只被认为是有效的,并且只有在从相关联的发送时才授予权限。 IP地址。

只要你不存储被认为是私有的实际数据到cookie本身,而是存储在服务器端的会话状态(仅由SESSIONID cookie选择),相关的cookie问题对你来说应该没问题