mcpField
O
oauth-auditor

oauth-auditor

本地服务
github.com/GuardBee安全11 天前更新

关于 oauth-auditor

oauth-auditor 是面向开发者的 MCP 服务,用于审查 MCP 服务中的 OAuth 授权代码。它检测指定的 OAuth 2.1 反模式,并可为 CI/CD 输出 SARIF 结果。

主要功能

  1. 01扫描六类 OAuth 反模式
  2. 02检查源文件和目录
  3. 03输出 SARIF 2.1.0 结果
  4. 04支持 guardbee.yml 配置

适用场景

  1. 01发布前审查 MCP 服务授权代码
  2. 02在 CI/CD 中加入 OAuth 检查
  3. 03检查代码片段或文件中的授权风险

MCP 相关

提供扫描文本、文件和目录以及列出支持模式的 MCP 工具。另有用于扫描代码和探测运行中端点的命令行工具。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"4hmetuyar-oauth-auditor": {
"command": "npx",
"args": [
"-y",
"@guardbee/mcp-oauth-auditor"
]
}
}
}
启动命令npx -y @guardbee/mcp-oauth-auditor

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@guardbee/mcp-oauth-auditor0.1.2

工具

4

收录的工具列表 · 更新于 2 周前

参数类型必填说明
labelstring否在发现结果中显示的可选标签(例如文件名)
contentstring是要扫描的代码内容

详细介绍

@guardbee/mcp-oauth-auditor

🇬🇧 English | 🇹🇷 Türkçe | 🇨🇳 中文 | 🇯🇵 日本語 | 🇰🇷 한국어 | 🇧🇷 Português | 🇪🇸 Español | 🇩🇪 Deutsch

npm version npm downloads License: MIT

一个 MCP(Model Context Protocol)服务,用于扫描 MCP 服务自身的授权代码,检查其中是否存在 MCP 规范「安全注意事项」章节列出的 OAuth 2.1 反模式。

MCP 规范并未对此含糊其辞——它明确指出,令牌直通(不交换令牌或重新限定其作用域,而是将客户端的令牌原样转发给下游 API)和缺少受众验证(接受 aud 声明并非为此服务签发的令牌),是作为 OAuth 资源服务器的服务最主要的授权失效模式。此程序包会检查这两种模式,以及同一类别中的另外三种相关反模式。

默认情况下,遥测功能处于关闭状态。设置 GUARDBEE_TELEMETRY=1 后,它会发送服务、工具、成功状态、持续时间以及简短的参数值(例如文件路径);较长的字符串以及 content、token 或 password 等字段会替换为占位符。请参阅 @guardbee/mcp-telemetry。

