supabase-extract-anon-key

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Supabase Anon Key Extraction

Supabase匿名密钥提取

🔴 CRITICAL: PROGRESSIVE FILE UPDATES REQUIRED
You MUST write to context files AS YOU GO, not just at the end.
  • Write to
    .sb-pentest-context.json
    IMMEDIATELY after each discovery
  • Log to
    .sb-pentest-audit.log
    BEFORE and AFTER each action
  • DO NOT wait until the skill completes to update files
  • If the skill crashes or is interrupted, all prior findings must already be saved
This is not optional. Failure to write progressively is a critical error.
This skill extracts the Supabase anonymous (public) API key from client-side code.
🔴 重要提示:需要逐步更新文件
你必须逐步写入上下文文件,而不是只在最后统一写入。
  • 每次发现信息后立即写入
    .sb-pentest-context.json
  • 在每个操作之前和之后都要记录到
    .sb-pentest-audit.log
  • 不要等到技能执行完成后再更新文件
  • 如果技能崩溃或被中断,所有之前的发现必须已保存
这不是可选要求。不逐步写入文件属于严重错误。
本技能用于从客户端代码中提取Supabase匿名(公开)API密钥。

When to Use This Skill

何时使用本技能

  • After extracting the Supabase URL, to get the API key for testing
  • To verify that only the anon key (not service key) is exposed
  • Before running API audit skills that require authentication
  • 提取Supabase URL之后,获取API密钥用于测试
  • 验证暴露的仅为匿名密钥(而非服务密钥)
  • 在运行需要身份验证的API审计技能之前

Prerequisites

