魔幻嫁接!免费用上完全体的Bitwarden!

Bitwarden以及Bitwarden.com是什么 Bitwarden是一个开源的密码库工具(云服务或自托管),用户可以将所有网站的登录凭据(包含:密码、TOTP、通行密钥等) 端到端加密 存储至其中。并在需要的时候自动填充帮你登录网站。这样,你就不再需要记住各个网站的账号密码了,只要你能访问Bitwarden,它会帮你做好一切 而Bitwarden.com是一项服务,提供用以存储密码库的服务器,使得用户 无需自有服务器 就可以使用Bitwarden Bitwarden.com 免费版的“默认”限制 Best Password Manager for Business, Enterprise & Personal | Bitwarden 免费版没法用TOTP,必须花钱来升级套餐实现 我们当然也可以选择不在任何网站使用TOTP,但这样的话。所有网站都只有密码保护你的账号,从长远来看这并不安全 Bitwarden.com 免费版实际上限制的东西 实际上,如果你曾经用过其他密码库,并存储了TOTP,并将其导入到 Bitwarden.com ,你会发现,它是可以成功导入的,只不过是无法“自动填充” 那么也就是说,实际上 Bitwarden.com 并没有封禁免费用户存储TOTP的权限 它只是在前端阻止了免费用户“自动填充”TOTP的权限 绕过 Bitwarden.com 免费版无法自动填充TOTP的限制 既然它是在前端阻止,我们实际上是有办法绕过的 无非就是自建一个第三方客户端/浏览器插件,然后在判断VIP的字段让它始终返回 true 即可 我们当然可以自己从零来实现,当然,也可以直接寻找市面上已有的,不错的解决方案 针对于 Android 我们可以使用 AChep/keyguard-app: Alternative client for the Bitwarden® platform & KeePass (KDBX), created to provide the best user experience possible. 这个开源的第三方Bitwarden客户端 注意,不要去Google Play下载。只有Github的版本拥有全部功能 此时,登录你的Bitwarden账号,即可绕过免费版限制,使用TOTP自动填充 关于KeyGuard对通行密钥的适配问题 KeyGuard可能无法自动填充你的通行密钥,这可能由多种情况导致,但一般是这种情况: [虫子]通行密钥在Cloudflare上无法使用·第#635期 ·AChep/keyguard-app 可以尝试重新生成一份通行密钥,通过KeyGuard上传至Bitwarden.com 但更建议: 不使用通行密钥,而是使用更广泛的TOTP二步验证方式 ...

February 23, 2026 · 1 min · 122 words

网站加友链的最佳姿势是什么?当然是自动化啦!

起因 正如很多站长都会遇到的那样,如果你通过 PR 来处理友链申请,尤其是在完全没有自动化的情况下,大概率会遇到下面这种场面: 数量多其实还不是最麻烦的,真正麻烦的是: 以及各种格式问题。 是的,我甚至都没有设计什么复杂格式,但很多人提交友链时,连 JSON 都写不明白。上图是忘了引号,下图则连 .json 后缀都没写对。 很长一段时间里,这些小问题我都是手动帮忙修的,毕竟看起来都不算大事。 但问题在于:当你正在打游戏,或者正忙着处理别的事情时,突然弹出一个友链 PR,你到底是现在处理,还是留到之后集中处理?无论怎么选,都挺打断节奏。 所以我就在想:有没有办法把这件事尽可能自动化掉? 正式开始 我们能不能用 GitHub Action 来自动化这件事? 思路是这样的:让用户在提交友链时额外填写一个回链字段,然后由 GitHub Action 实际检测是否存在回链。这样不仅能确认对方确实添加了你的友链,也能顺便完成一次所有权验证。 正式开始(旧的) 我们可以先把整个流程拆开来想一遍。 GitHub Action 本来就是用来处理这类自动化任务的,这不正好符合我们的需求吗?甚至还可以顺手做一些更高级的事情,比如所有权验证,某种程度上和站长平台验证域名的思路很像。 于是,整体流程草图很快就出来了。 接下来再把这份思路交给 AI 帮忙整理实现。 最终你就得到了 没关系,前期看起来乱一点很正常,毕竟 GitHub Action 这类流程很多时候只能在真实环境里慢慢调试。 最终我们就会得到… 看起来是不是很简单?其实并没有。现在看到的这套流程虽然表面上还算清晰,但也是反复梳理和修改之后,才勉强打磨到“基本能用”的状态。 下面再说一些非常容易踩坑的地方。 踩坑 首先,这整套架构虽然最终看起来还算清晰,但实际逻辑并不简单。要是一次就能跑通,那已经算运气很好了;一旦中间某一步出问题,排查起来会相当痛苦。 所以在多次调整架构之后,我最终决定直接使用 GitHub 的标签系统来跟踪进度并锚定规则。 每一步都给 PR 打上明确的标签,就像这样: 这样做的好处是,不仅在外部一眼就能看出某个 PR 卡在哪一步,也能让你在不额外写复杂日志的情况下,大致判断问题出在哪里。 接下来是所有权验证。这个环节其实必须做好错误处理,因为它往往无法一次性顺利跑到底。借助 GitHub 标签,我们可以控制某些步骤是否跳过,从而避免验证文件被重复要求,或者每次都随机生成一个新的文件。 只要打上 所有权验证进行中 这个标签,Action 就会去寻找之前已经创建好的验证文件,而不是重新生成一个新的。 ...

