关于 security-trust
用于修复 IsAgentReady.com「Security & Trust」检查项的技能,面向维护网站的人员。它涵盖安全响应头、API CORS、WebMCP 工具定义、表单行为和 OAuth 元数据,并提供验证命令。
主要功能
- 01修复 HTTPS 和安全响应头
- 02配置 API CORS 策略
- 03检查 WebMCP 工具定义
- 04审查表单自动提交风险
- 05发布 OAuth 元数据与认证说明
- 06提供只读验证命令
适用场景
- 01处理 Security & Trust 扫描失败项
- 02为 Web 服务器补充响应头
- 03按来源限制 API 访问
- 04为 Agent 准备网站认证
MCP 相关
涉及 WebMCP 工具定义和 Agent 认证就绪度的安全检查;它是修复技能,不是 MCP 服务。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ bartwaardenburg/ isagentready-skills --skill security-trust安装后在 Claude Code 中输入/security-trust确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/checkpoints.mdgotchas.mdsecurity-headers.mdserver-configs.md详细介绍
安全与信任
修复 IsAgentReady.com 的“安全与信任”类别。这些检查点会测试 Agent 协议所需的安全基线,以及 Agent 用于登录的身份验证元数据。
- 方法论版本:
2026-10-22。方法论:https://isagentready.com/en/methodology - 评分(权重和分数):https://isagentready.com/api/v2/methodology/2026-10-22/scoring
- 完整检查点数据(阶段、证据类型、验证命令、重新扫描命令):references/checkpoints.md
适用场景
- 扫描结果显示“安全与信任”类别存在失败项(旧版 ID 为 5.x)。
- 缺少 HTTPS、HSTS、CSP 或其他安全标头。
- 公共 API 需要正确的 CORS 策略。
- WebMCP 工具定义包含机密信息,或会自动提交存在风险的表单。
- 网站设有登录功能,且 Agent 必须能够找到 OAuth 元数据。
不适用场景
- robots.txt 或爬虫访问:使用
ai-content-discovery。 - JSON-LD:使用
structured-data。 - 语义化 HTML:使用
content-semantics。 - MCP、A2A 或 OpenAPI 文档:使用
agent-protocols。
说明
- 从扫描结果中获取失败的检查点。每项结果都有一个旧版 ID(
5.3)和一个稳定 ID(ia.hsts)。 - 对于标头检查点(5.1 至 5.9),使用 references/server-configs.md 中的一种服务器配置。该配置会一次性修复所有标头。
- 对于其他检查点,跳转到与稳定 ID 相同的锚点对应的修复工作流。
- 将
example.com替换为网站的域名。运行验证命令。所有验证命令均为只读操作。 - 使用
isagentready results <domain> --checkpoint <stable-id>重新扫描,或前往 isagentready.com。
如果提供了 $ARGUMENTS,请将其用作要修复的网址或检查点。
检查点
强度代表 agentready.org 规范级别(MUST、SHOULD、MAY)。强度不会改变评分。
| 旧版 | 稳定 ID | 名称 | AR ID | 强度 |
|---|---|---|---|---|
| 5.1 | ia.https | HTTPS | 无 | MUST |
| 5.3 | ia.hsts | HSTS | 无 | MUST |
| 5.4 | ia.csp | Content-Security-Policy | 无 | MUST |
| 5.5 | ia.x-content-type-options | X-Content-Type-Options | 无 | MUST |
| 5.6 | ia.frame-protection | X-Frame-Options / frame-ancestors | 无 | MUST |
| 5.7 | ia.cors | CORS | 无 | MAY |
| 5.9 | ia.referrer-policy | Referrer-Policy | 无 | MUST |
| 5.10 | ia.tool-definition-security | 工具定义安全性 | 无 | MAY |
| 5.11 | ia.auto-submit-risk | 自动提交风险 | 无 | MAY |
| 5.12 | ia.oauth-discovery | OAuth 发现 | AR-ACT-01 | SHOULD |
| 5.13 | ia.oauth-protected-resource | OAuth 受保护资源 | AR-ACT-01 | SHOULD |
| 5.14 | ia.agent-auth-readiness | Agent 身份验证就绪状态 | AR-ACT-01 | SHOULD |
一次性配置所有标头
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; frame-ancestors 'none'" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
使用 always,这样 Nginx 也会在 3xx、4xx 和 5xx 响应中发送这些标头。Apache、Caddy、Vercel、Netlify、Cloudflare、Express、Next.js 和 Django 的配置见 references/server-configs.md。
验证所有标头:curl -sfI https://example.com/ | grep -iE '^(strict-transport|content-security|x-content-type|x-frame|referrer-policy)'
修复工作流
5.1 HTTPS
重定向后的最终 URL 使用 https:// 且证书有效时,即通过检查。
- 获取证书。使用 Let's Encrypt 和 Nginx 时:
sudo certbot --nginx -d example.com -d www.example.com。 - 将 HTTP 重定向到 HTTPS:
server { listen 80; server_name example.com; return 301 https://$host$request_uri; }
验证:curl -sfI https://example.com/ | head -1
5.3 HSTS
当 Strict-Transport-Security 的 max-age 为 31536000 或更高时通过。设置 includeSubDomains 更佳。较短的 max-age 可获得部分分数。
- 添加标头:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; - 所有子域名都使用 HTTPS 时,添加
preload并在 hstspreload.org 提交域名。
验证:curl -sfI https://example.com/ | grep -i '^strict-transport-security'
5.4 Content-Security-Policy
当 CSP 包含有效指令时通过。仅包含 upgrade-insecure-requests 的 CSP 可获得部分分数。
- 先启用仅报告模式,以查明网站所需的来源:
add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' https://www.googletagmanager.com; report-uri /csp-report" always; - 报告没有问题后,改为
Content-Security-Policy。有关 nonce,请参阅 references/security-headers.md。
验证:curl -sfI https://example.com/ | grep -i '^content-security-policy'
5.5 X-Content-Type-Options
当值恰好为 nosniff 时通过。
- 添加标头:
add_header X-Content-Type-Options "nosniff" always;
验证:curl -sfI https://example.com/ | grep -i '^x-content-type-options: nosniff'
5.6 X-Frame-Options / frame-ancestors
当 X-Frame-Options 为 DENY 或 SAMEORIGIN,或 CSP 包含 frame-ancestors 时通过。
- 在 CSP 中添加
frame-ancestors 'none',或添加add_header X-Frame-Options "DENY" always;。 - 必须允许受信任的网站嵌入页面时,使用
frame-ancestors 'self' https://partner.example。不要使用ALLOW-FROM。
验证:curl -sfI https://example.com/ | grep -iE '^x-frame-options|frame-ancestors'
5.7 CORS
适用于 4.19 验证的公共 API 操作。当预检请求和 GET 返回相同的 Access-Control-Allow-* 标头、不在携带凭据时使用通配符,并且动态来源配置了 Vary: Origin 时通过。
- 预检请求和 GET 使用相同的策略进行响应:
const allowed = new Set(["https://app.example.com", "https://agent.example"]); app.use("/api", (req, res, next) => { const origin = req.get("Origin"); if (allowed.has(origin)) res.set({ "Access-Control-Allow-Origin": origin, Vary: "Origin" }); res.set({ "Access-Control-Allow-Methods": "GET", "Access-Control-Allow-Headers": "Accept" }); return req.method === "OPTIONS" ? res.sendStatus(204) : next(); }); - 对于不使用 Cookie 的公共 API,
Access-Control-Allow-Origin: *是正确的。绝不要将*与Access-Control-Allow-Credentials: true组合使用。
验证:curl -sI -H 'Origin: https://agent.example' https://example.com/api | grep -iE '^(access-control-|vary)'
5.9 Referrer-Policy
当存在 Referrer-Policy 且其值不是 unsafe-url 时通过。
- 添加标头:
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
验证:curl -sfI https://example.com/ | grep -i '^referrer-policy'
5.10 工具定义安全性
当页面包含 WebMCP 工具定义时适用。当定义中不含机密信息(JWT、API 密钥、令牌、银行卡号、密码)、名称与描述匹配,且只读工具包含 readOnlyHint 时通过。
- 从
toolname、tooldescription和registerTool()代码中移除每个令牌或密钥。在服务器上加载机密信息。 - 标记不会更改数据的工具:
document.modelContext?.registerTool({ name: "search_products", description: "Search the product catalog by keyword", annotations: { readOnlyHint: true }, inputSchema: { type: "object", properties: { query: { type: "string" } }, required: ["query"] }, execute: async ({ query }) => searchProducts(query), });
验证:curl -sf https://example.com/ | grep -ciE 'tool(name|description)="[^"]*(token|password|secret|api[_-]?key)'(预期为 0)
5.11 自动提交风险
当页面包含表单时适用。当没有表单使用 toolautosubmit,或仅搜索和筛选表单使用该属性时通过。高风险操作可获得部分分数。包含自动提交的密码或银行卡号输入框则不通过。
- 从登录、付款、删除和发送表单中移除
toolautosubmit。搜索表单可以保留:<form action="/search" toolname="search_products" tooldescription="Search the catalog" toolautosubmit> <input name="q" toolparamdescription="Search keywords"> </form>
验证:curl -sf https://example.com/ | grep -oE '<form[^>]*toolautosubmit[^>]*>'(预期仅包含搜索或筛选表单)
5.12 OAuth 发现
适用于网站存在身份验证信号的情况。如果 /.well-known/oauth-authorization-server 或 /.well-known/openid-configuration 包含 issuer、authorization_endpoint 和 token_endpoint,则通过。
- 发布元数据(RFC 8414):
{ "issuer": "https://example.com", "authorization_endpoint": "https://example.com/oauth/authorize", "token_endpoint": "https://example.com/oauth/token", "code_challenge_methods_supported": ["S256"], "scopes_supported": ["read", "write"] }
验证:curl -sf https://example.com/.well-known/oauth-authorization-server | jq -e '.issuer and .authorization_endpoint and .token_endpoint'
5.13 OAuth 受保护资源
适用于网站存在身份验证信号的情况。如果 /.well-known/oauth-protected-resource 包含 resource 和 authorization_servers,或主页发送了 WWW-Authenticate,则通过。
- 发布元数据(RFC 9728):
{ "resource": "https://example.com/api", "authorization_servers": ["https://example.com"], "scopes_supported": ["read"] } - API 返回 401 时,发送
WWW-Authenticate: Bearer resource_metadata="https://example.com/.well-known/oauth-protected-resource"。
验证:curl -sf https://example.com/.well-known/oauth-protected-resource | jq -e '.resource and (.authorization_servers | length > 0)'
5.14 Agent 身份验证就绪情况
适用于网站存在身份验证入口的情况。此检查会综合考量 PKCE S256、作用域元数据、受保护资源元数据或 WWW-Authenticate 标头、有效的 /auth.md,以及适用于 Agent 的授权授予方式。
- 在 5.12 中的元数据里添加
"code_challenge_methods_supported": ["S256"]和scopes_supported。 - 发布 5.13。
- 编写
/auth.md:# Authentication - Flow: OAuth 2.1 authorization code with PKCE (S256) - Agents: use the device code grant or a user-approved token. Do not ask for passwords. - Scopes: read (default), write (needs user approval)
验证:curl -sf https://example.com/.well-known/oauth-authorization-server | jq -e '.code_challenge_methods_supported | index("S256")'
关键注意事项
- HSTS
max-age=86400(一天)只能获得部分分数。请设置为一年。 - 仅包含
upgrade-insecure-requests的 CSP 只能获得部分分数。 - Nginx 的
add_header未使用always时,不会应用于错误响应。 Access-Control-Allow-Origin: *与凭据同时使用无效且不安全。- 不同域名上的 OAuth 元数据不计入此网站。
正确和错误示例请参阅 references/gotchas.md。
参考资料
- references/checkpoints.md:每个检查点的生成数据
- references/security-headers.md:各标头、其取值及作用
- references/server-configs.md:Nginx、Apache、Caddy、Vercel、Netlify、Cloudflare、Express、Next.js 和 Django 的配置
- references/gotchas.md:常见错误及正确和错误示例