[英]How can ASP.NET or ASP.NET MVC be protected from related domain cookie attacks?
相关域cookie攻击(更多信息)允许同一DNS域中的计算机添加其他cookie,这些cookie也将发送到同一域中的其他计算机。
这可能会导致身份验证问题,或者最糟糕的情况是混乱的副攻击中的一个组件。
题
如何保护ASP.NET或ASP.NET MVC免受此类攻击?
一种可能的攻击方案
这是一个简化的例子,但这个想法可以移植到其他类型的攻击中,我只是选择看起来并不“太糟糕”的场景。
如果这是两步攻击的第一步,那么它是如何“变坏”的一个想法。 假设用户上传了一个只能在他的帐户中访问的错误文件; 然后另一个用户无意中下载该文件,运行那里的任何可执行代码。
还有很多其他场景是可能的......而不是在这里列出所有场景我试图找出如何保护我的服务器免受此类攻击。
渠道限制饼干
以下提议的RFC来自Google员工,描述了客户端使用自签名浏览器证书的方式(因此不需要为最终用户提供令人困惑的“弹出”),这也可以解决称为“相关域”的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将在不同的源上使用 ,则服务器将不会对cookie进行通道绑定。 如果确实决定对cookie进行通道绑定,则应将cookie与客户端的公钥相关联。 这与RFC 5929类似,但不是客户端将数据绑定到服务器的公钥,在这种情况下,服务器将绑定数据(cookie)绑定到客户端的公钥。 服务器可以通过简单地在后端数据库中存储某个HTTP会话预期使用某个客户端公钥进行身份验证的事实来实现这一点,或者它可以使用合适的加密来编码cookie本身哪个TLS客户端公共cookie绑定的密钥。
在上图中,服务器将客户端的公钥包含到加密签名的数据结构中,该数据结构还包括经过身份验证的用户ID。 当服务器从客户端收回cookie时,它可以验证它确实发出了cookie(通过检查cookie上的签名),并验证cookie是否通过正确的通道发送(通过将TLS客户端密钥与cookie中提到的密钥)。
在这里继续.... http://www.browserauth.net/channel-bound-cookies
RFC Snip
TLS Origin-Bound Certificates RFC草案
(摘抄)
4.3。 Cookie强化
TLS-OBC可用于加强基于cookie的身份验证的一种方法是将cookie“绑定”到原始绑定证书。 当为HTTP会话发出cookie时,服务器会将客户端的源自原始证书与会话相关联(通过在cookie中不可伪造地编码有关证书的信息,或通过其他方式将证书与cookie的会话相关联) 。 这样,如果cookie从客户端被盗,它就不能在不同客户端发起的TLS连接上使用 - cookie窃贼也必须窃取与客户端的原始绑定证书相关的私钥,这是一项任务特别是当我们假设存在可信平台模块或其他可以存储的安全元素时,会更加困难
origin-bound-certificate的私钥。
此外,请注意,有些反直觉的是,通道绑定cookie可防止许多相关域攻击,即使客户端证明它们受到限制的范围也比Web源更广。
想象一下,用户代理创建了一个单一的自签名证书,它用作所有服务器的所有连接的TLS客户端证书(在隐私方面不是一个好主意,但请跟我一起进行这个思想实验)。 然后,服务器在各自的顶级域上设置cookie,但将它们通道绑定到用户代理的一对一客户端证书。
所以,假设app 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提案假定客户端证书具有更细粒度的“范围”。 然而,其原因纯粹是为了防止在不相关的域之间进行跟踪。 即使我们使用粗粒度客户端证书和粗粒度(即域)cookie,相关域攻击也已得到缓解。 至少,我起初发现这有点违反直觉,因为另一个提议防御它完全禁止粗粒度cookie并使用原始cookie代替。
TLS-OBC需要考虑许多问题; 我会在这里强调一下我所知道的一对。
某些SSL握手逻辑可能需要稍微修改; 有关技术讨论,请参阅https://bugzilla.mozilla.org/show_bug.cgi?id=681839 。
有潜在的隐私考虑; 特别是如果在主秘密协商之前以明文方式发送唯一客户端证书,则被动网络观察者可能能够唯一地识别客户端机器。 攻击者已经拥有客户端的IP地址,因此如果在IP地址更改时重新生成证书,这不是一个大问题,但这会使许多身份验证优势无效。 建议允许在进行主密钥协商后发送客户端证书。 (现在找不到bug,对不起)
关于#2如何解决的一个提议是: http : //tools.ietf.org/html/draft-agl-tls-encryptedclientcerts
与SPDY有棘手的互动。 为此,browserauth.net上会有更新。
假设用户上传了一个只能在他的帐户中访问的错误文件; 然后另一个用户无意中下载该文件,运行那里的任何可执行代码。
首先,你不能允许在你上传的目录上运行任何东西,因为即使你的普通用户也可以上传一个aspx页面并运行它并浏览你的文件。 第一步是在您的上传目录中添加此web.config(但也将权限设置为不允许运行任何内容)。
<configuration>
<system.web>
<authorization>
<deny users="*" />
</authorization>
</system.web>
</configuration>
亲戚: 我被黑了。 上传的Evil aspx文件名为AspxSpy。 他们还在努力。 帮我陷阱吧!
让我们看看我们如何识别用户。
现在,对于每个登录的会话,我们可以将前四个信息连接在一起,如果其中任何一个更改,我们可以将他登出并再次要求登录。
同样关键的是将一些如何(使用数据库中的一行)连接到用户的登录状态,因此如果用户注销,无论是否有人窃取了他的cookie,都无法查看页面 - 我的意思是让他登录的cookie不一定是我们唯一依赖的cookie,而且也是我们跟踪用户状态的数据。
在这种情况下,即使有人窃取了cookie,如果用户在某些操作后注销,则cookie也不再有用。
所以我们做的是我们连接每个登录的cookie + ip +浏览器id + javascript信息,如果它们中的任何一个发生变化,我们不再信任他,直到再次登录。
一个cookie是不够的。 我们至少需要两个cookie,一个只能在安全页面上运行,并且必须是https安全的,一个适用于所有页面。 这两个cookie必须连接在一起,并且此连接也必须保留在服务器上。
因此,如果此cookie之一不存在,或者连接不匹配,则用户再次没有权限并需要再次登录(向我们发出警报)
亲戚: 有些黑客可以从用户那里窃取cookie并在网站上使用该名称登录吗?
将cookie连接在一起的想法 。 有了这个想法,我将会话cookie与身份验证cookie连接起来。
黑客在到达网站时会遵循(做)一些步骤(或行动),以便能够从这个窗口获得机会,并打开后门。
正如我所说,我们永远不会允许上传可以运行的文件,所以这很容易。 另一个创建新管理员帐户的是我们需要添加一个未保存到任何cookie的额外密码,或者无论如何都存在于客户端上。
因此,对于罕见的操作,例如来自后台的新用户,更改用户的权限,删除用户等,我们需要每次只有管理员知道时请求第二个密码。
所以第二个密码是最后的密码。
我没有提出的一个想法是存储一些除了cookie以外的客户端信息,不能像cookie那样被盗,或者即使他被盗也隐藏在所有无法找到的数据上它。
此信息可以是用户的额外ID以及cookie,浏览器数据,IP。
我是一些可能的地方,但在现实生活中尚未经过测试或尝试过。 所以这是一些放置。
所以这是我的想法......任何评论家或解决方案(如何在cookie以外的客户端存储小信息)都是受欢迎的。
为了使其真正安全,我们需要跟踪服务器和数据库上的用户。 将用户,ip,浏览器ID和其他状态(如果现在是否登录)连接起来的表是我们可以用来做出决策的一种措施。
如果无法使用数据库,或者不想使数据库变得困难,那么连接可以将一些数据混合在一起并检查该哈希值是否相同。
例如,我们可以使用(Ip + BrowserID)的哈希设置一个cookie,并检查是否这么多。
以上所有他们都试图自动化。 我还建议向用户和管理员显示一些诊断和防止攻击的信息。 这些信息可以。
给用户
致管理员。
修复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.com
两个cookie与secure.example.com
之间的区别名称。 大多数浏览器将以随机顺序发送值。
也许这可以进行优化,以便服务器可以告诉客户端是否支持这种新的cookie格式,并且客户端可以相应地做出响应。
解决方案2:扩展HTML5 LocalStorage,以便(可选)自动将数据插入HTTP标头
如果我们可以扩展HTML5的LocalStorage以允许Secure / HTTPOnly数据,我们可以模仿上面的解决方案#1中所执行的操作,但是由HTML5 LocalStorage W3C工作组驱动更改
这样做的好处是,与#1解决方案相比,开销更少,因为更详细的cookie详细信息仅在需要时才发送到服务器。 换句话说,如果使用“新cookie详细信息”格式将敏感值保存到LocalStorage中,则可以明确区分需要发送的数据以及采用何种格式。
解决方案3 “Cookie验证”
Set-CookieValidationHash
向Cookie发送另一个标头: Set-CookieValidationHash
。 它包含一个SHA-256散列cookie密钥和值的JSON数组,并指定值的到期时间 来自: http ://www.w2spconf.com/2011/papers/session-integrity.pdf
5.2。 通过自定义标题完整性
我们可以通过选择存储和传输会话状态的新方法来实现会话完整性,而不是保护cookie。 虽然这可以使用像Flash这样的特殊浏览器插件来完成,但我们宁愿选择具有最少依赖关系的设计,因此我们将只关注基本的HTTP工具。 HTTP请求的基本形式很少有适合发送完整数据的地方。 HTTP请求的URL或实体主体中的数据没有完整性,因为HTTP请求的这些部分可以跨源创建,因此可被攻击者欺骗。 Cookie在这方面也很薄弱,因为在我们的威胁模型中攻击者可以覆盖它们。 但是,通过使用名为XMLHttpRequest(XHR)的JavaScript API,我们可以在自定义标头中发送数据。
背景。 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可以进行分区。
IETF TLS工作组建议将cookie绑定到TLS客户端证书 ,因此只要与证书对应的私钥仅在一台计算机上,cookie就只能在一台计算机上使用。
如果要模拟TLS客户端证书方法,可以使用localStorage存储私钥,并使用JS crypto 1将document.cookie替换为签名版本。 它有点笨重,但它可能会起作用。 (显然,使用web加密2会更好)
来源:来自Web 2.0安全和隐私会议的Origin Cookies提案
。
6.未来浏览器中的会话完整性以前的解决方案和其他考虑使用现有浏览器技术的解决方案都不能提供足够的安全性,同时可以保留现有站点的可部署性。 因此,我们建议对名为origin cookies的cookie进行扩展。 Origin cookie允许现有Web应用程序保护自己免受所描述的攻击,Web应用程序或浏览器的实现复杂性很小,对尚未实现源cookie的浏览器具有透明向后兼容性,包括旧版浏览器可能永远不会支持它们,并且对没有启用原始cookie的现有网站没有任何负担。 这不是一个需要解决的微不足道的问题,如现有提案所证明的那样,它们不能满足一个或多个上述所需特性。 例如,在每个请求上发送每个cookie的来源是一个常见的想法。 这比必要的要复杂得多,并且给网站带来了更大的负担,包括那些甚至不知道如何有效使用这些信息的网站。
6.1。 原始Cookie使用Cookie进行会话管理的真正问题是缺乏完整性,特别是由于其他来源清除和覆盖cookie的能力。 虽然我们无法在不破坏许多现有网站的情况下从cookie中禁用此功能,但我们可以引入新的类似cookie的功能,但不允许进行此类跨站点修改。
设计。 原始cookie是仅发送的cookie,仅可通过请求和来自确切来源的响应进行修改。 它们在HTTP响应中以与现有cookie相同的方式设置(使用Set-Cookie标头),但使用名为“Origin”的新属性。 为了使Web应用程序能够将原始cookie与普通cookie区分开来,原始cookie将在HTTP请求中以新标题“OriginCookie”发送,而普通cookie将继续在现有标题“Cookie”中发送。
HTTP/1.1 200 OK
...
Set-Cookie: foo=bar; Origin
...
Fig. 2. An HTTP response setting an origin cookie.
GET / HTTP/1.1
Host: www.example.com
...
Origin-Cookie: foo=bar
...
图3.对已设置原始cookie的URI的HTTP请求。
例如,如果响应对http://www.example.com/的GET请求,收到如图2所示的响应,那么将使用键'foo'和值'bar'设置原始cookie。对于原点http://www.example.com ,将在后续请求发送到该来源。 对http://www.example.com/的后续GET请求如图3所示。对任何其他来源,甚至https://www.example.com和http://example.com的请求都将完全准确好像从未设置过http://www.example.com的原始cookie。 扩展Set-Cookie本身语义的Origin属性是微妙的,意味着对cookie的其他可设置属性进行了几次语义更改。 如果设置了Origin属性,则Domain属性不再合适,因此应该忽略。 类似地,Secure属性不再合适,因为cookie的来源方案暗示它:如果方案是https,则原始cookie实际上具有属性 - 因为它只会通过安全通道发送 - 如果该方案是其他任何东西,cookie就没有该属性。 由于同源策略将不同路径视为同一源的一部分,因此Cookie的Path属性不提供安全性,也应忽略。 其他属性的语义,例如
HttpOnly
,Max-Age
,Expires
等,对于原始cookie保持不变。 普通cookie由其密钥,Domain属性的值以及Path属性的值唯一标识:这意味着使用已设置的密钥,域和路径设置cookie不会添加新的cookie,但是而是替换现有的cookie。 原始cookie应占用一个单独的命名空间,并由其键和设置它的完整原点唯一标识。 这可以防止网站意外或恶意删除原始cookie,以及其他针对阅读和修改的保护,并使服务器端使用原始cookie显着更容易。安全。 由于原始cookie是在起源之间隔离的,因此相关领域攻击者和活动网络攻击者在覆盖cookie方面的额外权力不再有效,因为他们特别利用现有cookie缺乏原始隔离,无论“混淆”是否到期到原产地的计划或领域。 如果没有这些额外的权限,相关域攻击者和主动网络攻击者就等同于网络攻击者,他们无法根据cookie和秘密令牌的组合破坏现有会话管理的安全性。
实现。 将原始cookie集成到现有浏览器中不会涉及重要的修改。 作为概念验证,我们在Chrome中实现了原始Cookie。 补丁总计只有573行
来自http://www.codeproject.com/Articles/16645/ASP-NET-machineKey-Generator
每当您使用ViewState,Session,Forms身份验证或其他加密和/或安全值时,ASP.NET都会使用一组密钥来执行加密和解密。 通常,每次应用程序回收时,这些键都会被ASP.NET隐藏并自动生成
如果这两个网站是不同的Web应用程序,则默认情况下它们将具有不同的密钥,因此将无法读取由另一个生成的加密令牌。 例外情况是它们在全局web.config或machine.config中使用公共值。
来自machineKey Element,decryptionKey: http : //msdn.microsoft.com/en-us/library/w8h3skw9.aspx
AutoGenerate,IsolateApps指定自动生成密钥。 这是默认值。 AutoGenerate修饰符指定ASP.NET生成随机密钥并将其存储在本地安全机构(LSA)中。 IsolateApps修饰符指定ASP.NET使用每个应用程序的应用程序ID为每个应用程序生成唯一的加密密钥。
因此,除非使用machineKey元素在全局级别设置decryptionKey,否则您描述的方法不起作用。 如果已设置,则可以使用web.config文件在应用程序级别覆盖。
您可以在web.config中为应用程序设置唯一的machineKey 。 这样,只能解密该应用程序发出的身份验证cookie。 如果用户访问同一域中的恶意站点,则该其他站点可能确实添加了具有相同名称但值不同的cookie身份验证cookie,但它将无法使用您使用的相同计算机密钥对其进行加密和签名。应用程序以及当用户导航回来时,将抛出异常。
答案很简单:始终将会话绑定到特定的客户端IP(这应该在任何现代Web应用程序中完成),并且不要将cookie用于任何其他目的。
说明:您总是将一个SESSIONID cookie发送回客户端,该客户端不包含任何信息 - 它只是一个非常长的随机字符串。 您将SESSIONID与经过身份验证的用户IP一起存储在您的webapps范围内 - 例如数据库。 虽然相关的cookie攻击可以用来在不同的客户端之间交换SESSIONID cookie,但是没有客户端可以伪装成另一个用户或执行任何操作,因为SESSIONID只被认为是有效的,并且只有在从相关联的发送时才授予权限。 IP地址。
只要您不存储被认为是私有的实际数据到cookie本身,而是存储在服务器端的会话状态(仅由SESSIONID cookie选择),相关的cookie问题对您来说应该没问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.