February 17, 2026 · 1 min · 68 words

如何在你的网站上放一个压缩炸弹?

前言 很早之前,我有一位朋友给我发了一个神秘的网站,打开以后就是一直转圈圈 但是正常来说,浏览器的转圈圈是有超时的,我在那等了好几分钟还是在转圈圈 最后发现不是网络请求的问题,而是网页提供的资产的问题! 原始网页发送了一个 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呢?然后将其压缩,最终就能得到一个十分小的压缩文件,但是解压后就会释放出巨大的文件! [!TIP] zstd与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显示 -> 乱码 ...

February 14, 2026 · 1 min · 104 words

阿里云网关 DPI 阻断绕过漏洞分析报告:TLS Client Hello 分片逃逸

[!caution] 提了Bug也没人管,公开了,侵删 阿里云网关 DPI 阻断绕过漏洞分析报告:TLS Client Hello 分片逃逸 目标资产: 0721for.me (未备案域名) 解析 IP: 39.107.95.178 (阿里云) 漏洞类型: DPI 深度包检测逃逸 / Fail-Open (失败即放行) 核心原因: 防火墙 DPI 引擎无法正确处理 TCP 分片的 TLS Client Hello 包 1. 结论摘要 经深度抓包分析,阿里云网关针对未备案域名的 SNI 阻断策略存在严重的底层实现缺陷。当 TLS Client Hello 数据包大小超过以太网 MTU (1500 字节) 从而触发 TCP 分片时,DPI 引擎会因无法重组报文或解析超时而选择直接“放行”。 随着现代浏览器(Chrome/Firefox)和新版工具(Curl)默认启用 后量子加密 (PQC, X25519Kyber768),Client Hello 包大小普遍暴增至 1800+ 字节。这导致正常的现代 HTTPS 流量能够天然绕过监管阻断,而旧版客户端或手动降级的请求反被拦截。 2. 现象对比与证据链 我们对比了多种客户端配置下的抓包数据,结果呈现出完美的二元对立:凡是分片的包均绕过,凡是不分片的包均被拦截。 客户端环境 TLS 关键特征 包大小 (approx) TCP 分片 结果 原因分析 Chrome / Firefox 默认开启 PQC (Kyber768) ~1900 bytes ✅ 是 绕过 (200 OK) 包过大触发分片,DPI 解析失败导致放行 Curl (Linux 新版) 默认开启 PQC (Kyber768) ~1800 bytes ✅ 是 绕过 (200 OK) 同上 Curl (伪装 TLS 1.2) 伪装 1.2 但带 PQC Key Share ~2400 bytes ✅ 是 绕过 (200 OK) 只要有 PQC 撑大包,版本号伪装也能过 Curl (手动指定) --curves X25519 (禁用 PQC) ~300 bytes ❌ 否 拦截 (RST) 单包完整,DPI 成功提取 SNI 并拦截 Curl (Windows) 旧版/Schannel (无 PQC) ~450 bytes ❌ 否 拦截 (RST) 同上 Firefox (强制 1.2) 纯 TLS 1.2 (无 KeyShare) ~180 bytes ❌ 否 拦截 (RST) 纯 TLS 1.2 包极小,DPI 轻松解析拦截 3. 技术细节分析 3.1 核心机制:PQC 撑爆 MTU PQC 引入:TLS 1.3 引入了后量子加密算法支持。主流的 X25519MLKEM768 (Kyber768) 密钥交换需要在 Client Hello 的 key_share 扩展中携带约 1200 字节 的公钥数据。 包大小激增:加上其他常规扩展(SNI, ALPN, Signature Algorithms 等),整个 Client Hello 的长度通常在 1800 - 2500 字节 之间。 TCP 分片:标准以太网 MTU 为 1500 字节。超过此大小的 TLS 握手包必须被网络协议栈拆分为多个 TCP 段(Segments)发送。 3.2 DPI 缺陷:Fail-Open 解析逻辑:阿里云网关的 DPI 引擎似乎仅检测 TLS 握手的第一个 TCP 数据包。 截断失效:对于分片的 Client Hello,SNI 扩展虽然通常在第一个包中,但由于 TLS Record Layer 的 Length 字段指示的长度(如 1800)远大于实际接收到的第一个分片长度(如 1400),DPI 引擎会判断为报文不完整或无法解析。 策略选择:为了避免在高并发下进行昂贵的 TCP 流重组(Stream Reassembly),或者避免误杀(False Positive),DPI 采取了 Fail-Open 策略,即 “看不懂就行”。 3.3 关键抓包证据 (Wireshark Frames) Frame 4251 (Firefox - 绕过): Length: 1890 [2 Reassembled TCP Segments] Extension: key_share ... X25519MLKEM768 Frame 964 (Firefox 强制 TLS 1.2 - 拦截): Length: 186 无 key_share,无 PQC。 单包发送,立即 RST。 Frame 568 (伪装 TLS 1.2 - 绕过): Version: TLS 1.2 但包含 PQC Key Share。 Length: 2441,分片 -> 绕过。 4. 危害与建议 危害:当前的监管阻断策略对现代流量(主流浏览器、新版工具)几乎完全失效,仅能拦截旧设备或特定配置的爬虫,形同虚设。 建议: 升级 DPI 引擎:必须支持 TCP 流重组(Reassembly),确保能够还原并解析跨包的 TLS Client Hello。 优化解析逻辑:即使不重组,也可以尝试在第一个分片中尽力提取 SNI(SNI 通常靠前),但这可能容易被 Padding 混淆绕过。最稳妥的方式依然是流重组。

