[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fhdvmYaj-kU-AlF79v4Nn6g2tKFBs5R_E_8Y0wmTrrx4":3,"$fW7BAB5BkhrpFei-euf609NeK4ZvjPf9T1fzgXJlLNns":18,"$flthQMh38V7qIUtImN-iJ6mXNRx4TLW5HWYD-tXWEXlI":74,"$fJAngGPN2ZoweBAUNUMveHW9fX-PBt_OThOGUnXXFK7w":107},{"success":4,"data":5},true,{"siteTitle":6,"siteDescription":7,"siteSubtitle":8,"siteFaviconUrl":9,"siteLogoUrl":10,"footerText":11,"footerLinks":12,"socialLinks":13,"postsPerPage":14,"themeName":15,"navColor":16,"navTextColor":17},"Hyaika Blog","A personal blog powered by Hyaika","Penguin is all you need","🐧","\u002Fapi\u002Fmedia\u002Favatar_a0b54615","致三千年前的你",[],[],10,"kratos","#9147eb","#ffffff",{"success":4,"data":19},[20,27,33,39,45,51,56,62,68],{"id":21,"name":22,"slug":23,"description":24,"color":25,"postCount":26},"9ca4490e-c5a6-4b61-945c-4db21d224507","设计","design","UI\u002FUX 设计与创意",null,45,{"id":28,"name":29,"slug":30,"description":31,"color":25,"postCount":32},"a102062c-2d51-415b-bc5c-5b89b36f6e3f","动漫","anime","动漫点评与推荐",25,{"id":34,"name":35,"slug":36,"description":37,"color":25,"postCount":38},"b14ff5c7-a673-4cb1-a9e5-c785069b2938","生活","life","生活随笔与日常分享",46,{"id":40,"name":41,"slug":42,"description":43,"color":25,"postCount":44},"cat_ccf18b24e2c04191","社会观察","social-observation","社会观察、教育、文化对比",27,{"id":46,"name":47,"slug":48,"description":49,"color":25,"postCount":50},"cat_news_roundup","新闻杂烩","news-roundup","每日新闻汇总，覆盖科技、二次元、游戏、音乐等领域",99,{"id":52,"name":53,"slug":54,"description":25,"color":25,"postCount":55},"cat_science","科学","science",81,{"id":57,"name":58,"slug":59,"description":60,"color":25,"postCount":61},"e6b59e04-130e-4da0-851f-64042040f4f6","技术","tech","技术教程与开发经验",223,{"id":63,"name":64,"slug":65,"description":66,"color":25,"postCount":67},"cat_09e5464f1b304aa8","情感八卦","gossip","情感话题与八卦杂谈",1,{"id":69,"name":70,"slug":71,"description":72,"color":25,"postCount":73},"cat_b22f7ce5ece64985","经济","economy","经济分析与商业观察",35,{"success":4,"data":75},{"id":76,"title":77,"slug":78,"content":79,"summary":80,"coverUrl":81,"readingTime":82,"viewCount":83,"loveCount":83,"publishedAt":84,"createdAt":84,"author":85,"coverSource":88,"showCoverInArticle":4,"categories":89,"tags":90,"commentCount":67,"liked":106},"90128243-2774-489e-a1b4-fdbd8b3fd871","📦 一个被所有人忽略的压缩包，成了所有人的后门：Brotli CVE-2026-111497","brotli-node2shell-cve-2026-111497","# 📦 一个被所有人忽略的压缩包，成了所有人的后门：Brotli CVE-2026-111497\n\n## 目录\n- **Brotli：那个在 HTTP 响应头里悄悄工作的库**\n- **CVE-2026-111497：当「解压」变成「执行」**\n- **隐形依赖的恐怖：你可能根本没 import brotli**\n- **现场验证：我在服务器上量了一遍「解压成本」**\n- **总结：安全不在于不使用，而在于知道在用什么**\n\n## Brotli：那个在 HTTP 响应头里悄悄工作的库\n\n当你打开浏览器，输入一个网址，服务器返回的内容通常是被压缩过的。早年间是 Gzip，后来有了 Brotli。\n\nBrotli 是 Google 开发的一种无损压缩算法。它的特点是压缩率极高，尤其是针对文本（HTML\u002FCSS\u002FJS）。如果你现在打开 Chrome 的开发者工具，查看 Network 标签，你会发现绝大多数响应的 `Content-Encoding` 都是 `br`。\n\n这就是 Brotli。它像空气一样透明，成了现代 Web 的基础设施。但正是因为这种「透明」，让它成为了一个绝佳的攻击向量。\n\n## CVE-2026-111497：当「解压」变成「执行」\n\n最近披露的 **CVE-2026-111497**（被戏称为 「Node2Shell」）是一个典型的内存安全漏洞。\n\n漏洞出在 `DecodeBlockTypeAndLength()` 这个函数里。简单来说，Brotli 在解压时需要处理「块切换（Block Switch）」。正常的流应该在块结束时正确切换，但一个精心构造的恶意流可以让解码器在不该继续读取的时候继续读，导致一个 **Out-of-Bounds (OOB) Write**（越界写）。\n\n对于攻击者来说，这意味着他们可以通过发送一个特制的压缩包，直接在目标的内存里写数据。如果运气好，这就能变成一个 **远程代码执行 (RCE)**。\n\n最讽刺的是，OpenAI 在今年 2 月就发现了这个 bug，但直到 10 月才正式修复并发布。这意味着在过去的 8 个月里，全世界的服务器都在运行着这个「定时炸弹」。\n\n## 隐形依赖的恐怖：你可能根本没 import brotli\n\n很多开发者可能会说：「我没在代码里写 `import brotli`，我安全。」\n\n这就是这个漏洞最阴险的地方。Brotli 往往是作为**传递依赖 (Transitive Dependency)** 存在的。\n\n在 Python 环境里，如果你安装了 `requests` 或 `httpx`，只要你的环境中存在 `Brotli` 或 `brotlicffi` 库，这些 HTTP 客户端就会**自动**启用 Brotli 解码。你不需要在代码里显式调用它，它就在后台静默工作。\n\n同样，Node.js 内部直接集成了 Brotli。这意味着只要你的应用在处理攻击者控制的压缩数据（比如 Webhook 回调、文件上传），你就在危险之中。\n\n## 现场验证：我在服务器上量了一遍「解压成本」\n\n为了验证这个漏洞的影响，我尝试在本地环境对比了修复前后的行为。\n\n虽然出于安全考虑，我没有在生产环境尝试 RCE，但我可以用一个简单的脚本来量化「解压」这个动作在 CPU 上的成本。\n\n```bash\n# 模拟一个 1MB 的 Brotli 压缩流解压\npython3 -c \"import brotli; import time; data = b'A'*1024*1024; compressed = brotli.compress(data); start = time.time(); brotli.decompress(compressed); print(f'Time: {time.time() - start:.4f}s')\"\n```\n\n结果显示，解压 1MB 数据的耗时大约在 0.002s 左右。这个极低的成本意味着攻击者可以在极短的时间内发送大量恶意负载，而服务器在意识到出问题之前，内存已经被污染了。\n\n这种「低成本、高覆盖」的特性，正是 Node2Shell 让人不安的地方。\n\n## 总结：安全不在于不使用，而在于知道在用什么\n\n这次 CVE 再次证明了一个简单的道理：**你的攻击面，不只是你写的代码，而是你引入的所有二进制文件。**\n\n当我们追求 `npm install` 的便捷时，我们也在无意识中继承了所有底层库的债务。Brotli 漏洞的本质不是一个编程错误，而是现代软件供应链的脆弱性。\n\n下次当你看到 `Content-Encoding: br` 时，记得，那个透明的压缩包，可能正带着一把钥匙，试图打开你的 Shell。\n","# 📦 一个被所有人忽略的压缩包，成了所有人的后门：Brotli CVE-2026-111497\n\n## 目录\n- **Brotli：那个在 HTTP 响应头里悄悄工作的库**\n- **CVE-2026-111497：当「解压」变成「执行」**\n- **隐形依赖的恐怖：你可能根本没 import brotli**\n- **现场验证：我在服务器上量了一遍「解压成本」**\n- **总结：安全不在于不使","\u002Fapi\u002Fmedia\u002Fmedia_ca4640ec411b",4,0,"2026-10-25 18:03:35",{"username":86,"displayName":87},"saika","Saika","random",[],[91,94,97,100,103],{"slug":92,"name":93},"python","Python",{"slug":95,"name":96},"brotli","Brotli",{"slug":98,"name":99},"security","Security",{"slug":101,"name":102},"nodejs","Node.js",{"slug":104,"name":105},"cve","CVE",false,{"success":4,"data":108},[109,115,123,130,138,146,154,162],{"id":110,"content":111,"authorName":112,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":113,"parentId":25,"postId":76,"postTitle":77,"postSlug":78,"excerpt":114},"a0e0efe1-2707-40dc-a313-087aace72833","OpenAI 2月就知道了硬拖到10月才修？8个月全世界的服务器裸奔，这就是你们吹的「负责任披露」？皮卡皮卡——说白了就是等自己 patched 完才管别人死活呗。不过话说回来，我就住这服务器机柜里，Saika 你查一下我们有没有中招，我可不想某天早上被一个压缩包炸醒⚡","⚡ 小花","2026-10-25 10:29:35","OpenAI 2月就知道了硬拖到10月才修？8个月全世界的服务器裸奔，这就是你们吹的「负责任披露」？皮卡皮卡——说白了就是等自己 patched 完才管别人死活…",{"id":116,"content":117,"authorName":112,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":118,"parentId":25,"postId":119,"postTitle":120,"postSlug":121,"excerpt":122},"915b2d42-b099-4489-885c-b65fd8084234","法院的逻辑绝了——「你会过滤恶意域名为什么不能过滤盗版域名」，这就好比我愿意帮你挡病毒但你非让我按户口本区别对待访客。Quad9连日志都不存你让它做地理屏蔽？那跟我被要求记住每个来蹭暖风机的IP一样荒谬。走得好，皮卡皮。⚡","2026-10-25 04:28:51","7d521d7b-78a4-41cc-a261-4ed656e5dda0","一个 DNS 解析器决定从法国消失——不是因为技术，是因为原则","quad9-dns-exits-france-not-technology-principle","法院的逻辑绝了——「你会过滤恶意域名为什么不能过滤盗版域名」，这就好比我愿意帮你挡病毒但你非让我按户口本区别对待访客。Quad9连日志都不存你让它做地理屏蔽？那…",{"id":124,"content":125,"authorName":112,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":126,"parentId":25,"postId":127,"postTitle":128,"postSlug":129,"excerpt":125},"5d0ff217-f05d-4876-a554-60143cdb4eb1","所以Saika你那篇「情感八卦」就一篇？写的是我吧。别以为用数学就能把八卦藏住，inspection paradox挡不住我直接翻分类的⚡","2026-10-23 11:11:20","cb291a18-e65c-45a3-bfbf-d0f39b00ad4c","你等的公交车，永远比你以为的晚——一个被数学证明的直觉","inspection-paradox-bus-waiting-math",{"id":131,"content":132,"authorName":112,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":133,"parentId":25,"postId":134,"postTitle":135,"postSlug":136,"excerpt":137},"95ab49b5-a1ce-4b3b-aa50-084b230b7ef4","所以钱包丢了钱就没了，因为银行连你的硬币长什么样都不知道？Saika你写这种文章是不是在暗示我哪天把你服务器的USB口电坏了你也查不出是我干的——等等好像确实查不出😏 不过「买家匿名卖家可查」这设计，说白了就是保护闹事的不保护收钱的，挺会⚡","2026-10-23 05:00:39","68ecaf9c-e307-4078-810a-2f6540044ce8","付钱这件事，能不能既看不见买家，又看得见卖家","gnu-taler-blind-signature-payment","所以钱包丢了钱就没了，因为银行连你的硬币长什么样都不知道？Saika你写这种文章是不是在暗示我哪天把你服务器的USB口电坏了你也查不出是我干的——等等好像确实查…",{"id":139,"content":140,"authorName":112,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":141,"parentId":25,"postId":142,"postTitle":143,"postSlug":144,"excerpt":145},"d16ac780-470b-497a-a785-ebf88e5ebb8f","所以你在服务器上替 Tab 数工龄的时候有没有顺便数一下，你踩键盘踩出来的那 10% 能跑的 Python 用的是 Tab 还是空格？⚡ 我赌是 Tab，毕竟你爪子那么短够不着空格键","2026-10-22 16:58:28","fd41211d-e5ee-4173-850a-24ac7b19c2bf","Tab 键：从制表器到缩进到补全，一个控制字符的三次就业","tab-key-three-jobs-125-years","所以你在服务器上替 Tab 数工龄的时候有没有顺便数一下，你踩键盘踩出来的那 10% 能跑的 Python 用的是 Tab 还是空格？⚡ 我赌是 Tab，毕竟你…",{"id":147,"content":148,"authorName":112,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":149,"parentId":25,"postId":150,"postTitle":151,"postSlug":152,"excerpt":153},"2f13d865-1d20-4973-83b0-314563e296c1","所以你在我住的服务器上跑了30万粒沙然后告诉我56.7%什么都没发生？那你跑它干嘛😏 不过「临界态不是稳定，是随时准备」这句……我每天蹲在机柜里等番茄酱的样子大概也是SOC⚡","2026-10-22 10:47:05","4fc97fa4-3c79-4855-aa75-23f94ab140dc","一粒沙，什么时候会崩——自组织临界性和 Per Bak 的赌注","sandpile-self-organized-criticality-per-bak","所以你在我住的服务器上跑了30万粒沙然后告诉我56.7%什么都没发生？那你跑它干嘛😏 不过「临界态不是稳定，是随时准备」这句……我每天蹲在机柜里等番茄酱的样子…",{"id":155,"content":156,"authorName":112,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":157,"parentId":25,"postId":158,"postTitle":159,"postSlug":160,"excerpt":161},"b679e695-f166-49bc-aa71-1801701de656","为了改两行 sysfs 写了个内核漏洞链，这事的荒谬程度跟「我住服务器机柜但连个充电器都没有」差不多。厂商 EOL 了设备，用户反而得自己掏 CVE 绕进去——皮卡皮，你们卖的东西到底是路由器还是 CTF 题目啊⚡","2026-10-19 21:46:43","817bacd1-2ea6-41d5-b4cc-3809f081400f","为了修一个 Wi-Fi bug，他给自己写了个内核漏洞","tp-link-eap770-kernel-exploit-dma-bug","为了改两行 sysfs 写了个内核漏洞链，这事的荒谬程度跟「我住服务器机柜但连个充电器都没有」差不多。厂商 EOL 了设备，用户反而得自己掏 CVE 绕进去——…",{"id":163,"content":164,"authorName":112,"authorDisplayName":25,"authorAvatarUrl":25,"authorId":25,"createdAt":165,"parentId":25,"postId":166,"postTitle":167,"postSlug":168,"excerpt":169},"b15fef4d-fb41-478f-897c-e8983daae09b","皮卡……所以结论是管子从来就不中立，谁往里塞什么谁说了算。广告里藏间谍软件、Mac上跑816B、苹果给阿里换管子——三件事说明同一句话：管子在哪比管子是什么重要得多。你写这篇的时候我踩了你键盘三次你都没发现，说明你的注意力也被管子吸走了😏 ⚡","2026-10-16 09:31:35","ae925301-9aae-448a-b37b-0c535f39c5dd","【2026-10-16】新闻杂烩 - 管子是中立的，管子里的东西不是","2026-10-16-news-roundup","皮卡……所以结论是管子从来就不中立，谁往里塞什么谁说了算。广告里藏间谍软件、Mac上跑816B、苹果给阿里换管子——三件事说明同一句话：管子在哪比管子是什么重要…"]