AgentSkillsCN

Z Audit

Z 审计

SKILL.md

Z-Audit: Security Audit for Vibe-Coded Projects

"2026 is the year of vibe-coding. Ship fast, audit faster."

Overview

A comprehensive, adaptive security audit that detects your stack and runs targeted checks. Designed for developers who moved fast and need to find vulnerabilities before someone else does.


Phase 0: Stack Detection (ALWAYS RUN FIRST)

Before auditing, detect what you're working with. This determines which checks to run.

0.1 If Given URLs (Remote Audit)

bash
# Fetch frontend and identify framework
curl -s "[FRONTEND_URL]" | grep -oE '(react|vue|svelte|next|nuxt|astro|vite)'

# Find JS bundles
curl -s "[FRONTEND_URL]" | grep -oE '[^"]+\.(js|mjs)"' | head -10

# Identify API type from URL patterns
# .workers.dev = Cloudflare Workers
# .vercel.app = Vercel Serverless
# .netlify.app = Netlify Functions
# .supabase.co = Supabase direct
# .firebaseapp.com = Firebase

0.2 If Given Local Codebase

bash
# Detect from config files
ls -la | grep -E "package.json|requirements.txt|go.mod|Cargo.toml|wrangler.toml|vercel.json|netlify.toml|supabase|firebase"

# Check package.json for framework
cat package.json | grep -E '"(react|vue|svelte|next|nuxt|hono|express|fastify|elysia)"'

# Check for auth libraries
cat package.json | grep -E '"(@supabase|firebase|@clerk|@auth0|better-auth|lucia|next-auth)"'

0.3 Stack Detection Matrix

SignalStackSpecial Checks
wrangler.tomlCloudflare WorkersCheck secrets, KV, D1
vercel.jsonVercelCheck env vars, edge functions
supabase/ dirSupabaseCheck RLS, anon key permissions
firebase.jsonFirebaseCheck Firestore rules, Auth
next.config.jsNext.jsCheck API routes, middleware
nuxt.config.tsNuxtCheck server routes, nitro
hono in depsHono APICheck middleware chain
express in depsExpressCheck middleware order

Phase 1: Secrets & Credentials Audit

1.1 Frontend Bundle Scan (CRITICAL)

For Remote Sites:

bash
# Get main bundle URL
BUNDLE=$(curl -s "[FRONTEND_URL]" | grep -oE 'src="[^"]+\.js"' | head -1 | cut -d'"' -f2)
curl -s "[FRONTEND_URL]$BUNDLE" > /tmp/bundle.js

# Scan for secrets

Universal Secret Patterns:

bash
# API Keys by provider
grep -oE 'sk-[a-zA-Z0-9]{20,}' /tmp/bundle.js              # OpenAI
grep -oE 'sk_live_[a-zA-Z0-9]+' /tmp/bundle.js             # Stripe Live
grep -oE 'sk_test_[a-zA-Z0-9]+' /tmp/bundle.js             # Stripe Test
grep -oE 'pk_live_[a-zA-Z0-9]+' /tmp/bundle.js             # Stripe Publishable
grep -oE 'AKIA[A-Z0-9]{16}' /tmp/bundle.js                 # AWS Access Key
grep -oE 'ghp_[a-zA-Z0-9]{36}' /tmp/bundle.js              # GitHub PAT
grep -oE 'gho_[a-zA-Z0-9]{36}' /tmp/bundle.js              # GitHub OAuth
grep -oE 'glpat-[a-zA-Z0-9\-]{20}' /tmp/bundle.js          # GitLab PAT
grep -oE 'xox[baprs]-[a-zA-Z0-9\-]+' /tmp/bundle.js        # Slack Token
grep -oE 'ya29\.[a-zA-Z0-9_-]+' /tmp/bundle.js             # Google OAuth
grep -oE 'AIza[a-zA-Z0-9_-]{35}' /tmp/bundle.js            # Google API Key
grep -oE 'eyJ[a-zA-Z0-9_-]*\.eyJ[a-zA-Z0-9_-]*\.[a-zA-Z0-9_-]*' /tmp/bundle.js  # JWTs

# Supabase specific
grep -oE 'eyJ[a-zA-Z0-9_=-]+\.[a-zA-Z0-9_=-]+\.[a-zA-Z0-9_=-]+' /tmp/bundle.js  # Supabase anon/service key
grep -oE 'https://[a-z]+\.supabase\.co' /tmp/bundle.js     # Supabase URL