February 11, 2026 · 2 min · 310 words

论DeepWiki为什么是神!

这是什么? 在AI大道当行的时代,DeepWiki提供免费的AI用以分析全球的Github仓库,只要你的仓库有一些Star,稍微流行一些,就有可能被DeepWiki收录,并且自动通过AI大模型创建专属于你的Github仓库的强大Wiki! 如何查看我的仓库是否被收录? 前往 DeepWiki | AI documentation you can talk to, for every repo 搜索你的 Github 用户名 即可看到当前DeepWiki收录的你的所有仓库 DeepWiki爬取的频率不算很高,我们可以通过在仓库README添加一串文本来声明该仓库希望DeepWiki收录,之后,按DeepWiki所说,将会每周爬取一次最新代码并生成Wiki [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/你的Github用户名/你的Github仓库) 之后,若DeepWiki已经收录该仓库,你将可以看到醒目的提示 接下来…? 你可以将DeepWiki贴到你的网站,服务,App上,让用户遇到问题直接询问DeepWiki!无需再手动搭建你的知识库了! 又或者,你也可以打开其他仓库的Wiki,尝试通过询问DeepWiki AI来快速上手他们!

February 11, 2026 · 1 min · 27 words

连着被打了4个月,来做一个彻头彻尾的复盘吧!