前提条件

  • Supabase URL extracted (or will auto-invoke
    supabase-extract-url
    )
  • Target application accessible
  • 已提取Supabase URL(如果未提取,将自动调用
    supabase-extract-url
  • 目标应用可访问

Understanding Anon Keys

了解匿名密钥

The anon key (also called public key) is:
  • Expected to be in client-side code
  • Safe when RLS (Row Level Security) is properly configured
  • ⚠️ Risky if RLS is missing or misconfigured
  • Not the same as the service_role key (which should NEVER be in client code)
匿名密钥(也称为公开密钥)的特点:
  • 正常情况:会出现在客户端代码中
  • 安全前提:当RLS(行级安全)配置正确时是安全的
  • ⚠️ 风险情况:如果RLS缺失或配置错误则存在风险
  • 注意区分:与service_role密钥不同(绝对不能出现在客户端代码中)

Key Format

密钥格式

Supabase anon keys are JWTs:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFiYzEyMyIsInJvbGUiOiJhbm9uIiwiaWF0IjoxNjQwMDAwMDAwLCJleHAiOjE5NTUzNjAwMDB9.xxxx
Key characteristics:
  • Starts with
    eyJ
    (base64 encoded
    {"alg":
    )
  • Contains
    "role":"anon"
    in payload
  • Project reference in
    "ref"
    claim
Supabase匿名密钥是JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFiYzEyMyIsInJvbGUiOiJhbm9uIiwiaWF0IjoxNjQwMDAwMDAwLCJleHAiOjE5NTUzNjAwMDB9.xxxx
密钥特征:
  • eyJ
    开头(base64编码的
    {"alg":
  • 载荷中包含
    "role":"anon"
  • 包含项目引用的
    "ref"
    声明

Extraction Patterns

提取模式

The skill searches for:
本技能会搜索以下模式:

1. Direct Key Assignment

1. 直接密钥赋值

javascript
const SUPABASE_KEY = 'eyJhbGci...'
const SUPABASE_ANON_KEY = 'eyJhbGci...'
javascript
const SUPABASE_KEY = 'eyJhbGci...'
const SUPABASE_ANON_KEY = 'eyJhbGci...'

2. Client Initialization

2. 客户端初始化

javascript
createClient(url, 'eyJhbGci...')
createClient(url, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY)
javascript
createClient(url, 'eyJhbGci...')
createClient(url, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY)

3. Environment Variable Patterns

3. 环境变量模式

javascript
NEXT_PUBLIC_SUPABASE_ANON_KEY
VITE_SUPABASE_ANON_KEY
REACT_APP_SUPABASE_KEY
SUPABASE_KEY
javascript
NEXT_PUBLIC_SUPABASE_ANON_KEY
VITE_SUPABASE_ANON_KEY
REACT_APP_SUPABASE_KEY
SUPABASE_KEY

Usage

使用方法

Basic Extraction

基础提取

Extract Supabase anon key from https://myapp.example.com
Extract Supabase anon key from https://myapp.example.com

If URL Already Known

若已知道URL

Extract anon key for project abc123def
Extract anon key for project abc123def

Output Format

输出格式

═══════════════════════════════════════════════════════════
 ANON KEY EXTRACTED
═══════════════════════════════════════════════════════════

 Key Type: anon (public)
 Severity: ℹ️  Expected (verify RLS configuration)

 Key: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJz
      dXBhYmFzZSIsInJlZiI6ImFiYzEyM2RlZiIsInJvbGUiOiJhbm
      9uIiwiaWF0IjoxNjQwMDAwMDAwLCJleHAiOjE5NTUzNjAwMDB9
      .xxxxxxxxxxxxx

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

 Found in:
 └── /static/js/main.js (line 1253)
     createClient('https://abc123def.supabase.co', 'eyJhbGci...')

 Next Steps:
 ├── Run supabase-audit-rls to test if RLS protects your data
 ├── Run supabase-audit-tables-read to see what's accessible
 └── Run supabase-extract-service-key to check for critical leaks

 Context updated: .sb-pentest-context.json
═══════════════════════════════════════════════════════════
═══════════════════════════════════════════════════════════
 已提取匿名密钥
═══════════════════════════════════════════════════════════

 密钥类型:anon(公开)
 严重程度:ℹ️  正常存在(请验证RLS配置)

 密钥:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJz
      dXBhYmFzZSIsInJlZiI6ImFiYzEyM2RlZiIsInJvbGUiOiJhbm
      9uIiwiaWF0IjoxNjQwMDAwMDAwLCJleHAiOjE5NTUzNjAwMDB9
      .xxxxxxxxxxxxx

 解码后的载荷:
 ├── iss: supabase
 ├── ref: abc123def
 ├── role: anon
 ├── iat: 2021-12-20T00:00:00Z
 └── exp: 2031-12-20T00:00:00Z

 发现位置:
 └── /static/js/main.js(第1253行)
     createClient('https://abc123def.supabase.co', 'eyJhbGci...')

 后续步骤:
 ├── 运行supabase-audit-rls测试RLS是否保护你的数据
 ├── 运行supabase-audit-tables-read查看可访问的内容
 └── 运行supabase-extract-service-key检查是否存在严重泄露

 上下文已更新:.sb-pentest-context.json
═══════════════════════════════════════════════════════════

Key Validation

密钥验证

The skill validates the extracted key:
Validation:
├── Format: ✅ Valid JWT structure
├── Decode: ✅ Payload readable
├── Role: ✅ Confirmed "anon" role
├── Project: ✅ Matches extracted URL (abc123def)
└── Expiry: ✅ Not expired (expires 2031-12-20)
本技能会验证提取的密钥:
验证结果:
├── 格式:✅ 有效的JWT结构
├── 解码:✅ 载荷可读
├── 角色:✅ 已确认是"anon"角色
├── 项目:✅ 与提取的URL匹配(abc123def)
└── 有效期:✅ 未过期(到期时间2031-12-20)

Multiple Keys

发现多个密钥

If multiple keys are found:
═══════════════════════════════════════════════════════════
 MULTIPLE KEYS FOUND
═══════════════════════════════════════════════════════════

 ⚠️  2 potential Supabase keys detected

 1. Anon Key (confirmed)
    └── Role: anon, Project: abc123def

 2. Unknown Key
    └── Role: service_role ⚠️  SEE supabase-extract-service-key
        This may be a CRITICAL security issue!

═══════════════════════════════════════════════════════════
如果发现多个密钥:
═══════════════════════════════════════════════════════════
 发现多个密钥
═══════════════════════════════════════════════════════════

 ⚠️  检测到2个潜在的Supabase密钥

 1. 匿名密钥(已确认)
    └── 角色:anon,项目:abc123def

 2. 未知密钥
    └── 角色:service_role ⚠️  请查看supabase-extract-service-key
        这可能是严重的安全问题!

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

Context Output

上下文输出

Saved to
.sb-pentest-context.json
:
json
{
  "supabase": {
    "anon_key": "eyJhbGci...",
    "anon_key_decoded": {
      "iss": "supabase",
      "ref": "abc123def",
      "role": "anon",
      "iat": 1640000000,
      "exp": 1955360000
    },
    "anon_key_sources": [
      {
        "file": "/static/js/main.js",
        "line": 1253
      }
    ]
  }
}
保存到
.sb-pentest-context.json
json
{
  "supabase": {
    "anon_key": "eyJhbGci...",
    "anon_key_decoded": {
      "iss": "supabase",
      "ref": "abc123def",
      "role": "anon",
      "iat": 1640000000,
      "exp": 1955360000
    },
    "anon_key_sources": [
      {
        "file": "/static/js/main.js",
        "line": 1253
      }
    ]
  }
}

Security Assessment

安全评估

FindingSeverityDescription
Anon key in clientℹ️ InfoExpected, but test RLS
Anon key expired⚠️ P2Key should be rotated
Multiple anon keys⚠️ P2May indicate key rotation issues
Role is not "anon"🔴 P0Wrong key type exposed!
发现结果严重程度描述
客户端存在匿名密钥ℹ️ 信息正常情况,但需测试RLS
匿名密钥已过期⚠️ P2应轮换密钥
存在多个匿名密钥⚠️ P2可能表明密钥轮换存在问题
角色不是"anon"🔴 P0暴露了错误的密钥类型!

Common Issues

常见问题

Problem: Key found but won't decode ✅ Solution: May be obfuscated or split. Try:
Extract anon key with deobfuscation from https://myapp.example.com
Problem: Key doesn't match URL project ✅ Solution: App may use multiple Supabase projects. Both keys are recorded.
Problem: No key found but Supabase detected ✅ Solution: Key may be fetched at runtime. Check network requests:
Monitor network for anon key on https://myapp.example.com
问题:找到密钥但无法解码解决方案:密钥可能被混淆或拆分。尝试:
Extract anon key with deobfuscation from https://myapp.example.com
问题:密钥与URL项目不匹配解决方案:应用可能使用多个Supabase项目。两个密钥都会被记录。
问题:检测到Supabase但未找到密钥解决方案:密钥可能在运行时获取。请检查网络请求:
Monitor network for anon key on https://myapp.example.com

Best Practices Reminder

最佳实践提醒

For developers reading this report:
  1. Anon key in client is normal — It's designed for this
  2. RLS is critical — The anon key relies on RLS for security
  3. Never use service_role in client — Use Edge Functions instead
  4. Rotate keys periodically — Available in Supabase Dashboard
针对阅读本报告的开发者:
  1. 客户端存在匿名密钥是正常的 — 该密钥就是为此场景设计的
  2. RLS至关重要 — 匿名密钥的安全性依赖于RLS配置
  3. 绝对不要在客户端使用service_role密钥 — 请改用Edge Functions
  4. 定期轮换密钥 — 可在Supabase控制台操作

MANDATORY: Progressive Context File Updates

强制要求:逐步更新上下文文件

⚠️ This skill MUST update tracking files PROGRESSIVELY during execution, NOT just at the end.
⚠️ 本技能必须在执行过程中逐步更新跟踪文件,而不是只在最后统一更新。

Critical Rule: Write As You Go

核心规则:逐步写入

DO NOT batch all writes at the end. Instead:
  1. Before starting any action → Log the action to
    .sb-pentest-audit.log
  2. After each discovery → Immediately update
    .sb-pentest-context.json
  3. After each significant step → Log completion to
    .sb-pentest-audit.log
This ensures that if the skill is interrupted, crashes, or times out, all findings up to that point are preserved.
不要在最后批量写入。请按以下步骤操作:
  1. 在开始任何操作之前 → 将操作记录到
    .sb-pentest-audit.log
  2. 每次发现信息后 → 立即更新
    .sb-pentest-context.json
  3. 完成每个重要步骤后 → 将完成情况记录到
    .sb-pentest-audit.log
这样可以确保如果技能被中断、崩溃或超时,所有已有的发现都会被保留。

Required Actions (Progressive)

必须执行的逐步操作

  1. Update
    .sb-pentest-context.json
    with extracted data:
    json
    {
      "supabase": {
        "anon_key": "eyJhbGci...",
        "anon_key_decoded": { ... },
        "anon_key_sources": [ ... ]
      }
    }
  2. Log to
    .sb-pentest-audit.log
    :
    [TIMESTAMP] [supabase-extract-anon-key] [START] Beginning anon key extraction
    [TIMESTAMP] [supabase-extract-anon-key] [SUCCESS] Anon key extracted
    [TIMESTAMP] [supabase-extract-anon-key] [CONTEXT_UPDATED] .sb-pentest-context.json updated
  3. If files don't exist, create them before writing.
FAILURE TO UPDATE CONTEXT FILES IS NOT ACCEPTABLE.
  1. 更新
    .sb-pentest-context.json
    ,写入提取的数据:
    json
    {
      "supabase": {
        "anon_key": "eyJhbGci...",
        "anon_key_decoded": { ... },
        "anon_key_sources": [ ... ]
      }
    }
  2. 记录到
    .sb-pentest-audit.log
    [TIMESTAMP] [supabase-extract-anon-key] [START] 开始提取匿名密钥
    [TIMESTAMP] [supabase-extract-anon-key] [SUCCESS] 已提取匿名密钥
    [TIMESTAMP] [supabase-extract-anon-key] [CONTEXT_UPDATED] 已更新.sb-pentest-context.json
  3. 如果文件不存在,在写入前先创建。
不更新上下文文件是不被允许的。

MANDATORY: Evidence Collection

强制要求:收集证据

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

Evidence Files to Create

需要创建的证据文件

FileContent
extracted-anon-key.json
Anon key with decoded JWT payload
文件内容
extracted-anon-key.json
包含匿名密钥及解码后的JWT载荷

Evidence Format

证据格式

json
{
  "evidence_id": "EXT-ANON-001",
  "timestamp": "2025-01-31T10:07:00Z",
  "category": "extraction",
  "type": "anon_key",
  "severity": "info",

  "key_data": {
    "key_prefix": "eyJhbGciOiJIUzI1NiI...",
    "key_suffix": "...xxxx",
    "full_key_length": 256
  },

  "decoded_payload": {
    "iss": "supabase",
    "ref": "abc123def",
    "role": "anon",
    "iat": "2021-12-20T00:00:00Z",
    "exp": "2031-12-20T00:00:00Z"
  },

  "source": {
    "file": "/static/js/main.js",
    "line": 1253,
    "context": "createClient('https://abc123def.supabase.co', 'eyJhbGci...')"
  },

  "validation": {
    "format_valid": true,
    "role_confirmed": "anon",
    "project_matches": true,
    "expired": false
  }
}
json
{
  "evidence_id": "EXT-ANON-001",
  "timestamp": "2025-01-31T10:07:00Z",
  "category": "extraction",
  "type": "anon_key",
  "severity": "info",

  "key_data": {
    "key_prefix": "eyJhbGciOiJIUzI1NiI...",
    "key_suffix": "...xxxx",
    "full_key_length": 256
  },

  "decoded_payload": {
    "iss": "supabase",
    "ref": "abc123def",
    "role": "anon",
    "iat": "2021-12-20T00:00:00Z",
    "exp": "2031-12-20T00:00:00Z"
  },

  "source": {
    "file": "/static/js/main.js",
    "line": 1253,
    "context": "createClient('https://abc123def.supabase.co', 'eyJhbGci...')"
  },

  "validation": {
    "format_valid": true,
    "role_confirmed": "anon",
    "project_matches": true,
    "expired": false
  }
}

Related Skills

相关技能

  • supabase-extract-url
    — Get URL first (auto-invoked if needed)
  • supabase-extract-service-key
    — Check for critical service key leak
  • supabase-audit-rls
    — Test if RLS protects your data
  • supabase-audit-tables-read
    — See what data is accessible with this key
  • supabase-extract-url
    — 先获取URL(如果需要会自动调用)
  • supabase-extract-service-key
    — 检查是否存在严重的服务密钥泄露
  • supabase-audit-rls
    — 测试RLS是否能保护你的数据
  • supabase-audit-tables-read
    — 查看使用该密钥可访问的数据