新的前端安全

除了大家耳熟能详的xss跨站脚本攻击和csrf跨站请求伪造,还有一些前端安全需要注意

第一个就是  

XS-Leaks

XS-Leaks即跨站泄漏。 XS-Leaks利用了对HTTP缓存进行查询的机制,通过对资源缓存的判断进而推断出当前用户的相关信息。如果你第一次听说XS-Leaks,那我相信你一定很意外为什么普普通通的HTTP资源缓存也能造成用户信息泄漏。

在这之前Chrome浏览器的请求缓存策略很简单:

  • 1、用户访问A页面,请求一张图片资源,浏览器拿到这张图片之后,会将这张图片进行缓存,并把这张图片的URL作为缓存查询的键值;
  • 2、用户接着访问B页面,假如这个页面也用到了上述的那张图片,此时浏览器会先查询是否已经缓存了此资源,由于缓存过这张图片,因此浏览器直接使用了缓存资源;

由于缓存资源没有域名限制,所有网站都共享了缓存资源,因此利用这一点就可以检测用户是否访问过特定的网站:恶意网站通过发起特定的资源请求,通过判断此次资源是否来自缓存就可以推断出用户的浏览历史。比如我在我的网站中请求掘金的LOGO图片(或者其他更具唯一性的资源),如果我判断出这张图片来自缓存,那我就可以知道该用户访问过掘金网站。

XS-Leaks和上述的原理类似,利用了对HTTP缓存进行查询的机制,通过检测一个查询询问是否有结果来获取一些用户数据。XS-Leaks攻击的主要步骤流程如下:

  • 1、删除特定网站的缓存资源。
  • 2、强制浏览器刷新网站。
  • 3、检查浏览器是否缓存了在(1)中删除的资源。

举一个小栗子,假如我们想知道当前访问我们网站的用户是否是某社交网站(假设链接为http://xxx.com)昵称为@helloWorld的用户,利用XS-Leaks攻击应该怎么做呢?

首先我们可以先将这名@helloWorld的用户头像图片从社交网站上扒下来,假设该图片链接长这样: http://xxx.com/user/helloWorld.jpg

为了避免用户因为浏览了社交网站的一些页面(比如帖子列表页),请求过helloWorld的头像导致的缓存影响判断目的,当用户访问我们的页面时,我们需要先想办法清空这张头像的浏览器缓存。那么怎么能强制清楚一张图片的缓存呢?

FETCH POST http://xxx.com/user/helloWorld.jpg
复制代码

没错,通过发起一个POST请求,就可以清除浏览器对这张图片的缓存(感兴趣的小伙伴可以看看这篇文章)。

接下来通过iframe或者<link ref=rerender href="http://xxx.com/user" />等方式悄悄发起一个请求,访问社交网站的个人信息页面http://xxx.com/user(这个页面包含用户的头像图片)。

紧接着只需要再请求一次头像http://xxx.com/user/helloWorld.jpg,判断其是否来自缓存,如果是,那不就说明了刚才请求的个人信息页面包含了这张图片,就可以推断出该名用户就是@helloWorld了。

那么问题又来了:如何判断一个请求来自缓存呢?

方法还是很多的,一种方法是通过读取img的宽高属性,来判断图片是否来自缓存:

const img = new Image();
img.onload = () => {
  // 如果img不是来自缓存,那么只有在图片加载完成触发onload之后,才能拿到实际的witdh值
  console.log(img.width);
}
img.src = 'http://xxx.com/user/helloWorld.jpg';
// 如果存在缓存,在这里可以立即读取到图片的 witdh 值,否则会打印 0
console.log(img.width);

至此一次XS-Leaks攻击就完成了。我们也可以请求一些带权限的链接来判断用户是否拥有某个网站的特权身份等等。虽然这个小栗子看起来危害不大,只是做到了当前用户和目标网站账号的关联,但是不要小看黑客们的脑洞,一个看起来不起眼的漏洞很可能会带来巨大损失。

这里给大家分享一个关于XS-Leaks的github地址,里边记录了与XS-Leaks相关的攻击方式、知识和实际案例,帮助大家更深刻地理解概念和攻击手段。


介绍了那么多,是时候总结一下XS-Leaks的一些防范措施了。可以看到XS-Leaks也是从第三方网站中发起攻击的,而且都是通过向目标网站发起请求而达到攻击目的,是不是和CSRF的攻击方式很相似?

没错,CSRF的防御手段同样可以让XS-Leaks对带鉴权的请求访问无效,从而降低危险。当然有些时候这种攻击其实并不需要鉴权就能达成目的,因此CSRF的防御手段并不能做到完美抵御,所以在浏览器层面增加缓存分区就显得非常有必要了:

  • 设置SameSite Cookie;
  • CSRF Token;
  • 浏览器支持缓存分区;
第二个就是

web服务端缓存攻击

XS-Leaks利用了浏览器缓存的漏洞实现了攻击,但是其实不仅仅浏览器可以缓存,web服务器也是可以有缓存的,服务器缓存是把请求过的资源暂且放在一个专门的缓存服务器(例如CDN)上,当下一个用户访问同样的资源时就可以直接从缓存服务器上拿到响应,从而减轻Web服务器的压力。

那假如我们可以把攻击代码通过某种方式放在CDN等缓存服务器中,那发起了相同资源请求的用户就都会拿到这份恶意代码从而遭受攻击,这不就实现了XS-Leaks的“存储型攻击”?

缓存服务器通过cache-key来确定两个用户访问的是否是同一个资源,而这个cache-key通常由请求方法、路径、query、host头组成。假如一个web服务器有如下请求响应:

该响应中将请求头X-Forwarded-Host的值直接拼接到meta标签的content属性中,由此产生了XSS攻击的漏洞,因此我们通过发起一个如下请求:

GET /en?dontpoisoneveryone=1 HTTP/1.1
Host: www.redhat.com
X-Forwarded-Host: a."><script>alert(1)</script>
复制代码

服务器就会返回如下响应,并缓存到缓存服务器中:

HTTP/1.1 200 OK
Cache-Control: public, no-cache
…
<meta property="og:image" content="https://a."><script>alert(1)</script>"/>
复制代码

由于X-Forwarded-Host不属于cache-key的一部分,因此当其他用户发起/en请求时,服务器都会认为是请求同一个资源从而应用缓存策略,将上面的恶意响应直接响应给用户,造成攻击。

上述的例子来自于BlackHat2020议题之Web缓存投毒这篇文章,文章非常详细地介绍了Web服务器缓存攻击的原理和案例,有兴趣的小伙伴也可以看看。

 
posted @ 2020-11-12 10:36  坟场蹦迪  阅读(82)  评论(0编辑  收藏  举报