您是否将用户暴露于恶意网站?了解如何使用 xs-leaks 从 Web 应用程序中窃取数据,以及如何通过 7 个步骤来阻止它。
XS-Leaks(或 Cross-Site Leaks)是一组浏览器侧通道攻击。它们使恶意网站能够从其他 Web 应用程序的用户那里推断数据。
Twitter 剪影攻击就是一个极好的例子。
在开始之前,了解 SOP(Same Origin Policy)是很有帮助的,它是 Web 浏览器安全模型的核心和灵魂。这是一个或多或少说的规则:
GET来源发送、、、POST和请求。此外,该请求将包括该来源的用户 cookie(包括会话 ID)。HEADOPTIONSanotherWindow.location.replace("https://www.evil.com")。例如,这个网站的来源https://www.appsecmonkey.com/是. 主机是,并且未指定端口(由于协议,这是隐含的)。protocolhttpswww.appsecmonkey.com443https
好的,这就是它的要点。让我们开始攻击。
浏览器可以轻松地对跨域请求进行计时。
- var start = performance.now()
-
- fetch('https://example.com', {
- mode: 'no-cors',
- credentials: 'include',
- }).then(() => {
- var time = performance.now() - start
- console.log('The request took %d ms.', time)
- })
The request took 129 ms.
这使得恶意网站可以区分响应。假设有一个搜索 API 供患者查找自己的记录。如果患者患有糖尿病并搜索“糖尿病”,则服务器返回数据。
GET /api/v1/records/search?query=diabetes
{ 'records': [{ 'id': 1, ... }] }
如果患者没有糖尿病,API 会返回一个空的 JSON。
GET /api/v1/records/search?query=diabetes
{ 'records': [] }
一般来说,前一个请求需要更长的时间。然后,攻击者可以创建一个恶意网站,对“diabetes” URL 的请求进行计时,并确定用户是否患有糖尿病。
您可以展开攻击并搜索 a... b... c... d... 是的。达..分贝...迪...是的。这种攻击称为XS-search。
查看xsleaks.dev上的所有计时攻击。
我们列表中的下一个侧通道是使用 JavaScript 策略性地捕获错误消息。假设一个页面根据一些敏感的用户数据返回200 OK或。404 not found
然后,攻击者可以创建如下所示的页面,该页面查询应用程序并确定端点是否为浏览器用户返回错误。
- function checkError(url) {
- let script = document.createElement('script')
- script.src = url
- script.onload = () => console.log(`[+] GET ${url} succeeded.`)
- script.onerror = () => console.log(`[-] GET ${url} returned error.`)
- document.head.appendChild(script)
- }
-
- checkError('https://www.example.com/')
- checkError('https://www.example.com/this-does-not-exist')
- [-] GET https://www.example.com/ succeeded.
- [+] GET https://www.example.com/this-does-not-exist returned error.
通过获取帧的句柄,可以访问该帧的window.length属性,该属性用于检索窗口中的帧数(IFRAME 或 FRAME)。
这种知识有时会产生安全/隐私影响。例如,网站可能会根据某些用户数据以不同的帧数呈现个人资料页面。
有几种方法可以获得窗口句柄。第一个是调用window.open,它返回句柄。
- var win = window.open('https://example.com')
- console.log('Waiting 3 seconds for page to load...')
- setTimeout(() => {
- console.log('%d FRAME/IFRAME elements detected.', win.length)
- }, 3000)
另一种是对目标网站进行框架,并获取框架的句柄。
- var win = window.frames.framecounter
-
- console.log('Waiting 3 seconds for page to load...')
- setTimeout(() => {
- console.log('%d FRAME/IFRAME elements detected.', win.length)
- }, 3000)
这两个可以说是最重要的。还有其他的,例如window.opener和window.parent。有关更全面的列表,请参阅本文。
在xsleaks.dev上阅读有关帧计数的更多信息。
知道浏览器是否在某处导航(例如,重定向),通常可以推断出关于用户的数据。例如,网站的经过身份验证的部分倾向于将用户重定向到登录页面。当然,除非用户已经登录。
观察导航使恶意网站能够查看浏览器用户登录的网站,这是一个巨大的隐私问题。
恶意网站可以通过多种方式检测重定向。这些包括:
onload调用的次数。history.length从窗口句柄中检索。在这里查看它们:https ://xsleaks.dev/docs/attacks/navigations/
当用户访问网站时,这些网站的资源通常会被缓存并存储在用户的磁盘上,因此不必再次下载。这节省了带宽,降低了服务器负载,并改善了用户体验。
不幸的是,基于时间和错误的 xsleak 变体可以利用这一点并确定用户之前是否访问过网站。
缓存时间变化很简单,为请求计时,如果是瞬时的,则资源被缓存。
基于错误的版本稍微复杂一些。它利用了缓存资源从未从服务器实际请求过的事实。因此,对缓存资源的无效 HTTP 请求不会引发异常(因为 Web 服务器永远没有机会拒绝它)。
在 xsleaks 上阅读它们:https ://xsleaks.dev/docs/attacks/cache-probing/ 。
这个利用了https://developer.mozilla.org/en-US/docs/Web/API/Element/focus_event事件在带有 url 之类的框架https://www.example.com/#example跳转到元素时被触发的事实example。
如果example页面上没有,则不会触发该事件。
阅读更多关于 xsleaks 的变体:https ://xsleaks.dev/docs/attacks/id-attribute/
到目前为止提到的变化应该给你的想法,但还有其他的。您可以访问xsleaks.dev了解更多攻击和详细信息。
您将无法完全阻止所有浏览器中的所有xsleaks 。世界还没有为此做好准备。但是你可以很安全,特别是对于 Chrome 或 Edge,它们拥有所有最前沿的安全功能。就是这样:
所有主要浏览器都支持一个很酷的功能,称为SameSite cookie。当您使用 设置 cookie 时SameSite=Lax,浏览器不会将其包含在跨域 POST 请求中,这可以很好地抵御CSRF攻击。
对于我们的 xsleaks 用例来说,至关重要的是,它还会阻止不是顶级导航的GET 请求,也就是说,脚本标签、获取请求、图像标签等将不再发送 cookie。
Set-Cookie: SessionId=123; ...other options... SameSite=Lax
另一个漂亮的浏览器功能是内容安全策略,简称 CSP。CSP 可以非常有效地抵御XSS攻击。但在这种情况下,我们对阻塞帧感兴趣,而 CSP 的秘诀是:
Content-Security-Policy: frame-ancestors 'none';
此 CSP 政策将阻止所有现代浏览器让任何其他网站构建您的应用程序。如果你也想支持 Internet Explorer,那么也发送X-Frame-Options。
X-Frame-Options: DENY
禁用缓存并不适合所有人。例如,我不可能为这个博客做到这一点。但可以说,防止与缓存相关的 xsleaks 向量的最有效方法是完全禁用您网站的缓存。您可以通过在所有响应中返回以下Cache-Control标头来执行此操作:
Cache-Control: no-store, max-age=0
这种方法更可行,但并非所有浏览器都支持。这个想法是根据获取元数据请求标头来改变缓存。
如果恶意网站尝试向您的应用程序发出请求,则Sec -Fetch-Site请求标头将包含该值。cross-site并且由于Vary标头,该恶意网站将拥有自己的缓存。它将无法推断出浏览器用户在网站上缓存的内容。
Vary: Sec-Fetch-Site
Cross-Origin-Opener-Policy是一个 HTTP 响应标头,可限制恶意网站获取您网站的窗口句柄。你可以这样设置:
Cross-Origin-Opener-Policy: same-origin
Chrome、Edge 和 Firefox已经完全支持它。
Cross-Origin-Resource-Policy是一个 HTTP 响应标头,用于限制恶意网站从您的域中读取/嵌入/呈现资源。在此处阅读更多相关信息。你可以这样设置:
Cross-Origin-Resource-Policy: same-origin
浏览器已经开始实现一个相对较新的安全功能,称为获取元数据请求标头。它们可用于服务器端,根据发生的上下文阻止或允许请求。
这种基于获取元数据标头阻止请求的中间件称为隔离策略。
在此处阅读有关获取元数据标头和隔离策略的更多信息。
有相当多的 XS 泄漏,正如我们所说,浏览器供应商正在想出解决它们的工具。
如果可能的话,阻止所有这些都不是一件容易的事。但是按照本文和Introduction | XS-Leaks Wiki中的指南,您应该没问题。