---
type: explanation
title: 安全
summary: 如何调优一个密钥的防护，以及如何在更强和更快之间取舍。
---

一个站点密钥的 **安全** 页决定挑战有多难，以及哪些请求被允许到达它。默认值是一个稳妥的折中；这一页讲的是何时该离开它们，以及朝哪个方向。

## 从这里开始

大多数站点都应该让默认值原封不动。当你有理由时，再去拨下面这些旋钮：

- **你正遭受活跃滥用，或表单价值很高**（注册、支付、密码重置）：把防护调高。提高 **难度**，提高 **混淆级别**，并打开 **阻止自动化浏览器**。你用一点访客算力和一些服务器 CPU，换来一堵高得多的墙。
- **速度和转化最重要，而风险很低**（一个营销页上的订阅框）：让防护轻一点。把 **难度** 留在低位、把 **每请求挑战数** 留在 1，好让挑战在一部便宜的手机上轻如鸿毛。

这一页余下的部分，就是每个旋钮以及该朝哪个方向拧。

## 要求一个游戏

这里最强的控制，是要求访客玩一个游戏才能通过，而不是只通过那道不动声色的背景检查。在这里、在安全页上，打开 **要求一个游戏来验证**，于是每位访客都必须通过这个密钥上已注册游戏中的一个。服务器挑选每位访客拿到哪个游戏，所以它无法被跳过或替换。

你注册一个密钥可用的游戏，那里也正是这个关卡把自己完整讲清楚的地方，在该密钥的 [游戏与游戏关卡](/docs/site-keys/games) 页上。在至少注册一个游戏之前，你打不开这个关卡。把它关着是更不安全的选择：这个密钥不玩游戏也能通过。

## 预览模式

在你还在搭建集成期间，**预览模式** 自动放行这个密钥上的每一次验证，于是你能接通组件和你的 `/siteverify` 后端，而不必每次都去解真正的挑战。组件和任何被要求的游戏仍然原样显示访客会看到的样子；只有裁决被强制为通过，而每一条会话都被标记为预览。它把这个密钥的机器人防护 **关掉**，所以上线之前把它重新关掉。完整细节见 [预览模式](/docs/site-keys/preview-mode)。

## Proof of work：难度与每请求挑战数

Proof of work 让浏览器解一个小谜题，好让大规模的滥用变得昂贵（见 [proof of work](/docs/understanding-caputchin/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 实现，验证照样能用。完整的宿主页策略见 [游戏沙箱](/docs/understanding-caputchin/game-sandboxing#the-csp-you-set-on-your-own-page)。

## 探测：混淆级别与阻止自动化浏览器

探测在访客的浏览器里跑一个小程序，以检查是一个真实的浏览器、而非一个脚本，解开了这道挑战（见 [探测](/docs/understanding-caputchin/instrumentation)）。它默认开启，是唯一能把真实浏览器和自动化浏览器区分开的那一层。

- **探测** 可以按密钥 **关闭**。几乎每个站点都让它开着。只有当嵌入你组件的那个页面跑着一个无法允许 `'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 需要什么的完整清单，在 [游戏沙箱](/docs/understanding-caputchin/game-sandboxing#the-csp-you-set-on-your-own-page) 上。

## 必需的头

你可以要求每个请求都带上某个特定的头。大多数站点不需要这个；当你自己的客户端总会发出一个你能据以设关卡的头时，它作为一个廉价的额外过滤器才有用。

你 **不能** 要求的，是 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` 测试时把它留空；在上线之前，加上你真实的来源，好让只有你自己的站点能用这个密钥。

## 另见

- [预览模式](/docs/site-keys/preview-mode)，在你搭建并测试期间自动放行每一次验证。
- [游戏与游戏关卡](/docs/site-keys/games)，去注册游戏并要求一个来验证。
- [站点密钥](/docs/site-keys/overview)，看一个密钥的其余部分。
- [统计与会话](/docs/site-keys/statistics)，看你的设置是否在拦住对的流量。