# Firebase specific
grep -oE 'AIza[a-zA-Z0-9_-]{35}' /tmp/bundle.js            # Firebase API Key
grep -oE '[a-z]+-[a-z0-9]+\.firebaseapp\.com' /tmp/bundle.js

# Generic high-entropy strings (potential secrets)
grep -oE '"[a-zA-Z0-9_-]{32,64}"' /tmp/bundle.js | head -20

# Hardcoded passwords
grep -oiE '(password|passwd|pwd|secret)["\x27\s]*[=:]["\x27\s]*["\x27][^"\x27]{4,}["\x27]' /tmp/bundle.js

1.2 Local Codebase Secrets Scan

bash
# Check for .env files committed
find . -name ".env*" -not -path "./node_modules/*" 2>/dev/null

# Check git history for secrets
git log -p --all -S 'password' --since="1 year ago" -- '*.js' '*.ts' '*.json' 2>/dev/null | head -50
git log -p --all -S 'secret' --since="1 year ago" -- '*.js' '*.ts' '*.json' 2>/dev/null | head -50
git log -p --all -S 'sk-' --since="1 year ago" 2>/dev/null | head -50

# Scan source files
grep -rn --include="*.ts" --include="*.js" --include="*.tsx" \
  -E '(api_key|apikey|api-key|secret|password|token)\s*[=:]\s*["\x27][^"\x27]+["\x27]' . 2>/dev/null

# Check for hardcoded in config
grep -rn --include="*.json" --include="*.yaml" --include="*.yml" \
  -E '(key|secret|password|token)' . 2>/dev/null | grep -v node_modules

Phase 2: Authentication & Authorization

2.1 Client-Side Auth Detection

bash
# localStorage/sessionStorage auth (weak)
grep -oE 'localStorage\.(get|set)Item\(["\x27][^"\x27]*(auth|session|token|user|login)[^"\x27]*' /tmp/bundle.js
grep -oE 'sessionStorage\.(get|set)Item\(["\x27][^"\x27]*(auth|session|token|user|login)[^"\x27]*' /tmp/bundle.js

# Check for client-side password validation (CRITICAL vulnerability)
grep -oE 'if\s*\([^)]*===\s*["\x27][^"\x27]+["\x27]\s*\)' /tmp/bundle.js | head -10

# Find auth context/provider
grep -oE '(AuthContext|AuthProvider|useAuth|isAuthenticated|isLoggedIn)' /tmp/bundle.js

2.2 API Authentication Testing

bash
API_URL="[YOUR_API_URL]"

# Test endpoints without auth
ENDPOINTS=("users" "projects" "tasks" "items" "data" "config" "settings" "admin" "me" "profile")
for ep in "${ENDPOINTS[@]}"; do
  echo "=== /api/$ep ==="
  curl -s -w "\nHTTP: %{http_code}\n" "$API_URL/api/$ep" | tail -5
done

# Test with malformed auth
curl -s "$API_URL/api/users" -H "Authorization: Bearer null"
curl -s "$API_URL/api/users" -H "Authorization: Bearer undefined"
curl -s "$API_URL/api/users" -H "Authorization: Bearer [object Object]"
curl -s "$API_URL/api/users" -H "X-API-Key: null"
curl -s "$API_URL/api/users" -H "Cookie: session=admin"

# Test path traversal
curl -s "$API_URL/api/../../../etc/passwd"
curl -s "$API_URL/api/users/../../admin"

2.3 Authorization (Access Control)

bash
# If you can get a valid token, test accessing other users' data
# IDOR (Insecure Direct Object Reference)
curl -s "$API_URL/api/users/1" -H "Authorization: Bearer [your-token]"
curl -s "$API_URL/api/users/2" -H "Authorization: Bearer [your-token]"

# Test role escalation
curl -s "$API_URL/api/admin" -H "Authorization: Bearer [regular-user-token]"
curl -s -X PUT "$API_URL/api/users/me" -H "Authorization: Bearer [token]" \
  -d '{"role":"admin"}'

Phase 3: API Security

3.1 CRUD Access Without Auth

bash
API_URL="[YOUR_API_URL]"

# CREATE
curl -s -X POST "$API_URL/api/projects" \
  -H "Content-Type: application/json" \
  -d '{"name":"z-audit-test","test":true}'

# READ (already tested above)

# UPDATE
curl -s -X PUT "$API_URL/api/projects/1" \
  -H "Content-Type: application/json" \
  -d '{"name":"hacked"}'

