mcpField
S
supabase-extract-jwt

supabase-extract-jwt

github.com/yoanbernabeu安全71473 次安装39 周前更新
代码仓库

关于 supabase-extract-jwt

此安全技能用于查找并分析客户端代码中的 Supabase 相关 JWT。它检查令牌声明和存储引用,帮助识别暴露的密钥、硬编码用户令牌及身份验证信息。

主要功能

  1. 01查找客户端代码中的 JWT 和 API 密钥
  2. 02分析令牌声明与过期时间
  3. 03检测硬编码用户令牌和个人信息
  4. 04识别 JWT 存储引用
  5. 05保存发现结果与提取证据

适用场景

  1. 01检查客户端代码是否暴露 service role 密钥
  2. 02调查硬编码的用户令牌
  3. 03审查令牌声明和过期时间
  4. 04了解身份验证相关代码模式

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/yoanbernabeu/supabase-pentest-skills --skill supabase-extract-jwt

安装后在 Claude Code 中输入/supabase-extract-jwt确认已加载。

详细介绍

Supabase JWT 提取

🔴 严重:必须渐进式更新文件

必须在过程中写入上下文文件,而不是只在最后写入。

  • 每次发现后立即写入 .sb-pentest-context.json
  • 每次操作前后都记录到 .sb-pentest-audit.log
  • 不要等到技能执行完毕后才更新文件
  • 如果技能崩溃或中断,所有先前的发现都必须已经保存

这不是可选项。未能渐进式写入是严重错误。

此技能用于从客户端代码中提取并分析与 Supabase 相关的 JSON Web Token(JWT)。

何时使用此技能

  • 查找客户端代码中暴露的所有 JWT 令牌
  • 分析令牌声明和过期时间
  • 检测硬编码的用户令牌(安全问题)
  • 了解身份验证流程

前提条件

  • 可以访问目标应用
  • 已完成 Supabase 检测(如有需要会自动调用)

Supabase 中的 JWT 类型

类型用途客户端暴露情况
Anon KeyAPI 身份验证✅ 预期情况
Service Role Key管理员访问❌ 绝不可暴露
Access Token用户会话⚠️ 仅动态生成
Refresh Token令牌续期⚠️ 仅动态生成

检测模式

1. API 密钥(静态)
// Supabase API keys are JWTs
const SUPABASE_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
2. 硬编码的用户令牌(问题)
// ❌ Should never be hardcoded
const userToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwiZW1haWwiOiJ1c2VyQGV4YW1wbGUuY29tIn0...'
3. 存储密钥模式
// Code referencing where JWTs are stored
localStorage.getItem('supabase.auth.token')
localStorage.getItem('sb-abc123-auth-token')
sessionStorage.getItem('supabase_session')

用法

基本提取
Extract JWTs from https://myapp.example.com
分析声明
Extract and analyze all JWTs from https://myapp.example.com

输出格式

═══════════════════════════════════════════════════════════
 JWT EXTRACTION RESULTS
═══════════════════════════════════════════════════════════

 Found: 3 JWTs

 ─────────────────────────────────────────────────────────
 JWT #1: Supabase Anon Key
 ─────────────────────────────────────────────────────────
 Type: API Key (anon)
 Status: ✅ Expected in client code

 Header:
 ├── alg: HS256
 └── typ: JWT

 Payload:
 ├── iss: supabase
 ├── ref: abc123def
 ├── role: anon
 ├── iat: 2021-12-20T00:00:00Z
 └── exp: 2031-12-20T00:00:00Z

 Location: /static/js/main.js:1247

 ─────────────────────────────────────────────────────────
 JWT #2: Hardcoded User Token ⚠️
 ─────────────────────────────────────────────────────────
 Type: User Access Token
 Status: ⚠️ P1 - Should not be hardcoded

 Header:
 ├── alg: HS256
 └── typ: JWT

 Payload:
 ├── sub: 12345678-1234-1234-1234-123456789012
 ├── email: [email protected]
 ├── role: authenticated
 ├── iat: 2025-01-15T10:00:00Z
 └── exp: 2025-01-15T11:00:00Z (EXPIRED)

 Location: /static/js/debug.js:45

 Risk: This token may belong to a real user account.
       Even if expired, it reveals user information.

 ─────────────────────────────────────────────────────────
 JWT #3: Storage Reference
 ─────────────────────────────────────────────────────────
 Type: Storage Key Pattern
 Status: ℹ️ Informational

 Pattern: localStorage.getItem('sb-abc123def-auth-token')
 Location: /static/js/auth.js:89

 Note: This is the expected storage key for user sessions.
       Actual token value is set at runtime.

═══════════════════════════════════════════════════════════

JWT 声明分析

此技能会识别关键声明:

标准声明
声明描述安全影响
sub用户 ID标识特定用户
email用户邮箱硬编码时会暴露个人身份信息
role权限级别service_role 属于严重风险
exp过期时间已过期的令牌风险较低
iat签发时间表示令牌的创建时间
Supabase 特定声明
声明描述
ref项目引用
iss应为 "supabase"
aal验证器保证级别
amr使用的身份验证方式

