题记与说明
date: 2026-11-01
prefix: knowledge-qyxuo8eu-1
type: 主题精读(主题研究)
title: Web 安全防御基础:XSS、CSRF、SSRF、CSP、CORS、Cookie 安全(结合 Agent 工具服务)
reading_method: 网络可用,WebFetch 精读 7 个来源(OWASP Cheat Sheet ×3 + MDN ×3 + MCP 规范 ×1),超出 3-5 个的检索范围,原因是主题本身点名了六类防御技术 + Agent 工具服务锚点,需逐一对照一手规范。
0. 阅读路径与来源说明
本主题是"主题研究"类条目:没有单篇论文,核心来源是各防御技术的一手权威规范。本次检索并精读 7 个来源(全部在线抓取成功,2026-11-01):
| # | 来源 | 类型 | URL |
|---|---|---|---|
| 1 | OWASP Cross Site Scripting Prevention Cheat Sheet | 官方防 XSS 规范 | https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html |
| 2 | OWASP Cross-Site Request Forgery Prevention Cheat Sheet | 官方防 CSRF 规范 | https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html |
| 3 | OWASP Server Side Request Forgery Prevention Cheat Sheet | 官方防 SSRF 规范 | https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html |
| 4 | MDN: CORS(HTTP 访问控制) | 浏览器机制权威文档 | https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS |
| 5 | MDN: Content Security Policy (CSP) | 浏览器机制权威文档 | https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP |
| 6 | MDN: Set-Cookie | 浏览器机制权威文档 | https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie |
| 7 | MCP Security Best Practices(Model Context Protocol 规范) | Agent 工具协议安全规范 | https://modelcontextprotocol.io/specification/2025-11-25/basic/security_best_practices |
说明:请求的是 2025-06-18 版本 URL,服务端返回的是规范最新版(页面内交叉引用均为 2025-11-25 版),按实际返回版本引用。
提取方式:WebFetch 基于页面原文做引导式摘录,引述句为页面原文(OWASP 内容为 CC BY-SA 4.0 授权)。本笔记未对浏览器行为做实测,行为类结论以 MDN 文字为准。
1. 七维提取
1.1 核心问题
Web 安全防御的根本问题是:在"浏览器—服务端—内网"三方之间,信任边界靠什么显式证明,而不是靠隐式默认。四条信任边界对应四类经典漏洞:
- 内容信任(XSS):不可信数据被放进了 HTML/JS/CSS/URL 的执行上下文,浏览器把数据当代码执行。防御问题 = 如何让"数据永远是数据"。
- 请求信任(CSRF):浏览器发请求时自动附带 cookie,服务端"无法区分合法授权请求和伪造的已认证请求"。防御问题 = 如何显式证明"这个请求表达了用户的真实意愿"。
- 出网信任(SSRF):服务端替用户向任意 URL 发请求,攻击者借此打内网、云 metadata、localhost。防御问题 = 服务端出网如何收敛到白名单 + 网络层隔离。
- 跨域读写信任(CORS / Cookie / CSP):同源策略默认禁止跨源读取,CORS 是服务器的"放行声明"而非防火墙;cookie 是隐式凭证,其作用域与传输规则决定 CSRF/窃取风险;CSP 是内容注入失效后的最后闸门。
Agent 工具服务如何放大这些边界问题(本次精读的锚点):Agent 把上述三条边界全部"外化"了——
- 工具输出、抓取的网页、其他 MCP server 返回的内容,都要进入客户端 UI 渲染(XSS 面)和 LLM 上下文(提示注入面,与 XSS 同构:数据与指令不分层);
- Agent 工具要抓取的 URL、OAuth 元数据发现要请求的 URL,都是服务端/客户端进程的出网请求(SSRF 面);
- Agent 的授权走 OAuth + consent cookie,MCP 规范直接承认这是 CSRF 的变体(confused deputy),要求 consent 页做 CSRF 防护。
MCP 规范原文将 SSRF、会话劫持、token passthrough、本地 server 命令注入列为协议级攻击向量,等于官方承认:做 Agent 工具服务 = 做一个安全敏感的 Web 服务。
1.2 主要主张
按来源归纳的可执行主张:
XSS(OWASP Cheat Sheet)
- 唯一正确姿势是按输出上下文做输出编码:HTML 体用实体编码(
& < > " '),属性值加引号并属性编码,JS 字符串用"同时保护外层 script 上下文"的编码器(仅十六进制/Unicode 转义不充分),CSS 用严格结构校验 + hex 编码,URL 只对参数值做百分号编码。 - 存在编码也救不了的"危险上下文":
<script>内部、HTML 注释、<style>、标签/属性定义位、事件处理器值、eval()/setTimeout()/setInterval()——设计上就不该把不可信数据放进去。 - 必须渲染富文本时用净化(sanitization)而不是编码:"OWASP recommends DOMPurify for HTML Sanitization",且"You must regularly patch DOMPurify or other HTML Sanitization libraries"(绕过被持续发现,必须跟着打补丁)。
- 优先用文本安全 sink(
textContent、insertAdjacentText()、document.createTextNode())替代innerHTML;不可避免时elem.innerHTML = DOMPurify.sanitize(dangerVar)。React 的dangerouslySetInnerHTML是"逃逸舱口",不净化就用等于裸奔。 - CSP 定位是纵深防御而非主防线:"should not be your primary defense mechanism";企业统一盖一个 header 会逼出豁免,"allow cracks in your XSS armor"。
- WAF 明确不推荐用于防 XSS;HTTP 拦截器统一编码是反模式(无上下文、防不了 DOM XSS)。
CSRF(OWASP Cheat Sheet)
- 根因:
browser requests automatically include all cookies including session cookies,服务端失去"请求是否代表用户意愿"的判断依据。 - 主防线是 token:唯一(per session)、保密、不可预测;同步令牌模式服务端比对,不匹配即拒绝并记录;绝不能进 URL 或服务器日志(GET 会经 history/日志/Referer 泄露)。
- 双提交 cookie 的朴素版是 DISCOURAGED(子域 cookie 注入可绕过),签名 + 会话绑定的 HMAC 版才是 RECOMMENDED。
- SameSite 只是纵深防御:Lax 只挡不安全方法,若有会改状态的 GET 端点,"this is the single most common way SameSite-based defenses fail in practice";SameSite 作用域是注册域名而非 origin,兄弟子域(包括被接管的)都算 same-site。
- Origin/Referer 校验:完整匹配 origin(
example.org.attacker.com不得通过);缺失和Origin: null都不能当同源证据;反代场景优先服务端配置取目标 origin。 - XSS 击穿一切 CSRF 防线:原文大写强调 "Cross-Site Scripting (XSS) can defeat all CSRF mitigation techniques!"——所以防 XSS 是防 CSRF 的前置条件。
- 登录 CSRF 也真实存在(攻击者把受害者登进自己的账号);认证成功后必须销毁 pre-session 重新发 token,兼防 session fixation。
- 敏感操作用重认证/一次性 token,明确不要依赖 CAPTCHA;状态变更永远不用 GET。
SSRF(OWASP Cheat Sheet)
- "Deny-lists are bypass-prone. Prefer allow-lists." 黑名单是下策;不得已时至少要封:云 metadata(AWS/GCP/Azure 的
169.254.169.254、metadata.google.internal)、127.0.0.0/8、0.0.0.0/8、::1/128、RFC1918、IPv6 ULCfc00::/7、link-localfe80::/10、组播。 - "Do not accept complete URLs from the user":由校验过的 host + 应用固定的 scheme/port/path 组装请求;拒绝解析器分歧的 URL(
http://example.com\@evil.com在 WHATWG 与 RFC 3986 下解析出不同 host)。 - 重定向必须禁用自动跟随:"Disable the support for the following of the redirection in your web client",否则自动跳转直接绕过输入校验。
- 域名白名单防不了 DNS rebinding:"Domain allowlisting alone does not prevent DNS rebinding." 必须校验解析出的 IP,且确保 HTTP 客户端只连已校验地址——"A second, unchecked DNS lookup between validation and connection can bypass these checks."(TOCTOU:校验和连接之间再做一次未校验 DNS 解析就白干);重试/fallback 连接也要应用同样的策略。
- 云上 SSRF 的最高价值目标是 metadata 服务(偷 IAM 凭证/访问 token);纵深措施:启用 AWS IMDSv2、禁用 IMDSv1。
- 网络层:防火墙 + 网段隔离,让"被攻破的应用也无法对任意应用发起调用"。
CORS(MDN)
- 同源策略限制的是脚本发起的跨源读取(fetch/XHR),不是嵌入:
<img>/<script>标签嵌资源但读不到数据,不需要 CORS。 - 凭证请求铁律:带 cookie 的跨源请求,服务端不得用
*,必须显式 origin +Access-Control-Allow-Credentials: true,且 Allow-Headers/Methods/Expose-Headers 也禁通配;否则浏览器拦截响应。还应回Vary: Origin防缓存串扰。 - 预检由"非简单请求"触发(非 GET/HEAD/POST,或 Content-Type 不是 form-urlencoded/multipart/text-plain,或带自定义头——自定义 CSRF 头正是靠这一点强制预检);
Access-Control-Max-Age默认仅 5 秒,浏览器各有上限。 - 常见错误榜:凭证 +
*、反射 Origin 不带 Vary、多个 Allow-Origin 头、依赖预检后重定向(浏览器支持不全)。
CSP(MDN)
- CSP 是"网站给浏览器的指令序列",主要用于控制文档能加载哪些资源,"mainly used as a defense against cross-site scripting (XSS) attacks";必须用
Content-Security-Policy响应头在所有响应上交付(meta 标签功能不全)。 - 推荐姿势是 strict CSP:
script-src 'nonce-{RANDOM}'; object-src 'none'; base-uri 'none'。域名白名单 CSP "are hard to get right and often policies inadvertently whitelist unsafe domains",且会膨胀到难以维护(举例:仅集成 Google Analytics 就要加 187 个域名)。 'unsafe-inline'让 CSP 大半作废:"Developers should avoid 'unsafe-inline', because it defeats much of the purpose of having a CSP. Inline JavaScript is one of the most common XSS vectors."(含 nonce/hash 时浏览器会忽略 unsafe-inline)。strict-dynamic放行"带 nonce 的脚本动态加载的脚本",方便但降强度;frame-ancestors 'none'是 X-Frame-Options 的更强替代(防点击劫持);先上Content-Security-Policy-Report-Only观察。- 定位边界一句话:"Setting a CSP is not an alternative to sanitizing input. Websites should sanitize input and set a CSP, providing defense in depth against XSS."
- Trusted Types(
require-trusted-types-for 'script')让innerHTML等 DOM sink 拒绝裸字符串,被 OWASP 称为"eliminates entire classes of DOM XSS"的少数手段之一。
Cookie 安全(MDN Set-Cookie)
- 三大安全属性:
Secure(仅 https 发送,localhost 豁免)、HttpOnly("Forbids JavaScript from accessing the cookie, for example, through the Document.cookie property"、"This mitigates attacks against cross-site scripting (XSS)"——但只挡读不挡发:HttpOnly cookie 照样随 fetch/XHR 发出)、SameSite(Strict 仅同站;Lax 同站 + 跨站顶级导航的安全方法;None 需配 Secure)。 - Lax 是现代浏览器默认值,且默认 Lax 是宽松版:"cookies are also included in POST requests, as long as they were set no more than two minutes before the request was made"(Lax+POST 两分钟豁免——默认值比标准 Lax 弱,防 CSRF 不能赌浏览器默认)。
__Host-前缀是作用域最强组合:必须 Secure + Path=/ + 禁止 Domain 属性,保证 cookie 只回设置它的 host、全 host 生效且不能被子域覆写(这是对子域 cookie 注入的工程级封堵);不支持前缀的老浏览器不会拒绝违规 cookie。Domain会让 cookie 暴露给该域及所有子域,任何子域失陷即全失;Path不是安全措施;Max-Age优先于Expires。
Agent 工具服务(MCP 规范)
- Confused deputy(代理服务器静态 client_id + 动态注册 + consent cookie → 绕过用户同意拿授权码):修复 MUST 清单包括 consent 页本身要实现 CSRF 防护(state 参数/CSRF token)+ 防 iframe(frame-ancestors CSP 或 X-Frame-Options: DENY)、consent cookie 必须
__Host-前缀 +Secure+HttpOnly+SameSite=Lax且绑定具体 client_id、redirect_uri 精确字符串匹配、state 单次使用短过期(如 10 分钟)且必须在用户批准后才能种下。 - Token passthrough 是反模式:"MCP servers MUST NOT accept any tokens that were not explicitly issued for the MCP server."(受众不校验 → 绕过限流/审计、横向漂移)。
- MCP 客户端做 OAuth 元数据发现时抓取的 URL 全部是 SSRF 面(
resource_metadata、authorization_servers、token_endpoint…),攻击者可塞http://169.254.169.254/、http://localhost:6379/、DNS rebinding、重定向链。MUST/SHOULD:强制 HTTPS、封私网段、"Avoid implementing IP validation manually. Attackers exploit encoding tricks (octal, hex, IPv4-mapped IPv6) that custom parsers often miss."、重定向逐跳校验、出口代理(推荐 Stripe Smokescreen)、DNS pinning 对抗 TOCTOU。 - 会话安全:"MCP Servers MUST NOT use sessions for authentication"——会话 ID 必须安全随机、可绑定
<user_id>:<session_id>防劫持/事件注入(共享队列 + 可续传流是新的注入通道)。 - XSS→RCE 升级链:恶意 MCP server 给
javascript:授权 URL → 客户端 XSS → 偷代理 token → stdio 传输 spawn 任意命令 = RCE。MUST:只允许 http/https scheme、拒绝javascript:/data:/file:、绝不用 shell 开 URL;Web 客户端 SHOULD 上 CSP(script-src 'self')。 - 本地 MCP server:一键安装 MUST 先展示完整命令并取得同意;运行在沙箱/最小权限中;stdio 传输本身就是隔离手段。
1.3 方法(各防御的技术路线,横向对比)
| 防御对象 | 核心技术路线 | 关键机制 | 失效模式 |
|---|---|---|---|
| XSS | 按上下文输出编码 + 安全 sink + 净化库 + strict CSP + Trusted Types(多层) | 输出编码按语境;DOMPurify;nonce CSP | 危险上下文直接注入;净化库未更新;unsafe-inline CSP |
| CSRF | 主防线 token(同步令牌/带 HMAC 的双提交)+ 纵深 SameSite + Origin 校验 + Fetch Metadata | 请求必须显式携带"本源证明" | 会改状态的 GET;子域 cookie 注入;XSS 打穿一切 |
| SSRF | allowlist + 不收完整 URL + 禁自动重定向 + 连接时 IP 校验(DNS pinning)+ 出网防火墙/egress proxy | 服务端出网收敛 + 网络隔离 | DNS rebinding TOCTOU;解析器歧义 URL;重定向绕过 |
| CORS | 服务端按需精确放行 | ACAO + 凭证规则 + 预检 | 凭证 + *;反射 Origin 无 Vary |
| CSP | 声明式资源加载限制 | nonce/hash strict CSP;report-only 灰度 | unsafe-inline;白名单膨胀;不是净化替代品 |
| Cookie 安全 | 作用域最小化 + 传输限制 | HttpOnly/Secure/SameSite/__Host-/Domain 不放宽 | Lax+POST 2 分钟豁免;老浏览器不认前缀 |
| Agent 工具服务(MCP) | 把上述全部协议化(MUST/SHOULD 条款) | consent 页 CSRF 防护、consent cookie __Host- 组合、出网 SSRF 缓解、会话绑定用户、URL scheme 白名单、沙箱 | token passthrough;会话 ID 当凭证用;stdio 代理把 XSS 升级成 RCE |
方法论上的共同结构(这是本次精读提炼出的统一视角):
- 每条防御都在回答同一个问题:"凭什么信任这次内容/请求/连接?"——XSS 答案是"按语境证明它是数据",CSRF 答案是"请求显式携带本源证明",SSRF 答案是"目的地在白名单且解析到白名单 IP",CORS 答案是"服务端明确声明放行",CSP 答案是"资源来源被策略约束",Cookie 答案是"作用域和传输被属性最小化"。
- 黑名单系统性劣于白名单:SSRF("Deny-lists are bypass-prone")、CSP 域名白名单 vs nonce/hash、MCP URL scheme 校验("SHOULD use allowlist-based validation rather than blocklist-based approaches")三处独立证据收敛到同一原则。
- 纵深防御是常态而非选项:每个 cheat sheet 都给出 ≥2 层措施,MCP 规范用 MUST/SHOULD 把纵深写成了合规要求。
1.4 数据与证据
- 规范条款证据(一手):OWASP 三张 cheat sheet 的规则编号与 MUST/DISCOURAGED/RECOMMENDED 分级(双提交朴素版 DISCOURAGED、HMAC 版 RECOMMENDED;timestamp 过期是误解——CSRF token "is not an access token");MCP 规范大量 MUST 条款(引用见 1.2)。
- 浏览器行为证据(MDN):Lax+POST 两分钟豁免原文;
Access-Control-Max-Age默认 5 秒;凭证请求遇*时"the browser will block access to the response";__Host-违规 cookie 的具体拒绝示例(__Host-id=1; Secure; Path=/; Domain=example.com // rejected)。 - 量化数据点:strict CSP 论据——仅集成 Google Analytics 需向白名单加 187 个 Google 域名(MDN CSP);MCP state 建议过期 10 分钟;SSRF proof-of-legitimacy 模式要求随机 token 约 20 位字母数字。
- 攻击面证据:MCP 规范给出 SSRF 在 Agent 场景的完整载体清单(OAuth 元数据发现的 3 类 URL 来源 + 5 类攻击模式:内网 IP 直达、云 metadata、localhost 服务、DNS rebinding、重定向链);以及 XSS→stdio→RCE 的完整升级链时序图。
- 跨来源一致性:云 metadata
169.254.169.254同时出现在 OWASP SSRF 黑名单最低集与 MCP SSRF 缓解清单;__Host-前缀同时出现在 OWASP CSRF 纵深清单与 MCP consent cookie MUST 清单——两代规范互相印证。
1.5 结论
- 六件套防御的分工是清晰的:编码/净化管内容、token/Origin 管请求、allowlist/出网管控管连接、CORS 管跨源读取放行、CSP 管失效后的爆炉半径、cookie 属性管隐式凭证的作用域。它们不是可选项池,而是 cookie 认证 + 富内容 + 服务端出网的应用各自必答的题。
- 最反直觉的两条:CORS 不是防火墙而是放行声明(安全责任在服务端配置精度);CSP 不是 XSS 主防线而是纵深层(主防线永远是编码/净化)。
- 结合 Agent 工具服务的总结论:Agent 是 Web 攻击面的放大器而非新物种。MCP 规范把 SSRF、会话劫持、confused deputy(CSRF 变体)、OAuth URL XSS、本地命令执行全部写成协议条款,证明建设 Agent 工具服务所需的核心能力就是这套经典 Web 防御的等价物,外加两个新特征——(a) 工具输出进入 LLM 上下文形成"提示注入 = 上下文层 XSS"的同构问题;(b) stdio/沙箱让 XSS 类攻击可以升级到 RCE,纵深防御的层级被抬高了。
- 落到工程:做 Agent 工具服务时,最小防御集 = 输出渲染(DOMPurify + strict CSP + Trusted Types)+ 出网(URL 白名单 + egress proxy + DNS pinning + 封 metadata)+ 授权(consent CSRF 防护 +
__Host-cookie + state 单次)+ 会话(ID 绑用户、token 校受众)+ 沙箱(本地 server 最小权限)。
1.6 局限
来源自身承认的局限
- OWASP XSS sheet:CSP Level 2/3 特性的浏览器支持不能假设;净化库(DOMPurify 等)绕过被持续发现,需持续 patch;WAF/统一编码过滤器无效于 DOM XSS。
- OWASP CSRF sheet:SameSite 兼容性残余风险(老/嵌入式浏览器);Lax 下同站子域仍是盲区;token 方案在可用性上要妥协(per-request 破坏后退按钮)。
- OWASP SSRF sheet:黑名单注定绕过率高、只是下策;DNS 校验本身有盲 DNS 泄露/DNS pinning 攻击风险;Case 2(出网到任意外部目标)下白名单不可用,只能靠 proof-of-legitimacy 与网络层。
- MDN Set-Cookie:cookie 前缀在不支持的浏览器上"will always be accepted",保证失效。
- MCP 规范:SHOULD 多于 MUST 之处(如出口代理、沙箱技术选型)留给实现者,落地质量参差;规范版本演进快(本次返回的已是 2025-11-25 版),条款可能再变。
- MDN CORS:预检后跨源重定向浏览器支持不全——跨源跳转类流程(恰好是 OAuth 场景)要自己兜底。
本笔记的局限(我推断的)
- 提取经 WebFetch 的模型化摘要完成,引述以摘录为准,未逐句回读原始 HTML 做二次校验;未实测任何浏览器行为(如 Lax+POST 豁免、预检缓存)。
- 本主题覆盖六类技术,每张 cheat sheet 内还有大量框架级细节(各语言库、Fetch Metadata 部署灰度等)未展开,只保留了规范级主干。
- "Agent 工具服务"维度以 MCP 规范为主要证据,其他 Agent 工具形态(OpenAPI function calling、自建插件市场)的对应条款未另行取证。
1.7 对我的启发(对用户项目/研究/写作)
- 一套可复用的"信任边界"写作框架:四类漏洞其实是一族问题(隐式信任 vs 显式证明),这比"六种漏洞六张清单"更适合写博客/做分享——把 XSS/CSRF/SSRF/CSP/CORS/Cookie 讲成"同一原则的六个投影",比堆砌 checklist 有传播力。
- Agent 工具服务的安全评审清单(若用户正在建 MCP server / agent 平台,可直接对照):
- 任何抓 URL 的工具:scheme 白名单、私网段拒绝(用现成 IP 库)、禁自动重定向、DNS pinning、egress proxy,封
169.254.169.254; - 任何渲染工具输出的 UI:DOMPurify(并保持更新)+ nonce strict CSP + Trusted Types + report-only 灰度;
- 任何授权/consent 流:CSRF token + state 单次短过期 + consent cookie
__Host-/Secure/HttpOnly/SameSite=Lax+ redirect_uri 精确匹配 +frame-ancestors 'none'; - 会话:ID 用 CSPRNG、绑定 user_id、session 不当认证用;token 校 audience,绝不 passthrough;
- 本地执行:展示完整命令、沙箱、最小权限、stdio 优先。
- 任何抓 URL 的工具:scheme 白名单、私网段拒绝(用现成 IP 库)、禁自动重定向、DNS pinning、egress proxy,封
- "提示注入 ≈ 上下文层的 XSS"是连接两个知识域的桥:用户此前已有 Agent 安全综述笔记(2026-10-29-Agent安全综述),本次精读给了它一个经典 Web 对照系——编码(结构化分隔工具输出与指令)之于提示注入,正如输出编码之于 XSS;这个类比可用于把 Web 安全读者引入 Agent 安全话题,或反向。
- 三条反直觉点适合做技术短文:CORS 是放行声明不是防火墙;CSP 不是主防线;SameSite=Lax 默认还有 2 分钟 POST 豁免(默认比标准更弱)。都是"很多人答错"的冷知识,有传播价值。
- 实操提醒(Windows/本地开发):MCP 规范多处给 loopback(localhost/127.0.0.1/::1)留了 http 豁免——本地调试 agent 工具服务时最小化使用,生产一律 https;本地 MCP server 用 stdio 传输天然限制访问面,比裸 HTTP + 无鉴权安全得多。
2. 分来源精读笔记(引述与要点)
2.1 OWASP XSS Prevention Cheat Sheet
- 输出编码五上下文规则(规则 #1–#5):HTML 体实体编码(
& → &等);属性值引号包裹 + 属性编码(属性名固定,无需编码空格);JS 只进带引号字符串且"using an encoder that also protects the enclosing HTML script context. Do not rely on quote escaping alone";CSS 严格结构校验 + hex 编码(\41或\000041);URL 只编码参数值。 - 不可信 URL 进
href/src:"Allow-list http and HTTPS URLs only." - 危险上下文(编码也无效):
<script>内、HTML 注释、<style>、标签/属性定义位、事件处理器值、eval()/setTimeout()/setInterval()。 - 净化:
DOMPurify.sanitize(dirty);净化后不得再修改("void your security efforts");必须持续更新净化库。 - 安全 sink 白名单:
textContent、insertAdjacentText()、className、setAttribute(safeName, value)、document.createTextNode();document.createElement()不是文本 sink(参数是标签名)。 - CSP:"Used as a defense-in-depth technique",需按应用定制;Trusted Types 是"eliminates entire classes of DOM XSS"级别的控制;WAF 不推荐。
- JSON:"For JSON, verify that the Content-Type header is application/json and not text/html to prevent XSS."
2.2 OWASP CSRF Prevention Cheat Sheet
- 定义:"when a malicious web site, email, blog, instant message, or program tricks an authenticated user's web browser into performing an unwanted action on a trusted site.";根因是浏览器自动带全部 cookie,服务端"cannot distinguish between legitimate authorized requests and forged authenticated requests"。
- token 三性:Unique per user session / Secret / Unpredictable;同步令牌模式服务端比对、不匹配拒绝并记日志;token 不进 URL/日志;"must not be leaked in the server logs or in the URL"。
- 双提交:朴素版 DISCOURAGED(子域 cookie 注入可绕),HMAC 会话绑定版 RECOMMENDED;不能只依赖 cookie 值本身,必须经 header/表单显式提交。
- SameSite 三值语义 + 局限:Lax 挡不住改状态的 GET(最常见失败方式);same-site ≠ same-origin(注册域名级);对 client-side CSRF 无效(攻击者操纵 URL 片段/
window.name/postMessage 骗你自己的 JS 发请求,token 和 SameSite 都会被应用自己带上)。 - Origin/Referer:属 forbidden headers,脚本改不了;两步校验、完整匹配;缺失/
null不算同源证据;X-Forwarded-Host只信可信代理。 - "Cross-Site Scripting (XSS) can defeat all CSRF mitigation techniques!" —— XSS 必须先防,但 token 仍是 cookie 认证应用的必需品。
- 纵深:Fetch Metadata(
Sec-Fetch-Site)+ Origin 兜底、HSTS、禁 API 接受简单 content-type、__Host-前缀、敏感操作重认证、不依赖 CAPTCHA、状态变更不用 GET、至少再加一层纵深措施。
2.3 OWASP SSRF Prevention Cheat Sheet
- 定义:"abuses an application to interact with the internal/external network or the machine itself";典型场景:用户头像 URL 抓取、"Custom WebHook (users have to specify Webhook handlers or Callback URLs)"、内部服务间转发用户数据;不限 HTTP(
file:///gopher:///dict://等,XXE 也能做 SSRF)。 - "Deny-lists are bypass-prone. Prefer allow-lists.";黑名单最低集:三大云 metadata、localhost 全段、RFC1918、IPv6 ULC/link-local、组播。
- "Do not accept complete URLs from the user";拒绝解析器分歧 URL(
http://example.com\@evil.com)。 - 重定向:"Disable the support for the following of the redirection in your web client"。
- DNS rebinding:"Domain allowlisting alone does not prevent DNS rebinding.";连接时 IP 校验 + 客户端只连已校验 IP(保 Host/SNI/证书验证);"A second, unchecked DNS lookup between validation and connection can bypass these checks.";重试与 fallback 也走同一策略。
- 云 metadata:SSRF 常用于"access and steal credentials and access tokens from metadata services";启用 IMDSv2、禁 IMDSv1。
2.4 MDN:CORS
- "Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources."
- 同源策略管脚本读取:
fetch()/XHR 默认只能同源;嵌入但读不到数据的场景不需要 CORS。 - 简单请求条件(GET/HEAD/POST + safelisted 头 + 三种 content-type);其余触发 OPTIONS 预检(ACRM/ACRH/ACMA)。
- 凭证铁律:"The server must not specify the * wildcard for the Access-Control-Allow-Origin response-header value";凭证响应的 Allow-Origin/Headers/Methods/Expose-Headers 全部禁通配;
*下的 Set-Cookie 也不会被设置;应带Vary: Origin。 - 预检缓存:
Access-Control-Max-Age默认 5 秒、浏览器有各自上限;预检请求永不携带凭证。
2.5 MDN:Content Security Policy
- "A CSP should be delivered to the browser in the
Content-Security-Policyresponse header. It should be set on all responses to all requests." default-src是未列明指令的回退;frame-ancestors 'none'替代 X-Frame-Options 防点击劫持。- 推荐组合:
script-src 'nonce-{RANDOM}'; object-src 'none'; base-uri 'none';nonce 每响应随机不可预测(服务器因此不能出静态 HTML);hash 方案静态可部署但外链脚本需 SRI。 - 白名单 CSP 之痛:难写对、易把不安全域名误入白名单、难维护(Google Analytics 需 187 个域名)。
- "Developers should avoid 'unsafe-inline', because it defeats much of the purpose of having a CSP. Inline JavaScript is one of the most common XSS vectors.";含 nonce/hash 时浏览器忽略 unsafe-inline;
unsafe-eval重开eval()/Function()/字符串版定时器。 - "Setting a CSP is not an alternative to sanitizing input. Websites should sanitize input and set a CSP, providing defense in depth against XSS."
- Report-Only 模式先行(meta 不可用 report-only;推荐 Reporting API 的
report-to,report-uri已弃用但需双声明至全浏览器支持)。
2.6 MDN:Set-Cookie
Secure:仅 https 发送(localhost 豁免);不防 JS/磁盘读——"Cookies with this attribute can still be read/modified either with access to the client's hard disk or from JavaScript if the HttpOnly cookie attribute is not set."HttpOnly:"Forbids JavaScript from accessing the cookie";"This mitigates attacks against cross-site scripting (XSS).";但 JS 发起的请求仍会带上该 cookie(只挡读不挡发)。SameSite:Strict 仅同站;Lax = 同站 + 跨站顶级导航的安全方法(排除 POST/PUT/DELETE、fetch、子资源、iframe);None 必须 Secure。- 默认 Lax 是宽松版:Lax+POST 豁免——"cookies are also included in POST requests, as long as they were set no more than two minutes before the request was made."
- 前缀:
__Secure-需 Secure+HTTPS;__Host-需 Secure + Path=/ + 无 Domain(拒绝示例见 1.4);老浏览器不认前缀、违规照收。 - 作用域:Domain 放宽到全部子域(任一子域失陷即失);Path 非安全措施;Max-Age 优先于 Expires;0/负数立即过期。
2.7 MCP Security Best Practices(Agent 工具服务锚点)
- 六大攻击向量,每个带时序图与 MUST/SHOULD 缓解清单:Confused Deputy、Token Passthrough、SSRF、Session Hijacking、Local MCP Server Compromise、OAuth Authorization URL Validation(另含 stdio 代理升级链、scope minimization)。
- Confused deputy 本质 = consent cookie 的"隐式同意"被重放(与 CSRF 根因同构:cookie 隐式信任);缓解 MUST:per-client consent 注册表、consent 页 CSRF 防护 + 防 iframe、consent cookie
__Host-+Secure+HttpOnly+SameSite=Lax+签名+绑定 client_id、redirect_uri 精确匹配、state 服务端存储/单次/短过期/批准后才种。 - Token passthrough:"MCP servers MUST NOT accept any tokens that were not explicitly issued for the MCP server."(受众分离、审计归因、信任边界)。
- SSRF:MCP 客户端抓的 OAuth 元数据 URL 全是攻击面;SHOULD:强制 https(loopback 豁免)、封私网段(RFC 9728 §7.7)、逐跳校验重定向、egress proxy(Smokescreen)、DNS pinning 对 TOCTOU;明令 "Avoid implementing IP validation manually"。
- 会话:"MCP servers MUST NOT use sessions for authentication";ID 用 CSPRNG、可轮换、绑定
<user_id>:<session_id>(ID 来自用户 token 而非客户端提供)。 - 本地 server:一键配置 MUST 展示完整命令(不截断)+ 明示危险 + 显式同意;SHOULD 沙箱/最小权限/危险模式告警;server 侧 stdio 传输或带鉴权的受限 IPC。
- OAuth URL:"MUST only allow
http://andhttps://schemes"(生产必须 https);"MUST rejectjavascript:,data:,file:,vbscript:";"MUST NOT use shell commands to open URLs";Web 客户端 SHOULD 上 CSP。
3. 经典 Web 防御 ↔ Agent 工具服务映射表
| 经典 Web 攻击/机制 | Agent 工具服务中的对应面 | 证据(MCP 规范条款) |
|---|---|---|
| XSS(存储/反射/DOM) | 客户端渲染工具输出与抓取网页;恶意 server 下发的 javascript: 授权 URL | OAuth URL MUST scheme 白名单;Web 客户端 SHOULD script-src 'self' |
| XSS → RCE 升级 | XSS 偷代理 token → stdio 传输 spawn 命令 → 完全控制 | stdio 代理缓解:沙箱 + 日志 + 附加鉴权 |
| CSRF(cookie 隐式信任) | OAuth consent cookie 被重放跳过用户同意(confused deputy) | consent 页 MUST CSRF 防护;consent cookie MUST __Host- 组合 |
| 会话固定/劫持 | 共享队列 + 可续传流下,session ID 被猜中后注入事件或冒充 | MUST NOT 用会话做认证;ID 绑 <user_id>:<session_id> |
| SSRF(webhook/抓取) | 客户端抓取 server 提供的 OAuth 元数据 URL;任何"抓网页"工具 | MUST 按 RFC 9728 封私网段;SHOULD egress proxy + DNS pinning |
| 令牌窃用/越权 | token passthrough(受众不校验)绕限流/审计、横向漂移 | MUST NOT 接受非本 server 签发的 token |
| 最小权限 | scope 全量预授 → 大爆炸半径 | scope minimization:起步最小集 + 按需 WWW-Authenticate 升级 |
| Cookie 作用域工程 | consent cookie 的作用域与防覆写 | __Host- 前缀(与 OWASP CSRF 纵深清单互相印证) |
同构洞察:工具输出进入 LLM 上下文 ≈ 不可信数据进入 HTML 上下文。提示注入与 XSS 的共同病理是数据与指令共用一个解释通道;Web 侧的解法(输出编码 = 通道隔离、CSP = 失效兜底)提示 Agent 侧的对应物是结构化分隔工具输出与系统指令 + 运行时权限兜底(工具白名单、人审高危操作)。
4. 来源清单(原始链接)
- OWASP XSS Prevention Cheat Sheet — https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html
- OWASP CSRF Prevention Cheat Sheet — https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html
- OWASP SSRF Prevention Cheat Sheet — https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html
- MDN CORS — https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
- MDN CSP — https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
- MDN Set-Cookie — https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
- MCP Security Best Practices — https://modelcontextprotocol.io/specification/2025-11-25/basic/security_best_practices
- (规范内引用)OWASP Top 10 A10:2021 SSRF — https://owasp.org/Top10/2021/A10_2021-Server_Side_Request_Forgery_%28SSRF%29/
- (规范内引用)RFC 9728 §7.7 / OAuth 2.1 / RFC 9700 — https://datatracker.ietf.org/doc/html/rfc9728 、https://datatracker.ietf.org/doc/html/rfc9700
- (规范内引用)Stripe Smokescreen egress proxy — https://github.com/stripe/smokescreen