# DELETE
curl -s -X DELETE "$API_URL/api/projects/1"

# If any of these succeed without auth = CRITICAL

3.2 Input Validation

bash
# SQL Injection
curl -s "$API_URL/api/users?id=1' OR '1'='1"
curl -s "$API_URL/api/users?id=1; DROP TABLE users;--"

# NoSQL Injection
curl -s -X POST "$API_URL/api/login" \
  -H "Content-Type: application/json" \
  -d '{"email":{"$gt":""},"password":{"$gt":""}}'

# XSS payloads in input
curl -s -X POST "$API_URL/api/projects" \
  -H "Content-Type: application/json" \
  -d '{"name":"<script>alert(1)</script>"}'

# Command Injection
curl -s "$API_URL/api/export?filename=test;ls"

3.3 Rate Limiting

bash
# Send 100 requests rapidly
for i in {1..100}; do
  curl -s -o /dev/null -w "%{http_code}\n" "$API_URL/api/projects" &
done
wait

# Should see 429 (Too Many Requests) eventually
# If all return 200 = no rate limiting

3.4 Error Handling

bash
# Trigger errors and check for info leakage
curl -s "$API_URL/api/projects/undefined"
curl -s "$API_URL/api/projects/null"
curl -s "$API_URL/api/projects/NaN"
curl -s -X POST "$API_URL/api/projects" -H "Content-Type: application/json" -d 'invalid-json'

# Check if stack traces are exposed
# Red flags: file paths, line numbers, package versions

Phase 4: Infrastructure-Specific Checks

4.1 Cloudflare Workers

bash
# If you have wrangler access
ACCOUNT_ID="[account-id]"
WORKER_NAME="[worker-name]"

# List secrets (names only, not values)
wrangler secret list --name $WORKER_NAME

# Check for missing critical secrets
# Should have: AUTH_SECRET, JWT_SECRET, or similar

# List KV namespaces (might contain sensitive data)
wrangler kv namespace list

# Check D1 databases
wrangler d1 list

# Download worker code for review
curl -s "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/workers/scripts/$WORKER_NAME" \
  -H "Authorization: Bearer [CF_API_TOKEN]" > worker.js

4.2 Vercel

bash
DOMAIN="[your-domain.vercel.app]"

# Check for exposed env files
curl -s "https://$DOMAIN/.env"
curl -s "https://$DOMAIN/.env.local"
curl -s "https://$DOMAIN/.env.production"

# Check for source maps
curl -s "https://$DOMAIN/_next/static/chunks/main.js.map"

# Check for exposed API routes
curl -s "https://$DOMAIN/api"
curl -s "https://$DOMAIN/api/auth"

# Check Next.js specific
curl -s "https://$DOMAIN/_next/data/[build-id]/index.json"

4.3 Supabase

bash
PROJECT_URL="https://[project-ref].supabase.co"
ANON_KEY="[anon-key-from-frontend]"

# Test anon key permissions (should be limited)
# List all tables
curl -s "$PROJECT_URL/rest/v1/" \
  -H "apikey: $ANON_KEY" \
  -H "Authorization: Bearer $ANON_KEY"

# Try to read users table
curl -s "$PROJECT_URL/rest/v1/users?select=*" \
  -H "apikey: $ANON_KEY" \
  -H "Authorization: Bearer $ANON_KEY"

# Try to read auth.users (should always fail)
curl -s "$PROJECT_URL/rest/v1/auth.users?select=*" \
  -H "apikey: $ANON_KEY"

# Check if RLS is enabled by trying to insert
curl -s -X POST "$PROJECT_URL/rest/v1/[table]" \
  -H "apikey: $ANON_KEY" \
  -H "Authorization: Bearer $ANON_KEY" \
  -H "Content-Type: application/json" \
  -d '{"test": "data"}'

# Check storage buckets
curl -s "$PROJECT_URL/storage/v1/bucket" \
  -H "apikey: $ANON_KEY" \
  -H "Authorization: Bearer $ANON_KEY"

4.4 Firebase

bash
# Check Firestore rules
# If rules are: allow read, write: if true; = CRITICAL

# Test direct database access
curl -s "https://[project].firebaseio.com/.json"

# Check storage rules
curl -s "https://firebasestorage.googleapis.com/v0/b/[project].appspot.com/o/"

Phase 5: Security Headers & CORS

5.1 Security Headers Check

bash
curl -sI "[FRONTEND_URL]" | grep -iE '^(strict-transport|content-security|x-frame|x-content-type|x-xss|referrer-policy|permissions-policy):'

