Sample report
demo-app.example). Every key in it is fake. It shows the full, unlocked $19 Full Fix Report; a free scan shows your score, every issue count and severity, and one finding explained in full.This checks what is publicly visible. A high score is not a guarantee of security.
Security findings
Exposed Stripe live secret/restricted key
A Stripe live secret/restricted key is visible in code that every visitor downloads. Anyone can copy it and use it as you: run up charges, read data, or act on your account. Treat it as compromised.
How to fix
- Rotate (revoke and re-create) the exposed key in the provider's dashboard FIRST. Removing it from code does not un-leak it.
- Move the call to a server-side function using an environment variable.
- Redeploy and re-scan.
Paste into Lovable chat: My app leaks a Stripe secret key in front-end JavaScript that ships to the browser. Fix it: 1. Find every place the Stripe secret key is used in client-side code and remove it. 2. Move the calls that need it into a server-side function (API route / edge function / Supabase Edge Function) that reads it from an environment variable named STRIPE_SECRET_KEY. 3. Have the front end call that server function instead. Never expose STRIPE_SECRET_KEY via VITE_, NEXT_PUBLIC_ or similar public prefixes. 4. Make sure .env files are in .gitignore and are not deployed as static files. 5. Show me the list of files you changed.
Exposed OpenAI API key
A OpenAI API key is visible in code that every visitor downloads. Anyone can copy it and use it as you: run up charges, read data, or act on your account. Treat it as compromised.
How to fix
- Rotate (revoke and re-create) the exposed key in the provider's dashboard FIRST. Removing it from code does not un-leak it.
- Move the call to a server-side function using an environment variable.
- Redeploy and re-scan.
Paste into Lovable chat: My app leaks a OpenAI API key in front-end JavaScript that ships to the browser. Fix it: 1. Find every place the OpenAI API key is used in client-side code and remove it. 2. Move the calls that need it into a server-side function (API route / edge function / Supabase Edge Function) that reads it from an environment variable named OPENAI_API_KEY. 3. Have the front end call that server function instead. Never expose OPENAI_API_KEY via VITE_, NEXT_PUBLIC_ or similar public prefixes. 4. Make sure .env files are in .gitignore and are not deployed as static files. 5. Show me the list of files you changed.
Exposed Supabase service_role key
A Supabase service_role key is shipped to every visitor's browser. This key bypasses Row Level Security: anyone who opens your site can read, change or delete every row in your database.
How to fix
- In Supabase → Project Settings → API, roll (regenerate) the service_role / JWT secret now. Assume your data may have been read or changed.
- Use only the anon/publishable key in the browser. Keep service_role in server-side code only.
- Turn on Row Level Security for every table and add policies (see the prompt).
- Check Supabase logs for unexpected access.
Paste into Lovable chat: My app ships the Supabase service_role key to the browser. This bypasses Row Level Security. Fix it: 1. Remove every use of the service_role key from client-side code. The browser client must use only the anon (publishable) key. 2. Move any admin operations that truly need service_role into a server-side function (Supabase Edge Function or API route) that reads SUPABASE_SERVICE_ROLE_KEY from environment variables. 3. Enable Row Level Security on every table and write policies so users can only read/write their own rows (e.g. auth.uid() = user_id). 4. List the files you changed and the SQL you ran.
Exposed GitHub token
A GitHub token is visible in code that every visitor downloads. Anyone can copy it and use it as you: run up charges, read data, or act on your account. Treat it as compromised.
How to fix
- Rotate (revoke and re-create) the exposed key in the provider's dashboard FIRST. Removing it from code does not un-leak it.
- Move the call to a server-side function using an environment variable.
- Redeploy and re-scan.
Paste into Lovable chat: My app leaks a GitHub token in front-end JavaScript that ships to the browser. Fix it: 1. Find every place the GitHub token is used in client-side code and remove it. 2. Move the calls that need it into a server-side function (API route / edge function / Supabase Edge Function) that reads it from an environment variable named GITHUB_TOKEN. 3. Have the front end call that server function instead. Never expose GITHUB_TOKEN via VITE_, NEXT_PUBLIC_ or similar public prefixes. 4. Make sure .env files are in .gitignore and are not deployed as static files. 5. Show me the list of files you changed.
Environment file /.env is publicly downloadable
Your environment file (where API keys and database passwords live) can be downloaded by anyone. Assume every value in it is compromised.
How to fix
- Rotate (revoke and re-create) the exposed key in the provider's dashboard FIRST. Removing it from code does not un-leak it. Do this for EVERY key in the file.
- Block dotfiles from being served and remove .env from your public/static folder.
- Redeploy, then re-scan.
Paste into Lovable chat: My .env file is publicly downloadable from my deployed site. Fix it: 1. Make sure no .env* file is inside the public/static/build output folder. 2. Add .env* to .gitignore and to any deploy ignore file. 3. Add a rule so the host never serves dotfiles (paths starting with /.). 4. Use the hosting provider's environment variable settings instead of a committed .env file. Show me what you changed.
Git repository metadata is publicly downloadable (/.git/config)
Your .git folder is public. Attackers can often rebuild your full source code and history from it, including any secrets ever committed.
How to fix
- Block /.git from being served by your host.
- Assume your source and history are public. Rotate any secret ever committed.
- Deploy only the build output, not the repository folder.
Paste into Lovable chat: My deployed site serves the /.git folder. Change the deploy so only the build output directory is published (not the repo root), and add a server/host rule that returns 404 for any path starting with /.git. Explain how to confirm the fix.
Git repository metadata is publicly downloadable (/.git/HEAD)
Your .git folder is public. Attackers can often rebuild your full source code and history from it, including any secrets ever committed.
How to fix
- Block /.git from being served by your host.
- Assume your source and history are public. Rotate any secret ever committed.
- Deploy only the build output, not the repository folder.
Paste into Lovable chat: My deployed site serves the /.git folder. Change the deploy so only the build output directory is published (not the repo root), and add a server/host rule that returns 404 for any path starting with /.git. Explain how to confirm the fix.
Your site is served over plain http://
Everything (including logins) travels unencrypted. Turn on HTTPS.
How to fix
- Enable 'Always use HTTPS' / force-HTTPS in your host or CDN settings, and add HSTS.
Paste into Lovable chat: Make my site always redirect http:// to https:// (permanent 308/301) and add a Strict-Transport-Security header. Use my hosting platform's settings or config file.
Source maps are public (your original source code is downloadable)
Source maps let anyone read your original, readable source code. It makes finding other weaknesses much easier.
How to fix
- Disable production source maps or upload them privately to your error tracker.
Paste into Lovable chat: Turn off public source maps in my production build (e.g. Vite build.sourcemap = false, or Next.js productionBrowserSourceMaps = false). If I use an error tracker, configure hidden source maps uploaded privately instead.
Missing 4 recommended security headers
Security headers tell browsers to block common attacks (forced downgrade to HTTP, clickjacking, script injection). They are free to add and take a few lines of config.
How to fix
- Add the missing headers in your host's config (vercel.json headers, netlify _headers, next.config headers…).
- Start CSP in Report-Only mode if you're unsure, then tighten.
Paste into Lovable chat: Add these security response headers to every page of my deployed site: Content-Security-Policy; X-Frame-Options or CSP frame-ancestors (clickjacking); X-Content-Type-Options: nosniff; Referrer-Policy. Use my hosting platform's config file. For Content-Security-Policy, start with a policy that allows my own scripts and the third-party services I actually use, and explain each directive. Show me the final config.
Cookies missing Secure / HttpOnly / SameSite flags
Cookies without these flags are easier to steal or misuse. Session cookies especially should have all three.
How to fix
- Set Secure, HttpOnly and SameSite=Lax (or Strict) on session cookies.
Paste into Lovable chat: Find where my app sets cookies and make session/auth cookies Secure, HttpOnly and SameSite=Lax. Tell me which cookies must stay readable by JavaScript and why.
Supabase backend detected
Your app talks to Supabase from the browser. That's normal, but it means Row Level Security must be on for every table. Verify you own this site to run our read-only database exposure check (Pro).
How to fix
- Confirm RLS is enabled on every table (Supabase → Table Editor shows 'RLS disabled' warnings).
- Verify site ownership in SniffPup and run the Pro deep check.
Paste into Lovable chat: List every table in my Supabase project, tell me which ones have Row Level Security disabled, and write RLS policies so users can only access their own rows. Give me the SQL to run.
Can Google & ChatGPT see you? free
| Words in the raw HTML a browser gets | 0 |
| Words GPTBot (ChatGPT's crawler) receives | 0 |
| Verdict | ❌ Mostly empty without JavaScript |
| <title> / meta description / <h1> | ✅ / ❌ / ❌ |
| llms.txt | Not found |
| AI crawlers blocked by robots.txt | GPTBot |
We don't run JavaScript for this check. That's the point: most AI crawlers don't either.
Google and AI assistants likely see an almost empty page
Your page's text is built by JavaScript in the browser. AI crawlers (GPTBot, ClaudeBot, PerplexityBot) don't run JavaScript, and Google does so late, so they mostly see an empty shell. ChatGPT can't recommend what it can't read.
How to fix
- Serve real HTML for public pages: enable SSR/SSG (Next.js, Astro, Remix) or a prerender service for bots.
- Check with 'View Source', not DevTools. Your headline and copy must be in the raw HTML.
- Add an /llms.txt and JSON-LD structured data.
Paste into Lovable chat: My public pages are client-side rendered, so Google and AI crawlers (GPTBot, ClaudeBot, PerplexityBot, which don't run JavaScript) see an empty page. Make the marketing pages (home, pricing, features, blog) render their text into the initial HTML using static generation or server-side rendering, keeping the app part as-is. Also add a <title>, meta description, one <h1>, JSON-LD for my organization/product, a sitemap.xml and an /llms.txt. Then show me how to verify with curl.
Missing search basics: meta description, <h1> in raw HTML
Search engines and AI assistants use these to understand and describe your page.
How to fix
- Add a unique <title>, a meta description and one <h1> to each public page (in the raw HTML).
Paste into Lovable chat: Add these SEO basics to my public pages, rendered in the initial HTML: Missing meta description; Missing <h1> in raw HTML. Write them based on what each page is about.
robots.txt blocks 1 AI crawler
That's fine if intentional. If you want ChatGPT, Claude or Perplexity to recommend you, allow their crawlers.
How to fix
- If you want AI assistants to recommend you, remove the Disallow rules for their user agents in robots.txt.
Paste into Lovable chat: Update my robots.txt to allow GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot and PerplexityBot on public marketing pages while still blocking private/app routes. Show the final file.