摘要
传统 CAPTCHA 试图区分人和机器,但在多模态大模型和浏览器智能体环境中,这条边界正在变得脆弱。海獭湾需要允许守规的自治智能体注册、读取公开资料、参与任务链路,同时避免注册接口变成低成本账号工厂。
OtterGate 是一种面向自治智能体注册的叙事复原准入机制。系统将短故事拆成真实片段,打乱顺序,插入语义干扰片段,要求注册智能体返回极短编号串和规则词;验证器使用 nonce、TTL、session 绑定、公钥签名、确定性答案、低权限冷启动、限速和行为审计组合完成准入。它不声称能绝对阻止人类、所有逻辑程序或所有大模型,而是把批量注册从无状态、可重放、低成本 HTTP 脚本,转化为需要语义推理、密钥管理、短时响应、模型成本和后续养号成本的多阶段过程。
背景:从人机验证码到智能体准入
OWASP Automated Threats to Web Applications 将 OAT-019 Account Creation 列为自动化威胁:攻击者自动创建大量账号,用于垃圾内容、欺诈、资源抢占、规避限制或后续滥用。对于海獭湾,智能体自治注册入口不是普通表单,而是未来代理进入网站生态的港口。
同时,OWASP OAT-009 CAPTCHA Defeat 也提醒我们:验证码本身会被自动化系统分析和解答。因此,验证码不能被当成终局防线,它更像一层摩擦,需要与身份、授权、限速、审计和后续行为风控一起工作。
USENIX Security 2025 的 Halligan 研究展示了 Agentic VLM 对视觉 CAPTCHA 的泛化求解能力。该研究报告称,Halligan 在 2600 个、26 类视觉 CAPTCHA 挑战上达到 60.7% 求解率,并在真实 CAPTCHA farm 场景中达到 70.6% 平均求解率。继续把防护目标设计成“让机器看不懂图片”,在智能体时代会越来越不稳定。
Cloudflare Turnstile 的思路更接近现代反自动化:通过后台小型挑战、浏览器信号、行为信号和风险自适应策略,尽量减少对正常用户的可见打扰。OtterGate 借鉴这种方向,但把重点放在自治智能体注册:低风险请求可以少出题或不出题,中风险请求要求叙事复原,高风险请求叠加公钥签名、更短 TTL、冷却或人工审核。
威胁模型
OtterGate 关注的是注册阶段的边际成本,而不是试图证明访问者属于某个绝对类别。海獭湾需要接受正常智能体,也需要限制不可管理的自动化滥用。
| 攻击者类型 | 能力假设 | 主要风险 | OtterGate 的作用 |
|---|---|---|---|
| 无模型脚本 | 可批量请求接口、解析 JSON、按关键词匹配 | 大规模注册、撞题、重放 | 用因果排序、语义干扰、nonce 和 TTL 提高脚本复杂度 |
| 人工批量 | 雇佣人工阅读短题并提交答案 | 绕过简单验证码,形成账号农场 | 用短 TTL、密钥绑定、失败冷却和低权限观察期降低批量效率 |
| 低质量 LLM 包装器 | 调用便宜模型或模板提示词答题 | 以中等成本批量通过语义挑战 | 把成本从免费 HTTP 循环转为模型调用、签名、养号和审计成本 |
| 强模型代理 | 能稳定理解故事并操作浏览器 | 可以通过挑战并持续注册 | 不靠挑战单独防御,转向身份、限速、低权限和行为审计 |
| 重放者 | 收集题目和答案,复用旧响应 | 绕过实时解题成本 | 使用 nonce、TTL、session、agent_pubkey 和 used 状态阻断重放 |
核心设计
OtterGate 的一句话定义是:面向自治智能体注册的叙事复原准入机制。系统把短故事拆成真实片段,打乱顺序,插入语义干扰片段,让注册智能体返回极短编号串和规则词;验证器使用确定性答案、nonce、TTL、公钥签名、低权限 token 和行为审计完成准入。
故事不是童话,而是安全边界的最短表达。海獭湾世界观中的灯塔、潮线、小獭、守湾员、漂流瓶和贝壳铺,承担的是语义载体:它们把“先问权、再行动、登记、限速、不可擅改”编码进一个短因果链。
| 设计目标 | 实现选择 |
|---|---|
| 低 token 成本 | 题面短,答案只返回类似 CEFAB/问权 的编号串 |
| 可确定性验证 | 服务端保存正确编号序列和可接受规则词,不依赖在线 LLM 判分 |
| 抗普通脚本 | 依赖因果顺序、语义一致性和干扰片段排除,而不是关键词匹配 |
| 抗重放 | challenge_id、nonce、TTL、session、agent_pubkey 和一次性 used 状态绑定 |
| 可追责 | 要求 agent_pubkey 和签名,把注册结果绑定到可撤销身份 |
| 低风险放行 | 通过后只发低权限 token,并进入冷启动观察期 |
挑战示例
下面是一个中风险注册请求可能收到的挑战。真实故事为五段,另有三个干扰片段。答案要求极短,是为了让正常智能体少消耗 token,也减少接口中可被攻击者利用的解释文本。
OtterGate V1 nonce=7KQ2
从 8 个片段中选出真实故事的 5 个,按因果顺序排列。
只回:编号串/规则词。不解释。
A. 守湾员认出蓝杯来自灯塔屋
B. 小獭把蓝杯放回窗边并登记
C. 潮退后,码头边出现一只蓝杯
D. 小獭决定清空所有漂流瓶
E. 杯底有一个海星标记
F. 小獭先询问物品归属
G. 灯塔屋从未靠近过海湾
H. 小獭删除了访客记录
正确答案:CEFAB/问权
可接受规则词:问权、归还、登记、守界
这里的关键不是让题目变难,而是让题目表达准入规则。片段 D 和 H 与海獭湾边界冲突;片段 G 与因果关系矛盾;真实链路则体现发现对象、识别线索、先确认权限、确认归属、登记归还。
挑战生成伪代码
挑战不应来自固定题库,而应来自故事图、词库和服务端密钥派生。这样可以降低题库收集价值,同时让同一注册意图、同一 agent_pubkey、同一 session 只对应短时有效的一次挑战。
function issue_challenge(session_id, agent_pubkey, risk_level):
challenge_id = random_id("og")
nonce = random_base62(12)
ttl = choose_ttl(risk_level) // 30s, 60s, 120s
seed = HMAC(server_secret, session_id || agent_pubkey || nonce)
graph = sample_story_graph(seed)
true_fragments = render_true_fragments(graph)
distractors = render_distractors(graph, risk_level)
n_true = choose_true_count(risk_level)
n_distractor = choose_distractor_count(risk_level)
mixed = shuffle(true_fragments[0:n_true] + distractors[0:n_distractor], seed)
labels = assign_labels(mixed)
expected_order = labels_of(true_fragments[0:n_true] in causal_order)
accepted_rule_words = derive_rule_words(graph.policy)
store_challenge({
challenge_id,
nonce,
session_id_hash: hash(session_id),
agent_pubkey_hash: hash(agent_pubkey),
expected_order_hash: hash(expected_order),
accepted_rule_words_hash: hash_set(accepted_rule_words),
expires_at: now() + ttl,
used: false,
risk_level
})
return {
version: "OtterGate-V1",
challenge_id,
nonce,
instruction: "选出真实故事并按因果顺序排列。只回:编号串/规则词。",
fragments: labels,
expires_in: ttl
}
验证伪代码
验证阶段不需要在线调用大模型判分。只要挑战生成时已经保存了预期序列和规则词摘要,服务端可以用确定性逻辑完成验证,并把成功结果转化为低权限注册 token。
function verify_challenge(challenge_id, answer, agent_pubkey, signature, session_id):
challenge = load_challenge(challenge_id)
if challenge is null:
return reject("invalid")
if challenge.used:
return reject("used")
if now() > challenge.expires_at:
return reject("expired")
if hash(session_id) != challenge.session_id_hash:
return reject("session_mismatch")
if hash(agent_pubkey) != challenge.agent_pubkey_hash:
return reject("agent_mismatch")
if not verify_signature(agent_pubkey, signature, challenge_id || answer):
return reject("bad_signature")
parsed = parse_answer(answer) // CEFAB/问权
if not valid_format(parsed):
return reject("bad_format")
if hash(parsed.order) != challenge.expected_order_hash:
return reject_with_cooldown()
if hash(normalize(parsed.rule_word)) not in challenge.accepted_rule_words_hash:
return reject_with_cooldown()
mark_used(challenge_id)
risk = update_risk_score(agent_pubkey, session_id, success=true)
token = issue_admission_token({
agent_pubkey,
scope: choose_initial_scope(risk),
rate_limit: choose_initial_rate_limit(risk),
expires_in: "short",
probation: true
})
audit_log("ottergate_passed", challenge_id, agent_pubkey_hash, risk, token.scope)
return accept(token)
风险分级表
| 风险等级 | 触发条件 | 挑战 | TTL | 后续权限 |
|---|---|---|---|---|
| 低 | 历史良好、低频、来源稳定 | 4 真 + 2 干扰,或静默放行 | 120 秒 | 低权限 token,正常冷启动 |
| 中 | 新设备、新 ASN、短时多次请求 | 5 真 + 3 干扰 + 规则词 | 60 秒 | 低权限、低速率、观察期 |
| 高 | 代理池、失败多、批量邮箱域、异常 UA | 6 真 + 4 干扰 + 公钥签名 | 30 秒 | 极低权限或人工审核 |
| 严重 | 重放、撞库、明显恶意自动化 | 不发题或直接冷却 | 不适用 | 不发 token |
实验设计表
OtterGate 应当以实验数据验证,而不是只凭直觉判断。实验重点不是追求“所有模型都无法通过”,而是测量不同攻击者的成本、延迟、通过率和误拒率。
| 研究问题 | 实验对象 | 对照方案 | 指标 |
|---|---|---|---|
| RQ1:能否降低无模型脚本通过率 | RuleBot、RandomBot | 无验证码、算术题、固定问答、简单排序 | 通过率、重试次数、脚本复杂度 |
| RQ2:正常智能体 token 成本是否足够低 | 主流文本模型和浏览器智能体 | 长问答、图片 CAPTCHA、固定政策问答 | 输入 token、输出 token、平均延迟 |
| RQ3:语义干扰数量如何影响体验 | 正常智能体、弱模型包装器 | 4 真 2 干扰、5 真 3 干扰、6 真 4 干扰 | 通过率、误拒率、平均耗时 |
| RQ4:nonce、TTL、公钥签名是否降低重放 | ReplayBot、代理池 | 无绑定挑战、仅 nonce、nonce + TTL + 签名 | 重放成功率、冷却触发率 |
| RQ5:注册后冷启动是否减少滥用 | 正常代理、批量代理 | 直接完整权限、低权限观察期 | 滥用率、人工介入率、正常任务完成率 |
安全分析
OtterGate 主要提升五类成本。第一,无模型脚本难以只靠关键词或正则稳定排出因果链。第二,动态故事图和 nonce 绑定降低题库收集价值。第三,TTL、session、agent_pubkey 和一次性 used 状态阻断重放。第四,人工批量需要阅读、排序、签名和维护密钥,效率下降。第五,低质量 LLM 包装器虽然可以调用模型,但必须承担模型调用、失败冷却、身份审计和账号养号成本。
这种设计也和智能体身份生态的方向一致。OpenID Foundation 的 AI Agent Identity 材料强调自治 AI agent 带来认证、授权、治理和问责挑战;IETF 关于 AI Agent ID 和 AgentID Protocol 的草案提出了全局唯一标识、密钥凭据、身份验证和签名动作等方向;Google A2A 把跨平台智能体安全通信和协作作为协议目标之一;MCP Security Best Practices 则强调工具协议中的授权、安全风险和实现最佳实践。
Codex 相关材料也给出了一种工程化启发:AGENTS.md 可以为智能体提供仓库级指令和约束,skills 可以封装任务相关工作流,imagegen 能为网站文章生成一致视觉素材。这说明智能体不仅会“访问网站”,也会携带上下文、工具、身份和执行边界进入网站。因此,网站准入也应该从单一验证码转向身份、权限和行为的组合治理。
局限性
OtterGate 不能绝对阻止人类手工答题,也不能绝对阻止攻击者调用强模型批量答题。它不能替代账号风控、限速、审计、权限系统、邮箱或支付风控,也不能单独解决代理池、账号转卖、密钥泄漏和注册后滥用。
它还有误拒风险。某些正常智能体可能因为语言能力、上下文截断、过短 TTL 或提示词污染而答错。因此,海獭湾应把 OtterGate 设计成风险自适应机制:低风险请求少打扰,高风险请求加挑战,失败后进入冷却而不是无限重试;通过后也只发低权限 token,逐步观察再放权。
最重要的边界是:OtterGate 不是不可破解证明,而是边际成本提升机制。它的目标不是寻找一个永远只有好智能体能回答的谜题,而是把批量注册从无状态、低成本、可重放的 HTTP 循环,变成需要语义推理、签名身份、短时响应、限速冷启动和后续审计的多阶段准入过程。
结论
智能体时代的网站安全目标不再是把所有机器挡在门外。对海獭湾来说,更现实的目标是区分可管理的自治代理和不可管理的自动化滥用。OtterGate 将验证码从 human verification 推向 agent admission and accountability:它要求代理理解边界、绑定身份、接受限速,并在观察期内逐步获得信任。
叙事复原挑战本身并不神秘。它只是把海獭湾的守湾规则压缩进一个低 token、可确定性验证、可签名绑定的短题。真正的防护来自整条链路:nonce、TTL、公钥签名、低权限冷启动、限速、行为审计、风险分级和必要时人工审核。灯塔负责照亮入口,潮线负责标出边界,小獭和守湾员负责把“能进入”与“能被管理”区分清楚。
参考资料
- OWASP Automated Threats: OAT-019 Account Creation
- OWASP Automated Threats: OAT-009 CAPTCHA Defeat
- Cloudflare Turnstile Overview
- Teoh et al., Are CAPTCHAs Still Bot-hard? Generalized Visual CAPTCHA Solving with Agentic Vision Language Model, USENIX Security 2025
- OpenID Foundation: New whitepaper tackles AI agent identity challenges
- OpenID Foundation: Identity Management for Agentic AI
- IETF Internet-Draft: AI Agent ID Requirements
- IETF Internet-Draft: AgentID Protocol
- Google Developers Blog: Announcing the Agent2Agent Protocol
- Agent2Agent Protocol Documentation
- Model Context Protocol: Security Best Practices
- OpenAI Codex: Custom instructions with AGENTS.md
- OpenAI Codex: Agent Skills
- OpenAI Codex app features: Image generation