js-secrets-extraction – skill Bảo mật cho agent AI
Phân tích JS bundle và source map để tìm secret được mã hóa cứng, API key, JWT và endpoint nội bộ.
Cài skill js-secrets-extraction bằng một lệnh
Chọn công cụ bạn đang dùng, copy lệnh và dán vào terminal. Skill sẽ nằm trong thư mục skills của công cụ đó và sẵn sàng dùng ở phiên làm việc tiếp theo.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/js-secrets-extraction-e27b3.tgz | tar xz -C ~/.claude/skills
Gọi trong Claude Code: /js-secrets-extraction – rồi mô tả công việc bạn muốn làm.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/js-secrets-extraction-e27b3.tgz | tar xz -C ~/.codex/skills
Gọi trong Codex: $js-secrets-extraction – rồi mô tả công việc bạn muốn làm.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/js-secrets-extraction-e27b3.tgz | tar xz -C ~/.hermes/skills
Gọi trong Hermes Agent: /js-secrets-extraction – rồi mô tả công việc bạn muốn làm.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/js-secrets-extraction-e27b3.tgz | tar xz -C ~/.deepcode/skills
Gọi trong DeepSeek: /js-secrets-extraction – rồi mô tả công việc bạn muốn làm.
Nội dung SKILL.md
Nội dung SKILL.md gốc bằng tiếng Anh.
JS Bundle & Source Map Analysis -- Secret Extraction
When to Use
- ALWAYS after initial web enumeration
- When you find modern SPA (React, Angular, Vue)
- When target uses Firebase, Supabase, Auth0
- Higher yield than directory scanning on many targets
Why Analyze JS Bundles
Modern JavaScript bundles (Webpack, Vite, esbuild) often contain:
- Hardcoded API keys and tokens
- Internal API URLs
- Firebase, Auth0, Supabase configurations
- Environment variables (VITE_*, REACT_APP_*, NEXT_PUBLIC_*)
- Internal routes
Bundle Download and Analysis
curl --max-time 30 --connect-timeout 10 -s "https://target.com" > index.html
grep -Eo 'src="[^"]*\.js"' index.html | cut -d'"' -f2 | while read js; do
curl --max-time 30 --connect-timeout 10 -s "https://target.com$js" > "$(basename $js)"
done
# Search for secrets in bundles
grep -rEn "(apiKey|api_key|API_KEY|token|secret|password|clientId|client_id|auth0|firebase|supabase)[\"'\"]?[[:space:]]*[:=][[:space:]]*[\"'\'][^\"'\']{8,}" *.jsSource Map Reconstruction
curl --max-time 30 --connect-timeout 10 -sI "https://target.com/assets/index-abc123.js.map"
curl --max-time 30 --connect-timeout 10 -sI "https://target.com/static/js/main.12345.js.map"
# If HTTP 200, use for reconstruction:
# https://unminify.com
# https://source-map-visualization.netlify.appReal-world case: Enterprise Angular SPA admin, 2 JS bundles (250KB each) exposed:
- Internal API URL (apiv3.empresa.com.br)
- Firebase API key (AIzaSy...2GXA)
- Encryption keys (AD5oDjsJaTJOzLe1Llj9mz)
- Cloudinary upload endpoint
Port-Specific URL Analysis
Modern deployments often serve the main SPA on port 443 and admin/API on separate ports (8080, 8081, 8084). Always check JS bundles on ALL discovered ports:
# Check source maps on every open port
for port in 443 8080 8081 8084; do
curl --max-time 30 --connect-timeout 10 -sI "https://target.com:$port/static/js/main.*.js.map" 2>/dev/null
curl --max-time 30 --connect-timeout 10 -sI "https://target.com:$port/assets/index-*.js.map" 2>/dev/null
doneSource maps on administrative or alternate-port applications may expose a
different route and configuration set from the public SPA. Analyze each
authorized application independently.
Admin Portal JS Analysis Pattern
When you find an admin portal on a separate port, the JS bundle often contains different secrets than the main site:
base = "https://target.com:8080" # Admin portal
js = requests.get(f"{base}/static/js/main.*.js").text
# 1. Extract ALL API URLs
api_urls = re.findall(r'https?://[^\"\'[[:space:]]\\n,)>\\]]+', js)
# 2. Find base API URL (the backend this admin talks to)
# 3. Look for hardcoded credentials, API keys, auth patterns
# 4. Extract route paths for the admin app
routes = re.findall(r'[\"\'](/[a-zA-Z0-9_/.-]*(?:admin|chat|bot|message|user|auth|login|token|config|setting|dashboard|hospital|pharmacy|drug|payment)[a-zA-Z0-9_/.-]*)[\"\']', js, re.IGNORECASE)Source Map Content Analysis (1,200+ Files)
When source maps are available, analyze the sourcesContent array for hardcoded secrets:
import json, re
data = json.loads(open("bundle.js.map").read())
all_source = " ".join(data.get("sourcesContent", []))
# Search for credentials in the original source
patterns = {
"password": r'[\"\']([^\"\']*(?:password|passwd|pwd)[^\"\']*)[\"\']\s*[:=]\s*[\"\']([^\"\']+)[\"\']',
"token": r'[\"\']([^\"\']*(?:token|jwt|api_key|apikey|secret)[^\"\']*)[\"\']\s*[:=]\s*[\"\']([^\"\']+)[\"\']',
}
for name, pat in patterns.items():
matches = re.findall(pat, all_source, re.IGNORECASE)
if matches:
print(f"[{name}] {matches[:5]}")- Cloudinary upload endpoint
Secret Regex Patterns Catalog
import re
patterns = {
"Firebase API Key": r'apiKey:\s*[\"\']([^\"\']{30,})',
"AWS Key": r'(?:AKIA|ASIA)[A-Z0-9]{16}',
"Google API Key": r'AIza[0-9A-Za-z\\-_]{35}',
"JWT": r'eyJ[A-Za-z0-9_\\-]{20,}\.[A-Za-z0-9_\\-]{20,}\.[A-Za-z0-9_\\-]{10,}',
"Mercado Pago": r'APP_USR-[a-f0-9]{8,}',
"Stripe": r'(?:sk_live|pk_live)_[A-Za-z0-9]{24,}',
"Auth0 Domain": r'(?:domain|auth0_domain):\s*[\"\']([^\"\']+\.auth0\.com)',
"Auth0 Client ID": r'(?:client_id|clientId|AUTH0_CLIENT_ID):\s*[\"\']([^\"\']{20,})',
"Supabase URL": r'(?:supabaseUrl|SUPABASE_URL):\s*[\"\'](https://[^\"\']+\.supabase\.co)',
"Supabase Key": r'(?:supabaseKey|anonKey|SUPABASE_ANON_KEY):\s*[\"\'](eyJ[A-Za-z0-9_\\-]+\.[A-Za-z0-9_\\-]+\.[A-Za-z0-9_\\-]+)',
"Heroku": r'[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}',
"Generic Secret": r'(?:secret|password|token|key):\s*[\"\']([^\"\']{8,})',
}Batch Bundle Download + Grep
import requests, re, json
base = "https://target.com"
html = requests.get(base).text
# Extract all JS URLs
js_urls = re.findall(r'src="([^"]*\.js)"', html)
for js_url in js_urls:
if js_url.startswith("/"):
js_url = base + js_url
content = requests.get(js_url).text
for name, pattern in patterns.items():
matches = re.findall(pattern, content)
for m in matches:
if isinstance(m, tuple):
m = m[0]
if len(m) > 6:
print(f"[{name}] {m[:80]}")Pitfalls
| Issue | Solution |
|-------|----------|
| Bundles too large | Use grep -Eo with specific patterns |
| Minified code (1 char names) | Use source maps for reconstruction |
| False positive matches | Validate keys by testing API endpoint |
| Rate limiting | Add delays between bundle downloads |
---
Backend URL Discovery
JS bundles frequently leak production backend URLs, enabling direct API attacks bypassing CDN/WAF:
# Platform-specific backend URL patterns
grep -Eo 'https?://[a-zA-Z0-9.\-]+\.(fly\.dev|azurewebsites\.net|onrender\.com|vercel\.app|netlify\.app)[^"'\'' ]{0,40}' /tmp/*.js
grep -Eo 'https?://[a-zA-Z0-9.\-]+\.(supabase\.co|r2\.dev|blob\.vercel-storage\.com)[^"'\'' ]{0,40}' /tmp/*.js
# Edge function URLs
grep -Eo 'functions/v1/[a-zA-Z0-9_\-]+' /tmp/*.js
# Internal API paths
grep -Eo '["\x60]/api/v1/[a-zA-Z0-9_\-/]+["\x60]' /tmp/*.jsReal Field Patterns
| Pattern | Platform | Example | Secret? |
|---------|----------|---------|---------|
| *.fly.dev | Fly.io | ht-prod-backend.fly.dev | ✅ Backend URL |
| *.azurewebsites.net | Azure | consigpro-api-prod-... | ✅ Backend URL |
| *.onrender.com | Render | clickcity-api.onrender.com | ✅ Backend URL |
| *.supabase.co | Supabase | jxhvjufqtabpeieyhkgk.supabase.co | ✅ Anon key is public; backend URL is intel |
| *.r2.dev | Cloudflare R2 | pub-xxx.r2.dev | ✅ Storage URL |
| functions/v1/* | Supabase Edge | provision-openrouter-key | ✅ Endpoint name |
| dpl_* | Vercel DPL | dpl_BCoyPsxxYLZ... | ❌ NOT a secret — public deploy ID |
Verification
# Test Firebase API key
curl --max-time 30 --connect-timeout 10 -s "https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=AIza..."
# Test Supabase anon key
curl --max-time 30 --connect-timeout 10 -s "https://PROJECT.supabase.co/rest/v1/users?limit=1" -H "apikey: ANON_KEY" -H "Authorization: Bearer ANON_KEY"Phase 5 — Source Map Exploitation
Recover full pre-compiled source code when .js.map files are left in production:
# Find .map files via Wayback Machine
curl --max-time 30 --connect-timeout 10 -s "https://web.archive.org/cdx/search/cdx?url=*.target.com/*&collapse=urlkey&output=text&fl=original&filter=original:.*\.js\.map$" \
| sort -u > map_urls.txt
# Download and extract source
wget https://target.com/static/app.js.map
node -e "
const map = require('./app.js.map');
map.sources.forEach((src, i) => {
const fs = require('fs');
fs.writeFileSync(src.split('/').pop(), map.sourcesContent[i]);
});
print('Extracted ' + map.sources.length + ' source files');
"
# Quick check: does a JS file have an available map?
curl --max-time 30 --connect-timeout 10 -skI "https://target.com/static/app.js.map" | grep "200\|Content-Type"Phase 6 — Deep JS Crawling
Crawl JS files recursively for embedded URLs, APIs, and IPs:
# lazyegg — crawls JS files for links, APIs, IPs
python3 lazyegg.py https://target.com
python3 lazyegg.py https://target.com/js/auth.js
# Combine with waybackurls for deep coverage
waybackurls target.com \
| grep '\.js$' \
| awk -F '?' '{print $1}' \
| sort -u \
| xargs -I{} bash -c 'python3 lazyegg.py "{}" --js_urls --domains --ips' \
> lazyegg_output.txt
# subjs — extract JS URLs from any URL list
cat all_urls.txt | subjs | tee js_files_full.txtPhase 7 — Per-File AI-Assisted Code Review
JS bundles are source code — even minified. A disciplined per-file (per-chunk) review finds what autonomous agents miss:
# 1. Download all JS chunks
curl --max-time 30 --connect-timeout 10 -sk "https://target.com" | grep -Eo 'src="[^"]+\.js[^"]*"' | \
cut -d'"' -f2 | while read js; do
curl … (nội dung đầy đủ có trong gói tải về)
Skill liên quan
- jwt-attack – Giải mã, giả mạo và brute-force JWT khi thấy header xác thực Bearer.
- helm-chart-builder – Skill và plugin agent phát triển Helm chart cho Claude Code, Codex, Gemini CLI, Cursor…
- meme-coin-audit – Kiểm tra bảo mật meme coin và token — phát hiện rug pull (honeypot, mint ẩn, thao túng…
- changelog-entry – Tạo mục CHANGELOG.md đúng định dạng Keep a Changelog từ khoảng commit hoặc PR. Nhóm thay…
- mid-engagement-ir-detection – Phương pháp phát hiện bản vá SOC của khách hàng, hoạt động tấn công và thay đổi trạng…
- oss-forensics – Điều tra pháp chứng chuỗi cung ứng GitHub: khôi phục, IOC, báo cáo.
- cis-benchmarks – Kiểm tra và khắc phục các vi phạm benchmark CIS.
- incident-response – Dùng khi một sự cố bảo mật đã được phát hiện hoặc khai báo, cần phân loại, sàng lọc ưu…