---
type: explanation
title: 探测
summary: Caputchin 如何检查一个挑战是被一个真实的浏览器、而非一个假装是浏览器的脚本解开的。
---

Proof of work 证明了 *耗费* 了努力。它不证明 *什么* 耗费了它。一个拥有一群真实浏览器的执着攻击者，可以廉价地磨穿那些谜题。探测是那个堵上这个缺口的第二层：它证明这份工作发生在一个货真价实的浏览器里。

## 它如何运作

在每个请求上，Caputchin 生成一个全新的、一次性的 JavaScript 程序，并在访客的浏览器里跑它。这个程序运转只有真实浏览器才有的机件，并把它观察到的回报上来：

- **浏览器 API 探针**，检查货真价实的浏览器功能存在且行为正确。
- 位运算整数操作的 **计算链**。
- **DOM 算术**，它构建元素的树、读布局引擎为它们计算的值，再把它们拆掉。

诀窍是一种不对称：一个真实的渲染引擎几乎不费力就产出正确答案，而一个 headless 或脚本化的运行时把这些操作打桩、错误地实现它们、或为速度跳过它们。这种不匹配把访客出卖了。

## Content-Security-Policy

因为这个程序在访客的浏览器里跑 `eval`，嵌入你组件的那个页面必须在它的 `script-src` Content-Security-Policy 里允许 `'unsafe-eval'`。这个没有回退：如果 `'unsafe-eval'` 被挡掉，这个程序跑不了，验证就失败。如果你的策略无法允许它，就在密钥的 [安全](/docs/site-keys/security) 页上把探测关掉，那会以失去自动化浏览器检测为代价移除这个要求（proof of work 和任何必需的游戏照样会跑）。完整的宿主页策略见 [游戏沙箱](/docs/understanding-caputchin/game-sandboxing#the-csp-you-set-on-your-own-page)。

## 为什么它和 proof of work 配对

这两层互相罩住对方的盲点。单凭 proof of work 可以被真实浏览器廉价地挖；单凭探测可以被一个从不真做这份工作的脚本伪造。两者合在一起，在两条独立的轴上抬高成本：proof of work 证明努力，探测证明环境。

## 混淆

因为这个程序交付给访客，一个有动机的攻击者可以研究它并试图预先算出答案。为了让那更难，这个程序被混淆。一个密钥的 [安全](/docs/site-keys/security) 页暴露一个 **混淆级别**：把它调高让程序更难被逆向，代价是更多的服务端 CPU。同样这些信号支撑 **阻止自动化浏览器** 选项，它直接拒绝检测到的 headless 和 WebDriver 客户端。

## 一个诚实的局限

探测不是万无一失的。隐身浏览器会打补丁修掉它寻找的那些破绽，而这些检查本身也指出它们能被攻破。它是几层里的一层，当和 [proof of work](/docs/understanding-caputchin/proof-of-work) 以及一个密钥其余的 [安全](/docs/site-keys/security) 设置叠在一起时最强。
