Fix guides
Every issue Unspill reports links here. Each guide explains the risk, gives step-by-step fixes and a prompt you can paste into your AI builder.
Leaked secrets
A Supabase service_role (or sb_secret_) key in front-end code gives anyone full read/write access to your database, bypassing Row Level Security. Here is how to rotate it and fix the leak.
Stripe secret key exposedA Stripe sk_live_ or sk_test_ key in your JavaScript lets anyone create charges, issue refunds and read your customers. Roll the key in the Stripe Dashboard and move payments server-side.
AI API key exposedAn OpenAI, Anthropic, Groq, OpenRouter or xAI key in your front-end bundle lets anyone run up your bill. Revoke it and proxy AI calls through a server function with rate limits.
AWS access key exposedAn AWS access key ID in your JavaScript usually ships with its secret. Deactivate it in IAM, check CloudTrail, and use presigned URLs or a server function instead.
Private key or Firebase admin credentials exposedA private key or Google service-account JSON in browser code gives admin access to Firebase/Google Cloud. Delete the key in Google Cloud IAM and use the Admin SDK only on a server.
Third-party token exposedService tokens in front-end code (GitHub, Slack, SendGrid, Resend, Twilio) can be used by anyone to act as your account. Revoke them and move the calls server-side.
Possible hard-coded secretVariables named secret, token, password or apiKey with long random values in front-end code are often real credentials. Check each one, rotate real secrets, and keep them server-side.
Google API key in client codeAIza keys in front-end code are fine for Firebase but dangerous for Gemini or paid Maps APIs. Restrict them by HTTP referrer and API in Google Cloud Console.
Database & backend
Your Supabase anon key is public by design, so Row Level Security is the only thing protecting your tables. Run these SQL checks to find tables with RLS off or policies that let anyone read everything.
Verify Firebase Security RulesYour Firebase web config is public by design, so Firestore, Realtime Database and Storage rules are the only protection for user data. Here's how to check them.
Permissive CORSIf your API reflects any Origin or allows * with credentials, any website can read your users' data through their browser. Restrict CORS to your own domains.
Exposed files
If https://yourapp.com/.env downloads your environment file, every secret in it is public. Remove it from the deployed output, block dotfiles, and rotate every key.
Exposed .git directoryA public /.git/config means attackers can often download your full source and commit history, including old secrets. Block /.git and rotate anything ever committed.
Public source mapsProduction .map files let anyone rebuild your original front-end code, comments and internal routes. Disable them in Vite or Next.js, or upload them privately to your error tracker.
Browser hardening
Serving an app over plain HTTP exposes logins, cookies and data to anyone on the network. Enable HTTPS and redirect all HTTP traffic.
HSTSHSTS tells browsers to always use HTTPS for your domain, preventing downgrade attacks on public Wi-Fi. Add one header in vercel.json, _headers or next.config.js.
Content-Security-PolicyA Content-Security-Policy limits which scripts can run on your site, reducing the damage of XSS. Copy-paste CSP examples for Vercel, Netlify and Next.js apps using Supabase.
Clickjacking protectionIf any site can load your app in an iframe, attackers can trick users into clicking buttons they can't see. Add X-Frame-Options: DENY or CSP frame-ancestors 'none'.
Mixed contentLoading scripts, styles or images over http:// on an HTTPS page breaks the padlock and lets attackers tamper with them. Switch every URL to https://.
Cookie flagsSession cookies without Secure and HttpOnly can be stolen by scripts or sent over HTTP. Set Secure, HttpOnly and SameSite on auth cookies.
X-Content-Type-OptionsThe nosniff header stops browsers from guessing file types, preventing some upload-based attacks. It's a one-line fix.
Referrer-PolicyWithout a Referrer-Policy, full URLs (which can contain tokens or IDs) may be sent to third-party sites. Set strict-origin-when-cross-origin.
Permissions-PolicyA Permissions-Policy header disables browser features (camera, microphone, geolocation) your app doesn't use, limiting what injected scripts can do.