安全
一个站点密钥的 安全 页决定挑战有多难,以及哪些请求被允许到达它。默认值是一个稳妥的折中;这一页讲的是何时该离开它们,以及朝哪个方向。
从这里开始
大多数站点都应该让默认值原封不动。当你有理由时,再去拨下面这些旋钮:
- 你正遭受活跃滥用,或表单价值很高(注册、支付、密码重置):把防护调高。提高 难度,提高 混淆级别,并打开 阻止自动化浏览器。你用一点访客算力和一些服务器 CPU,换来一堵高得多的墙。
- 速度和转化最重要,而风险很低(一个营销页上的订阅框):让防护轻一点。把 难度 留在低位、把 每请求挑战数 留在 1,好让挑战在一部便宜的手机上轻如鸿毛。
这一页余下的部分,就是每个旋钮以及该朝哪个方向拧。
要求一个游戏
这里最强的控制,是要求访客玩一个游戏才能通过,而不是只通过那道不动声色的背景检查。在这里、在安全页上,打开 要求一个游戏来验证,于是每位访客都必须通过这个密钥上已注册游戏中的一个。服务器挑选每位访客拿到哪个游戏,所以它无法被跳过或替换。
你注册一个密钥可用的游戏,那里也正是这个关卡把自己完整讲清楚的地方,在该密钥的 游戏与游戏关卡 页上。在至少注册一个游戏之前,你打不开这个关卡。把它关着是更不安全的选择:这个密钥不玩游戏也能通过。
Proof of work:难度与每请求挑战数
Proof of work 让浏览器解一个小谜题,好让大规模的滥用变得昂贵(见 proof of work)。
- 难度(1 到 8)设定每个谜题有多难。越高让攻击者花得越多,但也让访客的设备花得越多,低端手机在区间顶端会有感觉。从默认值起步,只有当你真的看到滥用时才提高它。
- 每请求挑战数(1 到 500)一次要求好几次求解,把成本翻倍。把它留在 1,除非你有一个具体理由要堆得更多。
浏览器在一个 Web Worker 里解这些谜题,所以你页面的 Content-Security-Policy 必须为 worker 允许 blob:(worker-src blob:);这一条是必需的。在 script-src 里允许 'wasm-unsafe-eval' 还能让求解器作为快速的 WebAssembly 运行,但那是可选的:没有它,求解器会在同一个 Worker 里退回到一个较慢的纯 JavaScript 实现,验证照样能用。完整的宿主页策略见 游戏沙箱。
探测:混淆级别与阻止自动化浏览器
探测在访客的浏览器里跑一个小程序,以检查是一个真实的浏览器、而非一个脚本,解开了这道挑战(见 探测)。它默认开启,是唯一能把真实浏览器和自动化浏览器区分开的那一层。
- 探测 可以按密钥 关闭。几乎每个站点都让它开着。只有当嵌入你组件的那个页面跑着一个无法允许
'unsafe-eval'的 Content-Security-Policy 时(探测程序需要它,见下文),才把它关掉。关了它,这个密钥就再也检测不到自动化浏览器,不过 proof of work 和任何必需的游戏照样会跑,而且下面这两项设置也不再生效。 - 混淆级别(1 到 10)是这个浏览器内程序逆向有多难。越高越强,但用更多服务器 CPU。默认值对大多数站点都合适;如果你是某个频繁、定向的攻击者的靶子,就提高它。
- 阻止自动化浏览器 会直接拒绝检测到的 headless 和 WebDriver 客户端。如果从没有合法的自动化碰你的表单,就把它 打开。如果你预期有合法的机器人(你自己的监控、合作方集成、无障碍工具),就把它 关着,因为它也会把那些挡掉。
Content-Security-Policy
探测程序会在访客的浏览器里跑 eval,所以嵌入你组件的那个页面必须在它的 script-src 里允许 'unsafe-eval'。这是那一条硬性的 CSP 要求,而且它没有退路:如果 'unsafe-eval' 被挡掉,验证会超时,浏览器控制台会显示 [cap] Instrumentation failed。你有两个选择:在承载组件的页面上允许 'unsafe-eval',或者把 探测 关掉(见上文)以移除这个要求。一个宿主页的 CSP 需要什么的完整清单,在 游戏沙箱 上。
必需的头
你可以要求每个请求都带上某个特定的头。大多数站点不需要这个;当你自己的客户端总会发出一个你能据以设关卡的头时,它作为一个廉价的额外过滤器才有用。
你 不能 要求的,是 Caputchin 为隐私在一个请求到达验证之前就剥离的那些头。它们标识访客,而 Caputchin 的姿态是不采集逐访客数据,所以它在平台边界处把它们丢掉:
| 被剥离的头 | 为什么被丢掉 |
|---|---|
cf-connecting-ip | 访客的 IP,由 Cloudflare 设置。绝不越过边界,所以 Caputchin 既不存储它,也不据它核对。 |
x-forwarded-for | 透过代理看到的访客 IP。同一个原因。 |
x-real-ip | 来自上游代理的访客 IP。同一个原因。 |
user-agent | 访客的 User-Agent 字符串,它标识他们的浏览器和设备。 |
sec-ch-ua*(每一个 Sec-CH-UA 客户端提示:sec-ch-ua、sec-ch-ua-platform、sec-ch-ua-mobile,以及其余的) | User-Agent 的结构化形式。同一道隐私边界。 |
要求其中之一会挡住每个请求,因为它从不到达,所以平台拒绝那种配置,而不让你把密钥变成砖头。
速率限制与 CORS 来源
- 每秒最大请求数 限制这个密钥接受请求的最快速度。如果你确实流量很大,就提高它;要扼制一个正被猛击的密钥,就降低它。
- CORS 来源 是你的来源允许列表,在服务端、在谜题运行之前就强制执行。当你从
localhost测试时把它留空;在上线之前,加上你真实的来源,好让只有你自己的站点能用这个密钥。