{ "summary": { "mode": "files", "files_scanned": 2, "high": 2, "medium": 3, "low": 1 }, "findings": [ { "severity": "high", "rule": "env-file-not-ignored", "file": ".env.local", "line": 0, "message": "This env file is not in .gitignore, so the next `git add .` commits it.", "fix": "Add .env* (and !.env.example) to .gitignore." }, { "severity": "high", "rule": "public-env-secret", "target": "NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY", "file": ".env.local", "line": 2, "message": "NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY is bundled into the browser (the NEXT_PUBLIC_ prefix does that). Anyone can read it in the page source.", "fix": "Rename to SUPABASE_SERVICE_ROLE_KEY (no NEXT_PUBLIC_ prefix), read it only in server code, and rotate it if it was ever deployed." }, { "severity": "medium", "rule": "env-value", "target": "STRIPE_SECRET_KEY", "file": ".env.local", "line": 3, "hint": "fake-... (21 chars)", "message": "STRIPE_SECRET_KEY has a value in an env file git will pick up.", "fix": "Keep real values only in ignored files (.env.local) and in your host's env settings." }, { "severity": "medium", "rule": "no-gitignore", "file": ".gitignore", "line": 0, "message": "No .gitignore with rules. Env files, build output, and node_modules can all end up committed.", "fix": "Create .gitignore with at least: .env*, !.env.example, node_modules, .next, .vercel" }, { "severity": "medium", "rule": "hardcoded-secret", "target": "adminPassword", "file": "app/api/pay.ts", "line": 2, "hint": "let... (12 chars)", "message": "adminPassword is set to a hardcoded value in code.", "fix": "Read it from an env var instead, for example process.env.ADMIN_PASSWORD." }, { "severity": "low", "rule": "stripe-test-key", "file": "app/api/pay.ts", "line": 1, "hint": "sk_tes... (34 chars)", "message": "Found a Stripe test secret key. It cannot move real money, but keys belong in env vars, not code.", "fix": "Move it to an env var, then rotate it in the provider's dashboard. Assume a committed key is already copied." } ] }