缓存如何工作?

计算机科学中的所有形式的缓存,无论是CPU缓存,HTTP Web Server缓存,数据库缓存等等,都旨在加快响应速度,以响应任何请求。这样做有助于最大程度地减少正在主动缓存的组件上的负载。

由于这个原理,缓存往往位于客户端/用户与服务器/组件之间。为了理解Web缓存中毒,了解这一点非常重要。在网络的生态系统中,使用的缓存类型可能会有所不同。一些示例包括但不限于:

  • 记忆快取
  • CDN(即Akamai,MaxCDN,AWS)
Web缓存中毒

继续,对缓存的任何引用都是在Web应用程序缓存的上下文中进行的,就像上面提到的那样。

缓存背后的想法非常简单。将“答案”(响应)静态存储到经常被请求的“问题”(请求),从而无需重新计算繁重的请求。缓存系统需要至少具有两个关键功能:

  1. 为其缓存项目(即文件,HTTP请求等)的时间
  2. 确定请求是命中高速缓存(因此快速响应)还是错过高速缓存(因此需要询问应用程序)

我们不太担心第一种选择。第二个选项可以通过使用键值存储来解决,这听起来很简单,但是实现起来确实很棘手。这里的问题是确定密钥中包含什么,以确定密钥是否唯一。

例子

想象一下,我们是一个始终位于同一域的简单站点的缓存系统 example.com。在这种情况下,将端点用作键将非常有用:

要求

POST //example.com/stats?page=1 HTTP/1.1
Host: example.com
Accept-Language: en-US

响应

HTTP/1.1 200 OK

<h1>统计页1</h1>
<p>语言:en-US</p>

这意味着我们现在可以为下一个请求路径的用户缓存该响应 /stats?page=1:

快取

钥匙 价值
stats?page = 1统计页1
语言:en-US

您可能会注意到,缓存系统会将以下两个请求视为相同。但是,那  接受语言 标头略有不同。

请求1

POST //example.com/stats?page=1 HTTP/1.1
Host: example.com
Accept-Language: en-US

请求2

POST //example.com/stats?page=1 HTTP/1.1
Host: example.com
Accept-Language: de

这是一个问题,因为:

  1. 即使客户要求内容为德语,该网站也将以英语(美国)进行响应,从而导致视觉错误。
  2. 无键输入(接受语言)反映在页面中。

因此,如果我们发送带有 跨站脚本 有效负载反而像这样:

POST //example.com/stats?page=1&cachebust=1 HTTP/1.1
Host: example.com
Accept-Language: <script>警报(document.domain)</script>

并且缓存被更新。

钥匙 价值
stats?page = 1&cachebust=1<h1>Stats Page 1</h1>
<p>Language: <script>警报(document.domain)</script></p>

这意味着  任何  访问URL的用户 //example.com/stats?page=1&cachebust=1 将返回缓存的值。这包括恶意负载,而应用程序尚未意识到,因此会利用用户的浏览器。

补救缓存中毒攻击

防御高速缓存中毒攻击可能非常棘手。完全禁用缓存是一种对大多数人不可行的方式,这是可以理解的。但是,一些有用的方法是:

  • 大量缓存静态响应,例如  * .js * .css * .png  文件,博客文章,登录页面或任何始终相同的页面。
  • 确保您不受跨站点脚本攻击的威胁,因此即使发生此类漏洞,也无法利用用户的浏览器。
  • 了解并限制进行缓存的位置。您是否正在使用实现自己的缓存的框架?如果是这样,您可能要禁用该功能并在单个点(例如CloudFlare)处处理缓存。
  • 避免将用户输入(即HTTP标头)用作缓存键。

结论

最后,尽管上述所有内容看起来都很艰巨, 网络应用扫描仪 如Acunetix可以检测 Web缓存中毒 as well as 跨站脚本 精确定位。

这将  剧烈地 减少发现此类漏洞所需的时间,从而帮助您在攻击者发现它们之前修复它们。

Source://www.acunetix.com/blog/