引言 本站建站初使用 静态 架构就是防止别有用心之人进行DDoS 你想啊,一个静态网站,所有攻击流量都是打在 CDN的边缘节点 上,也就是等于攻打 整个CDN厂商 一是很难打死,二是没必要,毕竟静态网站的背后没有源站,也不涉及利益,纯粹是白打 正常来说,DDOS应该是针对单个IP的,因为正常来说,运营一个网站,肯定是需要买一台服务器,然后再在其上跑服务,最终一切准备就绪开放到公网中 如果说没有高防,并且没有CDN,市面上很多的免费DDOS就可以轻松将一个IP打死 但是,该网站情况非常不同,它是一个 由CDN直接应答的静态网站 也就是说,攻击该网站 = 攻击CDN 按往常来说,这几乎是不可能的 从宏观角度来思考,CDN是用来清洗流量的,清洗恶意流量,然后放行干净流量访问源站 但是如果是一个静态网站呢? 它根本就没有源站,每一个请求都被视为有效请求被CDN所应答 所以综上,如果有人打CDN,绝对是自讨苦吃,我也根本不需要管 但,真的是这样吗? 如果说攻击者的目的不是 打死CDN 呢? 那么事情就变得有趣起来了 第一次大规模攻击:6.65TB流量冲击 以下记录于2025年12月16日,是本站遭受的第一次大规模DDoS攻击 于 2025年12月16号 11:13,我在和我的朋友测试项目的时候,有一个知识点他忘记了,我提议他前往我的博客查看,却被告知博客访问报 570 状态码 我立即使用 https://itdog.cn 测试了我的博客网站 https://acofork.com 发现大部分节点都为 570 状态码 因为当时我的网站部署在 EdgeOne 随后,我向腾讯客服求证,了解到该状态码是一个 单节点限频访问 的状态码 我的朋友甚至还在调侃说:你网站🔥了 但是事情貌似还有一些诡异,为什么海外都是 200 OK? 我开始怀疑被打了 可能玩静态久了,没有第一时间上到 EdgeOne 查看请求数和流量,想着都是静态,谁没事打呢 然后我就回家,暂时切了一下逻辑 之前:EdgeOne Pages 直接提供服务,但是570 现在:EdgeOne CDN 回源 Cloudflare Pages 切完后逐步好转,虽然速度有些慢,然后我就睡觉了 真相大白 睡醒后我越想越奇怪,于是就登上了 EdgeOne Pages 控制台,然后一看,我嘞个大雷 ...

February 10, 2026 · 1 min · 154 words

你需要为你的网站上水印吗?水印怎么打才有效?

