supabase-extract-anon-key
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSupabase Anon Key Extraction
Supabase匿名密钥提取
🔴 CRITICAL: PROGRESSIVE FILE UPDATES REQUIREDYou MUST write to context files AS YOU GO, not just at the end.
- Write to
IMMEDIATELY after each discovery.sb-pentest-context.json- Log to
BEFORE and AFTER each action.sb-pentest-audit.log- 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.xxxxKey characteristics:
- Starts with (base64 encoded
eyJ){"alg": - Contains in payload
"role":"anon" - Project reference in claim
"ref"
Supabase匿名密钥是JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImFiYzEyMyIsInJvbGUiOiJhbm9uIiwiaWF0IjoxNjQwMDAwMDAwLCJleHAiOjE5NTUzNjAwMDB9.xxxx密钥特征:
- 以开头(base64编码的
eyJ){"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_KEYjavascript
NEXT_PUBLIC_SUPABASE_ANON_KEY
VITE_SUPABASE_ANON_KEY
REACT_APP_SUPABASE_KEY
SUPABASE_KEYUsage
使用方法
Basic Extraction
基础提取
Extract Supabase anon key from https://myapp.example.comExtract Supabase anon key from https://myapp.example.comIf URL Already Known
若已知道URL
Extract anon key for project abc123defExtract anon key for project abc123defOutput 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.jsonjson
{
"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.jsonjson
{
"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
安全评估
| Finding | Severity | Description |
|---|---|---|
| Anon key in client | ℹ️ Info | Expected, but test RLS |
| Anon key expired | ⚠️ P2 | Key should be rotated |
| Multiple anon keys | ⚠️ P2 | May indicate key rotation issues |
| Role is not "anon" | 🔴 P0 | Wrong 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.comBest Practices Reminder
最佳实践提醒
For developers reading this report:
- Anon key in client is normal — It's designed for this
- RLS is critical — The anon key relies on RLS for security
- Never use service_role in client — Use Edge Functions instead
- Rotate keys periodically — Available in Supabase Dashboard
针对阅读本报告的开发者:
- 客户端存在匿名密钥是正常的 — 该密钥就是为此场景设计的
- RLS至关重要 — 匿名密钥的安全性依赖于RLS配置
- 绝对不要在客户端使用service_role密钥 — 请改用Edge Functions
- 定期轮换密钥 — 可在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:
- Before starting any action → Log the action to
.sb-pentest-audit.log - After each discovery → Immediately update
.sb-pentest-context.json - 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.
不要在最后批量写入。请按以下步骤操作:
- 在开始任何操作之前 → 将操作记录到
.sb-pentest-audit.log - 每次发现信息后 → 立即更新
.sb-pentest-context.json - 完成每个重要步骤后 → 将完成情况记录到
.sb-pentest-audit.log
这样可以确保如果技能被中断、崩溃或超时,所有已有的发现都会被保留。
Required Actions (Progressive)
必须执行的逐步操作
-
Updatewith extracted data:
.sb-pentest-context.jsonjson{ "supabase": { "anon_key": "eyJhbGci...", "anon_key_decoded": { ... }, "anon_key_sources": [ ... ] } } -
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 -
If files don't exist, create them before writing.
FAILURE TO UPDATE CONTEXT FILES IS NOT ACCEPTABLE.
-
更新,写入提取的数据:
.sb-pentest-context.jsonjson{ "supabase": { "anon_key": "eyJhbGci...", "anon_key_decoded": { ... }, "anon_key_sources": [ ... ] } } -
记录到:
.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 -
如果文件不存在,在写入前先创建。
不更新上下文文件是不被允许的。
MANDATORY: Evidence Collection
强制要求:收集证据
📁 Evidence Directory:
.sb-pentest-evidence/02-extraction/📁 证据目录:
.sb-pentest-evidence/02-extraction/Evidence Files to Create
需要创建的证据文件
| File | Content |
|---|---|
| Anon key with decoded JWT payload |
| 文件 | 内容 |
|---|---|
| 包含匿名密钥及解码后的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
相关技能
- — Get URL first (auto-invoked if needed)
supabase-extract-url - — Check for critical service key leak
supabase-extract-service-key - — Test if RLS protects your data
supabase-audit-rls - — See what data is accessible with this key
supabase-audit-tables-read
- — 先获取URL(如果需要会自动调用)
supabase-extract-url - — 检查是否存在严重的服务密钥泄露
supabase-extract-service-key - — 测试RLS是否能保护你的数据
supabase-audit-rls - — 查看使用该密钥可访问的数据
supabase-audit-tables-read