vibecoder-review.md A developer has created a practical OWASP-focused security review skill for fast-moving codebases built with AI assistance. The skill targets common vulnerabilities in AI-generated code, such as exposed secrets, authentication bypasses, and missing access controls, and is intended for initial security triage of unfamiliar codebases and rapid prototypes. | name | vibecoder-review | |---|---| | description | Practical OWASP-focused security review for fast-moving codebases built with AI assistance - catches common patterns where speed trumps security exposed secrets, auth bypasses, missing access controls, injection vulnerabilities | Target audience: Fast-moving codebases built by developers using AI assistance, rapid prototyping tools, and modern frameworks. These projects prioritize speed and iteration, often skipping security fundamentals. Philosophy: Assume the codebase was built with AI tools. Look for patterns where convenience beats security. Focus on vulnerabilities that are common in AI-assisted development. Use this skill for: - Initial security triage of unfamiliar codebases - Reviewing AI-generated or rapidly prototyped applications - Finding low-hanging security fruit before deep analysis - Assessing startups, MVPs, and "vibecoded" projects - Quick security health check 1-2 hours Don't use for: - Mature, security-focused codebases - Deep vulnerability validation - Formal audit reports - Complex cryptographic analysis Goal: Find credentials anyone with repo/bundle access can steal Where to look: Search patterns grep -r "api key\|API KEY\|secret\|SECRET\|password\|PASSWORD\|token\|TOKEN" --include=" .{js,ts,py,java,go,rb,php,env ,yml,yaml,json,config}" Common files .env .env.local config/ .{yml,yaml,json} src/config/ /constants.{js,ts,py} Check for: - Hardcoded API keys Stripe, OpenAI, AWS, database URLs - Database credentials in source code - JWT secrets, session keys, encryption keys - OAuth client secrets - Credentials in comments "// TODO: remove test key" - Secrets in frontend code or bundled in client builds - Credentials in test fixtures that work in production Red flags: js // BAD: Frontend bundle exposure const OPENAI API KEY = "sk-proj-abc123..."; const supabase = createClient URL, "eyJhbGci..." ; // BAD: Hardcoded in backend DATABASE URL = "postgresql://admin:password123@db.prod.com/app" What to flag: - Any plaintext credential committed to repo - Frontend code with API keys/secrets - Config files with production credentials - Comment out test credentials that actually work Proper handling: - Environment variables process.env, os.getenv - Secret managers AWS Secrets Manager, HashiCorp Vault - CI/CD secret injection - .env.example with placeholders no real values Goal: Find paths to log in as someone else or escalate to admin Where to look: Authentication code grep -r "login\|signup\|authenticate\|session\|jwt\|token\|oauth" --include=" .{js,ts,py,java,go,rb,php}" Authorization checks grep -r "is admin\|isAdmin\|role\|permission\|can\|authorize" --include=" .{js,ts,py,java,go,rb,php}" Session handling grep -r "cookie\|session\|localStorage\|sessionStorage" --include=" .{js,ts,py}" Check for: - User identity from URL params: /api/user?userId=123 - Role/admin status from request body without verification - Client-side auth checks only no server-side validation - Trust in JWT claims without signature verification - Non-expiring tokens or magic links - Session cookies without secure flags - Missing authentication on admin routes - Password reset flows with predictable tokens Anti-patterns: js // BAD: Trust client-provided user ID app.get '/api/profile', req, res = { const userId = req.query.userId; // Attacker controls this const profile = db.getProfile userId ; return res.json profile ; } ; // BAD: Trust client-provided role app.post '/api/admin/users', req, res = { if req.body.isAdmin === true { // Attacker sets this // Admin operations } } ; // BAD: Client-side only auth check function AdminPanel { const { user } = useAuth ; if user.role == 'admin' return null; // Only checked in UI return