[!CAUTION] 2月4号的2xss你好呀 你TM加几把水印呢,还不备份,还Drop并且强制推送远端,还TM给Github发邮件让他们GC 你知道老子今天从 .edgeone .astro 里面找缓存的没水印的原图图片有多几把难吗 你真的牛大了,给我桂霞! 前言 这是很早之前的事了,简单来说就是有人盗了我的这一篇文章: 关于我折腾了一晚上 EdgeOne - AcoFork Blog 这是他发在微信公众号上的: https://mp.weixin.qq.com/s/F4R6FtJmyHEaKkeMDI6IDw 可以看到,文章纯纯是照搬,而且格式有很多明显错误,并且图片也是用的我的,甚至你还能看到上古域名 afo.im 并且不难发现,它的文章发布日期为 而我的文章发布日期为 有人可能会说,你是静态博客,发布日期只是一串数字,可以随便改,那么我拿出Github当时的提交记录 又有人可能会说了,浏览器中的HTML是可以改的,那么我给出当时的提交URL,你们可以自行查阅: posts: 发布文章:关于我折腾了一晚上 EdgeOne(ps:腾讯云我草泥马😅) · afoim/fuwari@4e8fa65 好的,那么至此我应该可以证明我是原作者了 其实被盗文章也没啥,我本身也不通过文章来盈利。但是,当我看到我自己拿我自己电脑使用QQ截的图片被发到微信公众号上并默认添加了他的水印,就有点膈应了 我向来视我的文章如老婆,他这样一整就好像我被NTR了一样 那么开始水印战争吧,我要让盗文章的就算盗了,也要让最终读者知道到底是谁做的 正式开始 终于又到了我最喜欢的技术环节,那么既然要加水印,我最先想到的就是一个十分古老的LSB水印项目: guofei9987/blind_watermark: Blind&Invisible Watermark ,图片盲水印,提取水印无须原图! 它的原理非常简单,就是对图像做一点很细微的改动,通过改动像素来插入一个编码后的二维码,由于二维码天生抗干扰,再加上一张正常规格的图片像素点非常多,该项目README演示了对添加水印的图片做旋转,缩放,遮挡都可以完整提取出水印 我当场就扒下来看了看用了用,发现并不是很适用 首先就是我的图片在正式在网站中展示前都会被Sharp进行压缩,虽然WEBP是个好格式,它可以大幅缩减图片大小,而质量仅下降一点点。但是对于LSB来说,你对大部分像素完全遮挡不是什么问题,但是WEBP是对整个图像进行压缩,这无疑是对所有像素进行“污染”,实测一旦通过压缩,甚至是简单的重复截图就可以完全破坏水印,而且该项目由于是专注于LSB水印,默认添加的水印也是不可见的,除非你是显微镜,否则文章被盗后甚至是平台默认加个水印,你的水印就不翼而飞了 接下来我就尝试使用传统水印,由于我的博客本身在构建的时候就会使用Sharp进行压缩,Sharp本身也就是一个高效的图像合成库,我就直接拿它将我的域名作为水印覆盖到每一张图上 就像这样: 这里就不配图了,因为按理来说现在全站的文章都有这个神秘的水印 到这应该就结束了,但是为了严谨,避免别有用心之人跑到Github上面去扒我们的历史提交,我们应当重写仓库历史提交,删除所有图片,然后在这次提交中再提交回来,并且找Github删除孤立的提交与资源文件,详见: 如何让一个文件在Git提交中永远消失?如何丢掉其中一条提交并保持逻辑完整? - AcoFork Blog 至此,应该再无任何人能得到无水印的原图了,只要我不再写完新文章后忘记运行加水印的脚本,结束 题外话 让文章不被盗是不可能的,对于文本内容,几乎无计可施,因为别有用心之人仅需爬RSS即可获取你的文章,但是对于图片,我们也只有加水印这一种方式,虽然这会让原本干净的图片变得有点遭

February 4, 2026 · 1 min · 52 words

你真的懂了浏览器跨域吗?COOP,COEP,CORP,CORS都是管什么的?