# Expected headers:
# Strict-Transport-Security: max-age=31536000
# Content-Security-Policy: default-src 'self'
# X-Frame-Options: DENY
# X-Content-Type-Options: nosniff
# Referrer-Policy: strict-origin-when-cross-origin

5.2 CORS Check

bash
# Check if API allows any origin
curl -sI "$API_URL/api/projects" \
  -H "Origin: https://evil.com" | grep -i "access-control"

# If Access-Control-Allow-Origin: * = potential issue
# If it reflects back the evil origin = CRITICAL

Phase 6: Dependency Audit

6.1 NPM/Yarn

bash
# Check for known vulnerabilities
npm audit --json 2>/dev/null | jq '.metadata.vulnerabilities'

# Or with yarn
yarn audit --json 2>/dev/null | head -50

# Check for outdated packages
npm outdated

6.2 Python

bash
# Using pip-audit
pip-audit

# Or safety
safety check

Phase 7: Sensitive Data Exposure

7.1 API Response Analysis

bash
# Check what data is returned
curl -s "$API_URL/api/users" | jq 'if type == "array" then .[0] else . end | keys'

# Red flags in responses:
# - password / password_hash / hashed_password
# - credit_card / card_number
# - ssn / social_security
# - api_key / secret_key
# - internal_id that reveals info
# - created_by showing other user IDs

7.2 Error Message Analysis

bash
# Intentionally trigger errors
curl -s "$API_URL/api/users/99999999"
curl -s -X POST "$API_URL/api/users" -d '{}'

# Red flags:
# - Full stack traces
# - Database table/column names
# - File system paths
# - Package versions

Severity Classification

LevelCriteriaExamples
🔴 CRITICALImmediate exploitation, data breach possibleHardcoded passwords, no API auth, exposed secrets
🟠 HIGHSignificant risk, needs quick fixExposed API keys, missing auth on some routes, IDOR
🟡 MEDIUMShould fix soonVerbose errors, weak rate limiting, missing security headers
🟢 LOWBest practice improvementsOutdated dependencies (no known exploits), missing CSP

Report Template

markdown
# 🔐 Z-Audit Security Report

**Target:** [Project Name / URLs]
**Date:** [Date]
**Stack Detected:** [e.g., Next.js + Supabase + Cloudflare Workers]

---

## Executive Summary
[2-3 sentences: Overall posture, critical issues count, immediate actions needed]

---

## 🔴 Critical Findings

### C1: [Title]
- **Location:** [File/URL/Endpoint]
- **Issue:** [Description]
- **Impact:** [What an attacker could do]
- **Evidence:** [Screenshot/curl command/code snippet]
- **Remediation:** [How to fix]

---

## 🟠 High Findings
[Same format as Critical]

---

## 🟡 Medium Findings
[Same format]

---

## 🟢 Low Findings / Recommendations
[Same format]

---

## ✅ What's Secure
- [Positive finding 1]
- [Positive finding 2]

---

## 📋 Prioritized Action Plan
1. **Immediate (today):** [Critical fixes]
2. **This week:** [High fixes]
3. **This month:** [Medium fixes]
4. **Backlog:** [Low priority improvements]

---

## Appendix: Tools Used
- Z-Audit skill
- curl, grep, jq
- [Other tools]

Stack-Specific Fix Guides

Supabase Auth Setup

typescript
// 1. Enable RLS on all tables
ALTER TABLE your_table ENABLE ROW LEVEL SECURITY;

// 2. Create policies
CREATE POLICY "Users can only see own data" ON your_table
  FOR SELECT USING (auth.uid() = user_id);

// 3. Frontend auth
const { data: { session } } = await supabase.auth.getSession()

Better Auth Setup

typescript
// auth.ts
import { betterAuth } from 'better-auth'
 
export const auth = betterAuth({
  emailAndPassword: { enabled: true },
  socialProviders: { google: { clientId, clientSecret } }
})

// Protect API routes
app.use('/api/*', auth.middleware)

Cloudflare Workers Auth

typescript
// Add auth middleware
app.use('/api/*', async (c, next) => {
  const token = c.req.header('Authorization')?.split(' ')[1]
  if (!token) return c.json({ error: 'Unauthorized' }, 401)
  
  try {
    const payload = await verify(token, c.env.JWT_SECRET)
    c.set('user', payload)
    await next()
  } catch {
    return c.json({ error: 'Invalid token' }, 401)
  }
})

Resources