Claude ──► oauth-auditor ──► Your MCP server's auth code
              │
              ├─ token-passthrough    (client's token forwarded unchanged downstream)
              ├─ token-validation     (jwt.verify() with no audience check)
              ├─ discovery-ssrf       (OAuth/OIDC discovery URL built from client input)
              ├─ pkce                 (authorization request missing code_challenge)
              ├─ redirect-validation  (redirect_uri checked with startsWith/includes, not exact match)
              └─ secrets-exposure     (hardcoded client_secret)

为什么特别关注这两种模式

令牌直通之所以重要,是因为客户端提交给此服务的令牌,其作用域和受众都是此服务,而不是服务自身的工具处理程序接下来调用的任何下游 API。原样转发令牌,就意味着下游服务在信任一个自己从未签发过的凭据,而这一决定是由服务端作出的,原始令牌签发方并未批准。

缺少受众验证是从另一个方向出现的同类失效:jwt.verify(token, key) 能确认令牌的签名有效,却无法说明令牌是为谁签发的。如果没有显式的 audience 检查,那么为完全无关的资源服务器签发的令牌——只要它恰好与当前服务共用同一个签发方或签名密钥——在此处也会成功通过验证。这正是 MCP 规范警告的典型「困惑的代理」替代攻击。

另外三种模式也与这一主题紧密相关,都是具体实例:使用客户端提供的输入构造 OAuth/OIDC 发现 URL(这正是某个已披露 CVE 背后的攻击模式);通过前缀或子字符串检查而非精确匹配来验证 redirect_uri(可绕过开放重定向防护);以及在授权请求中悄然遗漏 PKCE(OAuth 2.1 无条件要求 PKCE,而不仅仅是针对公共客户端)。


功能

  • 6 个类别:token-passthrough、token-validation、discovery-ssrf、pkce、redirect-validation、secrets-exposure
  • 其中两项检查(缺少 audience 验证、缺少 PKCE)会在调用点附近查找缺失项,而不是匹配固定正则表达式——它们会提取完整的 jwt.verify(...) 调用(或授权请求 URL 的构造过程),并确认附近确实没有 audience: / code_challenge,而不只是恰好匹配到字符串中的某个位置
  • 输出 SARIF 2.1.0——支持 CI/CD 集成(GitHub Code Scanning 等)
  • 支持通过 guardbee.yml 使用配置文件
  • 18 项单元测试——每种模式都包含一个正向场景和一个负向(误报)场景,另有一个完全正确的 OAuth 流程,其结果为零项发现。开发过程中发现并修复了一个实际的正则表达式错误(] 字符后跟了一个无法匹配的 \b,因为 ] 不是单词字符——导致方括号表示法的请求头访问形式被悄然漏检)。已针对包含全部 6 种故意植入的反模式的测试样例完成端到端验证(全部 6 种均被检出),并针对整个 guardbee-mcp 单体仓库完成验证(401 个文件——任何真实第三方代码中均无发现;唯一非测试匹配项来自扫描器自身的模式定义源码:其中一处在正则表达式字面量中以文本形式包含字符串 jwt.verify(,另一处在文档注释中包含该字符串,并非实际的易受攻击用法)

快速开始

Claude Desktop / MCP 客户端
{
  "mcpServers": {
    "guardbee-oauth-auditor": {
      "command": "npx",
      "args": ["-y", "@guardbee/mcp-oauth-auditor"]
    }
  }
}
CLI(CI/CD)
npx @guardbee/mcp-oauth-auditor scan ./src --fail-on=high --format=sarif > results.sarif

MCP 工具

工具描述
scan_text扫描代码片段
scan_file扫描单个文件
scan_directory递归扫描目录
list_patterns按类别列出所有受支持的模式

检测到的模式

类别模式严重性OWASP
token-passthroughtoken_passthrough_to_downstreamcriticalMCP07
token-validationmissing_audience_validationhighMCP07
discovery-ssrfoauth_discovery_ssrfcriticalMCP07
pkcemissing_pkce_on_auth_requesthighMCP07
redirect-validationloose_redirect_uri_validationhighMCP07
secrets-exposurehardcoded_oauth_client_secrethighMCP07
state-handlepredictable_state_handle(+ Python)——使用 Math.random、Date.now 或计数器生成的 state / session 句柄highMCP07
state-handlestate_handle_not_bound_to_user——从工具参数获取句柄并进行查找,却未检查该句柄是否属于调用者mediumMCP07
mix-upmissing_iss_validation——兑换授权码时未检查 iss(RFC 9207)mediumMCP07
auth-urlauth_url_scheme_not_validated——打开服务端提供的 URL 时未检查 scheme(javascript:、data:、file:)highMCP07
auth-urlauth_url_opened_via_shell——通过 shell 将 URL 插入 open / xdg-open / start 命令criticalMCP05
local-exposurelocal_http_server_unauthenticated——HTTP MCP 传输未进行身份验证highMCP07
local-exposuremissing_host_origin_check——未验证 Host / Origin(DNS 重绑定)mediumMCP07
local-exposurelisten_all_interfaces——MCP 服务绑定到 0.0.0.0mediumMCP07
Python 和 Go

语言类型根据文件扩展名确定,Python 和 Go 专属规则仅适用于对应语言的文件。

  • Python(FastAPI / Starlette / Flask、PyJWT、python-jose、authlib):python_missing_audience_validation(jwt.decode 未设置 audience=,且 authlib 未设置 claims_options 中的 aud)、python_audience_verification_disabled("verify_aud": False)、python_token_passthrough_to_downstream(在 requests / httpx / 客户端调用中传递 Authorization 标头或全部 request.headers)、authlib create_authorization_url / authorize_redirect 未设置 code_challenge 时触发的 missing_pkce_on_auth_request,以及发现服务 SSRF、重定向、state 和 0.0.0.0 规则。
  • Go(golang-jwt / jwx、go-oidc、golang.org/x/oauth2、go-sdk 和 mcp-go HTTP 传输):go_missing_audience_validation(jwt.Parse 未设置 jwt.WithAudience)、go_oidc_client_id_check_skipped、go_token_passthrough_to_downstream(out.Header.Set("Authorization", r.Header.Get("Authorization")))、go_hardcoded_oauth_client_secret、go_loose_redirect_uri_validation(strings.HasPrefix)、go_predictable_state_handle(math/rand、time)、go_oauth_discovery_ssrf、go_auth_url_opened_via_shell、AuthCodeURL 未设置 S256ChallengeOption 时触发的 missing_pkce_on_auth_request,以及将 ListenAndServe(":8080") 识别为 listen_all_interfaces。
  • 两者通用:token_passthrough_via_variable — 读取传入的 Authorization 标头并存入变量,随后将其放入传出请求。

每项发现都会链接到 MCP 规范《安全最佳实践》 中对应的章节(SARIF helpUri),并带有作为 SARIF 标签的 OWASP MCP Top 10 编号。较新的规则是针对单个文件的启发式检查:在其他模块中执行的检查(如身份验证中间件或辅助函数中的 iss 比较)无法被检测到。

实时探测
npx @guardbee/mcp-oauth-auditor probe http://127.0.0.1:3000/mcp

对运行中的 HTTP MCP 端点执行只读检查:它是否会在没有凭据的情况下响应 initialize(probe_unauthenticated_access),以及是否接受外部 Host(probe_dns_rebinding_host_accepted)或 Origin(probe_foreign_origin_accepted)?它不会发送凭据,不会调用 initialize 以外的任何内容,会关闭它打开的任何会话,并会拒绝解析到公共地址的主机,除非指定 --allow-public。仅限 CLI:Agent 无法通过 MCP 工具启动它。


配置(guardbee.yml)

oauth-auditor:
  fail-on: high       # any | critical | high | medium | none
  max-files: 5000
  exclude:
    - ".test.ts"

局限性(有意如此)

  • TypeScript/JavaScript、Python 和 Go。 每种语言都针对其常用库设有规则(见上文)。其他语言(Rust、Java、C# 等)和其他库只有在代码形态恰好与这些规则相符时才会被匹配,例如字面量 client_secret 或 response_type=code。
  • 启发式检查,不是完整的 OAuth 一致性测试。 它会在源代码中查找特定反模式,而不是对运行中的授权服务器执行实时协议一致性检查。它无法发现 OAuth 流程的所有错误实现方式,只检查 MCP 规范指出风险最高的少数几项。
  • 基于缺失项的检查(audience、PKCE)使用有界文本窗口,而不是真正的解析器——如果 jwt.verify() 调用的选项对象是在远离调用位置的地方构建的(通过变量传入,而不是内联对象),就无法正确检查其中的 audience。

开发

npm run build
npm test

许可证

MIT — GuardBee

反馈

有问题、想法或误报?请在 GitHub Discussions 中发起讨论,或提交 issue。如果 GuardBee 对你有帮助,请在项目仓库点一个 ⭐,帮助其他人发现它。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。