正式开始 如果你做过网站(HTML),你就会知道,一个网页除了自身提供内容,如 <p>hello world</p> ,还可以 内嵌外链资源 ,如 <img src="https://othersite.com/hello.webp"> 一方面,HTML允许我们非常自由的引用资源,另一方面,这也会造成一些问题 我们不妨设想一下,你有一个图库站点,里面全都是高清大图,网站访问量也特别高。如果这个时候有人眼红了,也想做一个这样的站点,它可以直接通过HTML做个壳,把品牌改成自己的,然后引用你的图片,这样,它只需要托管很少的文本文件(HTML壳),而无需托管实际图片 那我们肯定不能让他这样,怎么办呢,所以我们需要让我们的图片在被拉取时返回一个 CORP 响应头,并且值为 same-site ,这样,只要不是你的域名写 <img> ,浏览器会统统阻断加载 这就是 CORP(Cross-Origin-Resource-Policy) - 跨域资源策略,它管的是 资源给不给用 值 描述 same-origin 同源。仅允许 example.com 拉取对应资源 same-site 同站。仅允许 *.example.com example.com 拉取资源 cross-origin 默认值。允许所有源,任何人都可以拉取 好的,我们解决了图片被滥用的问题。接下来更棘手的来了,我们还有一个其他网站,不过它并不提供媒体资源,而是在访问的时候获取访客IP 本来这只是你自用的一个网站,但是你发现最近后端的日志有很多乱七八糟的IP,经过一番盘查,你发现有一个网站的底部会显示访客IP,通过F12查看网络请求发现这就是请求的你的网站! 接着你查看了一下这个API返回的响应头,发现你之前为了跨域调用方便设置了 Access-Control-Allow-Origin: * ,该头会允许任何人调用你的API并且获取响应 再然后,你将该头的值改为了 yoursite.com 这样,就只允许你自己的网站来调用该API了。其他人调用依旧会被浏览器拦截 接着,你又做了个网站,并且为各个地区访问的访客配置了不同的CDN图床,你想让该网站告诉用户您正在使用什么CDN 于是你灵机一动,想到各家CDN返回的响应头 Server 的值都不一样,于是就写了一点JS读取响应头并回写到页面上,但是你发现页面上并未显示,并且网络请求是一个奇怪的状态 200 Failed 于是你思考了一下,哦!对了!由于是不同的CDN图床,且主站域名为 blog.yoursite.com ,图床域名为 img.yoursite.com ,会触发跨域! 虽然你已经经过上次的教训正确设置了 Access-Control-Allow-Origin 头,但是对于浏览器来说,你只是允许了别人读取我的响应体,并没有规定响应体,然后你打印了一下JS获取到的所有响应头,你发现只能读到 Content-Type 等几个无关响应头,JS根本看不见 Server 头 然后你费劲千辛万苦,终于在各大CDN都配置了返回 Access-Control-Expose-Headers: server ,然后,你的代码终于工作了! 接着,随着你的网站越做越大,你想给网站添加一个访问量显示模块,但是由于网站本身是静态的,你又不想在全是前端代码的项目里面插后端代码,于是你很聪明,想到了搭建另一个服务,Umami,然后将追踪JS嵌入你的网站,你再通过客户端JS读取Umami的公开页面获取访问量 ...

February 2, 2026 · 3 min · 531 words

让我们来看看图片防盗链各大厂做的怎么样!

这是什么? 只是随便搜集的一些头像接口,全部来自于我手机里目前安装的大部分APP服务。其中无 Web 标识的头像,如果你能看得见,那么证明该服务商并没有做严格的SSL校验,导致逆向极其简单。无该标识的默认为移动APP。以下所有资源均来自我个人使用的账号 一些小发现 微软(Microsoft)的头像非常严格,使用Cookie校验,不能直接访问 微信、支付宝,TapTap,钉钉不采用Web协议,故抓不到包 小黑盒,网易云音乐,酷安,作业帮,豆包,肯德基,库街区都采用了严格的SSL校验,不能直接访问 下述图片,除了TapTap校验Referer,其他都没有校验Referer,故可以直接访问。不过就算校验Referer也是徒劳 头像 描述 QQ OPPO(Web) Google(Web) 小米(Web) 京东(Web) 高德地图(Web) 美团 淘宝 拼多多 GitHub(Web) Telegram(Web) WPS(Web) 闲鱼 好游快爆 网易云音乐(Web) KOOK TapTap(Web) (微信)公众号助手 百度网盘 Steam(Web) 这表明了什么? 对于图片,音乐,影片等静态资源,若直接使用 img audio video 等标签,无需CORS即可将远端资源在任意网页上展示。这是W3C规范的一部分,详情请参考 HTML5 嵌入内容 当然,如果您是一个网站的维护者,您可能不想让陌生人直接将你的资源展示给别人看,或者怕被刷出账单,下面我将简单说明哪些措施是有效的,哪些是掩耳盗铃 首先我们来分辨一下您手动做服务端的防盗链和浏览器CORS的区别: 浏览器CORS是客户端行为,当某个行为被对端CORS策略拒绝,浏览器会阻止响应体。而服务端防盗链是在您的后端上编写一些小脚本,用以拒绝非法访问。前者会在用户浏览器弹出CORS错误,而后者会在用户浏览器显示错误状态码,如500,401,403,这取决于您的实现 是否可以尝试设置Referer白名单来拒绝非法访问? 没用 因为Referer在浏览器中是可以伪造或者不发送的。详见 HTML 5 引用来源策略 您应该做的事情稍微有些复杂,如将API放到Cookie(登录,非游客权限)中,并且让后端处理Cookie的发放与吊销。就像微软那样 又或者说,您只想要用户仅能通过浏览器单独查看图片,而不让 任何人(包括您) 引用图片到网站中,您可以使用 Accept 请求头 白名单,您可以尝试比较一下这两个 Accept 请求头 ,前者是直接访问图片浏览器自动发送的,而后者是引用时发送的 ...