安全发现

P0 - 严重
🔴 Service role key exposed (role: service_role)
   → Immediate key rotation required
P1 - 高
🟠 User token hardcoded with PII (email, sub visible)
   → Remove from code, may need to notify user
P2 - 中
🟡 Expired test token in code
   → Clean up, potential information disclosure

上下文输出

保存至 .sb-pentest-context.json:

{
  "jwts": {
    "found": 3,
    "api_keys": [
      {
        "type": "anon",
        "project_ref": "abc123def",
        "location": "/static/js/main.js:1247"
      }
    ],
    "user_tokens": [
      {
        "type": "access_token",
        "hardcoded": true,
        "severity": "P1",
        "claims": {
          "sub": "12345678-1234-1234-1234-123456789012",
          "email": "[email protected]",
          "expired": true
        },
        "location": "/static/js/debug.js:45"
      }
    ],
    "storage_patterns": [
      {
        "pattern": "sb-abc123def-auth-token",
        "storage": "localStorage",
        "location": "/static/js/auth.js:89"
      }
    ]
  }
}

常见问题

❌ 问题: JWT 看起来被截断了
✅ 解决方案: 内容可能跨越多行。此技能会尝试重新拼接。

❌ 问题: 无法解码 JWT
✅ 解决方案: 可能经过加密(JWE)或使用自定义格式。会将其标记为无法解码。

❌ 问题: 误报很多
✅ 解决方案: 一些 Base64 字符串看起来像 JWT。此技能会验证其结构。

硬编码令牌的修复方法

修复前(错误)
// ❌ Never hardcode user tokens
const adminToken = 'eyJhbGciOiJIUzI1NiI...'
fetch('/api/admin', {
  headers: { Authorization: `Bearer ${adminToken}` }
})
修复后(正确)
// ✅ Get token from Supabase session
const { data: { session } } = await supabase.auth.getSession()
fetch('/api/admin', {
  headers: { Authorization: `Bearer ${session.access_token}` }
})

强制要求:渐进式更新上下文文件

⚠️ 此技能必须在执行过程中渐进式更新跟踪文件,而不是只在最后更新。

关键规则:边操作边写入

不要等到最后才批量写入。应按以下步骤操作:

  1. 开始任何操作前 → 将操作记录到 .sb-pentest-audit.log
  2. 每次发现后 → 立即更新 .sb-pentest-context.json
  3. 每个重要步骤后 → 将完成情况记录到 .sb-pentest-audit.log

这样可确保即使技能被中断、崩溃或超时,在此之前发现的所有内容都能得到保留。

必需操作(渐进式)
  1. 更新 .sb-pentest-context.json,加入提取的数据:

    {
      "jwts": {
        "found": 3,
        "api_keys": [ ... ],
        "user_tokens": [ ... ],
        "storage_patterns": [ ... ]
      }
    }
    
  2. 记录到 .sb-pentest-audit.log:

    [TIMESTAMP] [supabase-extract-jwt] [START] Beginning JWT extraction
    [TIMESTAMP] [supabase-extract-jwt] [SUCCESS] Found 3 JWTs
    [TIMESTAMP] [supabase-extract-jwt] [CONTEXT_UPDATED] .sb-pentest-context.json updated
    
  3. 如果文件不存在,请在写入前创建文件。

未能更新上下文文件不可接受。

强制要求:证据收集

📁 证据目录: .sb-pentest-evidence/02-extraction/

要创建的证据文件
文件内容
extracted-jwts.json找到的所有 JWT 及其分析结果
证据格式
{
  "evidence_id": "EXT-JWT-001",
  "timestamp": "2025-01-31T10:08:00Z",
  "category": "extraction",
  "type": "jwt_extraction",

  "jwts_found": [
    {
      "type": "anon_key",
      "severity": "info",
      "location": "/static/js/main.js:1247",
      "decoded_payload": {
        "iss": "supabase",
        "ref": "abc123def",
        "role": "anon"
      }
    },
    {
      "type": "hardcoded_user_token",
      "severity": "P1",
      "location": "/static/js/debug.js:45",
      "decoded_payload": {
        "sub": "[REDACTED]",
        "email": "[REDACTED]@example.com",
        "role": "authenticated",
        "exp": "2025-01-15T11:00:00Z"
      },
      "expired": true,
      "issue": "Hardcoded user token with PII"
    }
  ],

  "storage_patterns_found": [
    {
      "pattern": "localStorage.getItem('sb-abc123def-auth-token')",
      "location": "/static/js/auth.js:89"
    }
  ]
}

相关技能

  • supabase-extract-anon-key — 专门提取 anon key
  • supabase-extract-service-key — 检查 service key(至关重要)
  • supabase-audit-auth-config — 分析身份验证配置

评论

支持 Markdown