No Content-Security-Policy header
Without a CSP, any injected or compromised third-party script runs with full access to your page — the classic XSS / supply-chain hole.
“Every script on the page is on the guest list right now.”
Content-Security-Policy header, starting strict and loosening only as needed:Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'
Content-Security-Policy-Report-Only first, watch the reports, then enforce.No clickjacking protection (frame-ancestors / X-Frame-Options)
The page can be embedded in an <iframe> on any site, which enables clickjacking — an attacker overlays your UI and tricks users into clicking things they cannot see.
“Your app can be reframed on any site. Literally.”
Prefer a CSP directive (also covers modern browsers):
Content-Security-Policy: frame-ancestors 'self'
Or the legacy header if you have no CSP yet:
X-Frame-Options: SAMEORIGIN
HTTPS everywhere
The site is served over HTTPS.
“The bar is on the floor, but you cleared it.”
Closed beta · coming next
This grade reads what a browser can download. The deep scan goes where the leaks actually live — your repo’s secret history, your Supabase access rules, your dependency tree, and your Next/Vercel config. The checks that need to understand the stack, not just the page.
Deep mode only ever runs on apps you prove you own — a DNS record or a file on your domain. It scans what you asked it to, nothing else.