February 1, 2026 · 1 min · 104 words

想要一个Cookie管理器?无需手搓!

前言 你的网站是否有很多的跟踪器?如 Google Analytics、Google Adsense、Microsoft Clarity、百度统计 等等? 他们有些是追踪用户体验,获取站点访问数据,有些是提供广告,为您提供收入… 但是,用户是有权限拒绝某些东西的,如拒绝将访问信息传送给Google,或让展示的广告与个性化无关等等 那么我们要如何实现让用户控制自己的数据被传送向何方呢? 你可能会想到,我们可以先编写一个入口脚本,管理这些JS,让用户同意某些再执行JS,又或是和Service Worker约定拦截某些请求 这对于架构设计来说肯定是极好的,但是我们真的有必要手搓一个Cookie管理器吗,为何不去使用一个现成的解决方案呢? Download Cookie Consent Banner: GDPR + ePrivacy Directive 它就是一个很好的选择,在该网站上提供你需要被管理的JS脚本片段,然后将该网站返回的JS脚本插入您的站点即可!无需编写额外的JS代码,无需管理复杂的Service Worker约定!这一切也都是通过该网站的客户端JavaScript实现的! 正式开始 首先,我们进入 Download Cookie Consent Banner: GDPR + ePrivacy Directive (搭配浏览器翻译),往下滚动,找到步骤图 第一步,首先选择基本逻辑 电子隐私指令:当用户未进行Cookie管理时,这往往是用户第一次进入你的网站,允许所有受管理的JavaScript脚本执行 GDPR + 电子隐私指令:字面意思,用户不允许就永远不加载 第二步,设置网站名称,布局样式以及提供您的隐私政策页面 首先填写网站名称,这会在用户管理Cookie时显示 接下来选择布局,你可以在网站中看到实时更改与实际交互样式,这里不再赘述 然后,选择色彩搭配,这里是硬编码的,但是更建议后续通过JS动态更改自动适配白天/黑夜模式 默认语言用英语即可,该管理器提供了多达 36 种 语言,但就是没有简体中文,不过在实际的管理器中有繁体中文。不过英语仍然是一个较好的选择,它易读也是使用率最高的语言,这没什么问题 最终,对于隐私政策,这是个可选项,但是强烈建议配置。不过如果您暂时没有配置,也不用着急,先预填写一个将来的隐私政策URL(http/https开头),后续我会说明为什么这几乎是一个必填项 第三步,导入您的JS Ok,终于到重头戏了,接下来,我们需要将我们网站上原来安装的各种追踪器(JS片段),归类然后一个个按部就班的添加进Cookie管理器 这里的名称仅会在最终代码中展示出来,站点访客仅能管理这四种类型是开是关(这也是为什么上文说你几乎配置一个隐私政策页面,否则用户根本不知道这四种类型分别对应着什么),其中,第一个类型是必开的,所以你可以在其中放入一些不运行这些JS网站就不正常的脚本(如评论区) 第四步,复制网站提供的JS,将其粘贴到您网站的 <body> 后。并移除重复的JS片段 值得注意的一点是,当用户在第一屏选择完要启用的Cookie后,日后想更改这些首选项,需要怎么做呢? 网站在提供的代码最后添加了一个特殊标签的按钮,也就是 id="open_preferences_center" ,你可以先将红框中的代码移除,否则可能会破坏布局,接下来找一个地方放置这个 编辑您的Cookie首选项 按钮,让用户可以轻松的更改Cookie首选项,而不是需要用户伪造一个按钮来手动触发这个id 最终效果 当用户第一次访问时,会弹出是否允许Cookie的弹窗。用户可以选择全部允许(I agree),全部拒绝(I decline)或高级配置(Change my preferences) ...

January 30, 2026 · 1 min · 72 words