Website Security Scan: What It Checks and How to Run One Free
A real website security scan covers TLS, headers, exposed files, shipped secrets, and missing Row Level Security. See what it checks and run one free.
You paste your URL into a free tool, it flashes a green padlock and a letter grade, and you close the tab feeling better. That's the version of a website security scan most people run: check the certificate, check a malware blocklist, confirm the site isn't a phishing page. It still matters, but if your app was built with an AI coding tool (Lovable, Bolt, Replit, Cursor, v0, or similar), it answers a smaller question than the one you need answered. The place these apps most often leak data is a layer a certificate check never touches: whether your backend restricts who can read what.
This post covers what a real website security scan checks, from the shallow layer to the deep one, then how to run one on your own site for free.
⚡ TL;DR
- A real website security scan has five layers: TLS/SSL, response headers, reachable sensitive files, shipped source maps and secrets, and (deepest) whether your backend's data-access rules restrict who sees what.
- Most free "is this site safe" tools stop at layer one. That catches phishing and expired certificates, not data leaks.
- Missing Row Level Security (RLS) is the highest-impact gap in apps built with AI, and it's invisible to a padlock check.
- You can scan the public-facing layers of your own app for free, no login and no code to read.
What a website security scan actually checks
A website security scan is a read-only look at what your app exposes to the public internet: TLS setup, HTTP responses, public files, shipped JavaScript, and, at the deepest level, how your backend responds to requests it should refuse. None of it requires logging in or touching your database. It's information your site is already handing out to anyone who asks, including an attacker.
1. TLS/SSL configuration
This is the padlock. A scan confirms your certificate is valid, not expired, issued for the right domain, and that your server isn't accepting old, broken protocol versions. It's table stakes: without it, traffic could be intercepted. But a valid certificate says nothing about whether your app leaks data to a user who's authenticated correctly and changes a number in the URL.
2. Security response headers
Every response includes headers, and several exist specifically to block classes of attack: a Content Security Policy (CSP), which limits what scripts can run on your page; X-Frame-Options, which stops your site being embedded in an invisible frame on someone else's page (clickjacking); and X-Content-Type-Options, which stops the browser guessing a file's type in a way attackers can abuse. Missing headers won't compromise your site today, but they remove a free layer of defense.
3. Reachable sensitive files
AI coding tools generate a lot of scaffolding, and some of it shouldn't be public. A scan checks whether paths like /.env (environment variables, sometimes database credentials), /.git (your commit history), or config.json are reachable by URL. Nobody clicks onto these by accident, but an automated scan checks these exact paths in seconds.
4. Shipped source maps and secrets in JS bundles
Your production JavaScript bundle is public by definition; every visitor's browser downloads it. A scan checks whether source maps (.map files) ship alongside it, handing an attacker a readable copy of your source, and whether the bundle contains secret keys hardcoded in by mistake. This is where the false alarms live, too: a Supabase anon key or Firebase web config in your JS bundle is normal, both public by design. What matters is a Stripe secret key (sk_live_), a Supabase service_role key, or a raw OpenAI or AWS key, credentials that should never leave your backend.
🐺 Not a real problem
If a scan result shows your Supabase anon key or Firebase
apiKey, that's not a leak. Those keys are meant to be public. The real question is what's standing behind them, which is layer 5.
5. The layer most scanners miss: your backend's data-access rules
This is the deepest layer, the one a padlock-and-grade tool never reaches, because it's whether your backend enforces who can read what once a request arrives with valid but unprivileged credentials.
For an app built on Supabase, that control is Row Level Security (RLS): per-table policies filtering every query down to the rows a given user may see. If RLS is off, or a policy reads USING (true) ("let everyone through"), anyone holding the public anon key, already sitting in every visitor's browser, can query that table directly and pull every user's data. Not a hypothetical: CVE-2025-48757, disclosed May 2025, found this exact pattern in 170 of 1,645 scanned Lovable and Supabase apps (10.3%), leaking data through 303 endpoints via nothing more than the anon key. It was the first published CVE for this category, and the pattern has recurred since. See our guide to Supabase security for AI-built apps and how to check whether your Supabase project is exposed.
Shallow scan versus real scan: what "SSL grade" actually tells you
A tool that only checks TLS and cross-references a malware or phishing blocklist answers "is this a scam site," useful for a stranger deciding whether to trust a site they've never visited. That's a different question from "does my app leak data." A site can score a perfect SSL grade and sit on zero blocklists while still handing out every user's private records, because RLS was never turned on. The certificate and blocklist checks are static; catching a leak means probing the live app, the distinction between static analysis (reading source before it ships) and dynamic analysis. A website security scan is the dynamic kind. See DAST vs SAST for AI-generated apps for the comparison.
How to run a website security scan of your own site
You don't need to install anything or hand over credentials to get a first read on your own app.
- Check TLS. Click the padlock icon in the address bar and confirm the certificate is valid and matches your domain.
- Check headers. Open dev tools, Network tab, click your main document request, and look for
Content-Security-Policy,X-Frame-Options, andX-Content-Type-Options. - Try the sensitive paths. Type
yoursite.com/.envandyoursite.com/.git/configinto your address bar. Either should return a 404, never a file. - Search your JS bundle. In dev tools, Sources tab, open your main bundle, and search for
sk_live_,service_role, and any AI provider key pattern. Check for.mapfiles alongside it. - Test your own data access. Log in, open a page showing your own record with an ID in the URL, and change that ID to one that isn't yours. If someone else's data loads, that's a real gap regardless of any header or certificate check.
Steps 1 and 2 take under a minute each. Steps 3 through 5 take longer to do thoroughly by hand, and step 5 is easy to under-test since it needs checking against every endpoint that takes an ID.
Want the 60-second version instead?
Paste your link and get a free, read-only report of what an attacker sees on your live site. No login, no install, no code to read.
Scan my site free →What a real scan catches (and doesn't cry wolf about)
We validated this approach against a deliberately vulnerable test app with 21 planted flaws (secrets fake but format-valid) covering the five layers above, scored against that answer key. It caught 19 of the 20 flaws that were actually catchable (one, missing HSTS, was already added by the host, leaving 20 live to find). All four dangerous secret keys, Stripe sk_live_, OpenAI, AWS, and Supabase service_role, were flagged critical. The two public-by-design keys, the anon key and Firebase web config, were correctly held at info. Reachable /.env, /.git, and config.json were caught, along with missing CSP, X-Frame-Options, and X-Content-Type-Options, an open CORS rule, and shipped source maps.
The single miss was broken access control: an endpoint returning any customer's order record to any logged-in caller, regardless of whose order it was. That flaw class, IDOR (Insecure Direct Object Reference), is hard for a passive scan to catch since confirming it needs judgment about intent, not a pattern match. After reworking how a deeper, domain-verified active check reasons about unauthenticated data access, it caught that same IDOR on all six re-runs, while still holding the anon key at info. That brought the validated result to 20 of 20 catchable flaws.
This false-positive discipline matters as much as the catches; a scanner that flags every anon key as critical trains you to ignore its output. And it applies more, not less, to an app that came from an AI tool rather than a hand-coded backend; see are vibe-coded apps secure for the research behind that.
FAQ
Is a free website security scan actually useful, or only a lead magnet?
Both can be true. A scan that only checks TLS and a blocklist tells you something real, but not much for an app with user data behind a login. Look for one that also checks headers, reachable config files, shipped secrets, and whether your data-access rules are restrictive.
How is a website security scan different from a website vulnerability scanner?
In practice the terms overlap. "Security scan" tends to mean the lighter check; "vulnerability scanner" tends to mean the full five-layer version above. When comparing tools, ask what layers they cover rather than trust the name.
Will a website security scan flag my Supabase anon key or Firebase config as a problem?
A well-built one won't treat their mere presence as a critical finding, since both are meant to be public. A scan that flags them without checking what's enforced behind them is producing noise, not a finding; the thing worth checking is RLS or Security Rules, not the key.
How often should I run a website security scan?
Every deploy that touches auth, data access, or file uploads is worth a re-check. An app under active AI-assisted development needs this as a habit, not a one-time launch check.
The bottom line
A website security scan worth trusting checks five layers, not one: TLS, response headers, reachable files, shipped secrets, and, deepest and most often skipped, whether your backend's data-access rules restrict who sees what. That last layer is where apps built with AI tools tend to fail quietly, invisible to anything that only checks the padlock. An attacker can run this exact check in minutes. The only real defense is running it yourself first, and again on every deploy that touches user data.
Is your site hackable? Find out in 60 seconds.
Is My Site Hackable? scans your live app for the exact gaps in this article (exposed keys, missing RLS, open buckets) and tells you what's a real risk and what's a false alarm. Paste your link, get a free report. No login, no install.
Run my free scan →