我们已经通过 Google Adsense 审核!不出意外,在未开启广告拦截器的情况下,应该已经可以看到广告了
如果您对广告位置不满意(如:占据面积大,挡住主要内容等情况),请前往 置顶文章 告知我们!
前言
很早之前,我有一位朋友给我发了一个神秘的网站,打开以后就是一直转圈圈
但是正常来说,浏览器的转圈圈是有超时的,我在那等了好几分钟还是在转圈圈
最后发现不是网络请求的问题,而是网页提供的资产的问题!
原始网页发送了一个 42kb 大小的文件,通过响应头告知浏览器为br压缩,原始格式为html,然后…
打开F12控制台,我去!这玩意怎么有10个G!不对!它还在加载!

随后得知这就是个Web压缩炸弹,今天又想起来这件事了,就尝试折腾了一下
接下来手把手教各位做这个压缩炸弹!
原理
在现代网页中,服务器一般不提供原始的源文件(如:.html),而是提供一个压缩后的文件(如:.br, .gz, .zstd)
浏览器收到文件后根据 Content-Encoding 响应标头的值来判断资产是否被压缩以及要使用的解压算法是什么
此项措施原本是为了节省网络带宽,分发压缩后的网页文件一般会比分发原始文件消耗的带宽少得多
如果你稍微了解过压缩原理,你应该就知道压缩实际上就是去重+归类
用一个不太恰当的例子
假如这是源文件,一共有10个0
0000000000如果我们想要压缩?非常简单!因为该文件只有10个0,我们可以将其写为 10-0, 以代表10个0,这样,一个简单的压缩算法就实现了
它成功将源文件压缩了50%(源文件存放需要10个单位,压缩后仅需5个单位)
这只是一个简单的演示,并不代表市面上任意一个压缩算法,仅限于简单理解“压缩是怎么实现的”
那么如果我们往一个文件内塞入非常非常多的0呢?然后将其压缩,最终就能得到一个十分小的压缩文件,但是解压后就会释放出巨大的文件!
TIPzstd与br的压缩率远高于gz,所以一般都使用他们来制作压缩炸弹,压缩后与源文件的比率可以达到惊人的 1:124878.0487804878
一个 8.20 KB 的压缩炸弹,解压后可以释放高达 10 GB 的文件!
实操
首先我们需要准备这个特制的压缩炸弹,你可以手动制作,也可以直接从这里下载 吃内存的网页炸弹 – 晨旭的博客~
接下来我们就得到一个压缩炸弹了,它看起来人畜无害

当我们使用解压工具进行解压后就能得到这个巨大的原文件了

ok,接下来我们只需要将这个压缩炸弹放到web上,然后设置压缩标头即可
那么…放在哪呢?其实哪都可以,你只需要确保
- Web服务器能提供 原始的压缩炸弹文件
- Web服务器能够提供给客户端一个能使压缩炸弹 被正常解压缩的压缩标头
Content-Encoding
我们以Cloudflare Page/Worker 的静态托管举例
首先,将压缩炸弹放到静态资产目录(为了伪装,我这边重命名为了 index.html )
![]()
接下来,编辑Cloudflare规则,使其能给客户端一个我们所期望的标头
由于Cloudflare默认针对html文件采用了自动压缩,我们的压缩炸弹会被cf再压缩一遍,这会导致压缩炸弹失效,可参考下图的逻辑链
原始压缩炸弹.br -> Cloudflare 自动压缩(一般为 .zstd) -> 原始压缩炸弹.br.zstd -> 发送给客户端并携带zstd压缩标头 -> 客户端使用 zstd 算法解压得到 原始压缩炸弹.br -> 直接将 原始压缩炸弹.br 作为HTML显示 -> 乱码
这样就没有效果了,所以我们首先需要禁用Cloudflare的自动压缩,使其直接提供原始文件

接下来由于Cloudflare自动压缩被禁用了,Content-Encoding 响应标头也会被移除,此时如果客户端拉取,就是以下结果
原始压缩炸弹.br -> 直接将 原始压缩炸弹.br 作为HTML显示 -> 乱码
我们仍然没有达到我们的目的,所以我们需要额外再配置一条响应标头规则,强制让客户端以 br 算法解压我们的压缩炸弹 保险起见,这里让客户端将文件类型强制解析为html,避免其他类型导致客户端忽略 Content-Encoding

接下来再尝试访问,不出意外,客户端成功吃到我们的压缩炸弹了!

压缩炸弹的用处?
没啥用,只能拿来炸炸你朋友的浏览器
如果你想拿来替代WAF拦截,该方法确实有效,但是对于一些带宽敏感的CDN,还是建议返回CDN自带的拦截页面避免CDN误判 你没做好防护
鸣谢
发现错误或想要改进这篇文章?
在 GitHub 上编辑此页