Skip to content
ShipSafeStack

Free check

Is your AI-built app leaking? Find out in 10 seconds.

A free website security check for AI-built and vibe-coded apps. Passive checks only. Nothing is stored.

Informational only. Passive public checks, not a security audit, no guarantees. ShipSafeStack.

Only scan sites you own or have permission to check. Nothing you submit is stored.

Loading the check…

What the free check looks at

This is a free website security check for AI-built and vibe-coded apps, and for any other public URL. It sends ordinary GETs, the way a browser would load the page. It does not log in, post a form, or change anything on the site. Informational only. Passive public checks, not a security audit, no guarantees. ShipSafeStack.

  • HTTPS

    The check loads the URL you typed, then requests the same host over plain HTTP. It records whether the page stayed on HTTPS and whether HTTP redirected there.

    A page that stays on HTTP, or an HTTP URL that never redirects, sends the app in the clear. AI builders often ship the preview on HTTPS and leave the HTTP address open.

    Pre-launch checklist
  • Strict-Transport-Security

    It reads the Strict-Transport-Security header on the HTTPS response and looks for a max-age greater than zero.

    HSTS tells the browser to keep using HTTPS on later visits. Without it, a later visit can still start on HTTP.

    Pre-launch checklist
  • Content-Security-Policy

    It checks that a Content-Security-Policy header is present. It does not grade how strict the policy is.

    A policy is one of the controls that limits which scripts and frames a page will load. A missing header is a gap. A present header is not proof the policy is tight.

    Pre-launch checklist
  • Framing

    It looks for X-Frame-Options set to DENY or SAMEORIGIN, or a Content-Security-Policy frame-ancestors directive.

    Without one of those, another site can put your page in a frame. That is the setup clickjacking uses.

    Pre-launch checklist
  • X-Content-Type-Options

    It looks for the nosniff value on X-Content-Type-Options.

    nosniff tells the browser not to guess a content type. A stylesheet or script served with the wrong type is less likely to be executed as something else.

    Pre-launch checklist
  • Referrer-Policy

    It checks that a Referrer-Policy header is present. It does not require a particular policy.

    The referrer can carry the full URL, including query tokens, to the next site. A policy is how you limit that.

    Pre-launch checklist
  • Permissions-Policy

    It checks that a Permissions-Policy header, or the older Feature-Policy header, is present.

    The header is where a page turns off camera, microphone, and other powerful features it does not use.

    Pre-launch checklist
  • Exposed files

    It requests a short list of common paths: /.env, /.env.local, /.git/config, /.git/HEAD, /.DS_Store, /config.json, and /backup.zip. A path counts only when the response is HTTP 200 and the body matches that kind of file. The check never prints the file.

    A public .env or git directory is the app's secrets and history, not a missing header. Builders sometimes deploy the project folder as the site root.

    API keys in the frontend
  • Keys in public scripts

    It reads the homepage HTML and up to about ten same-origin scripts that page loads. It looks for secret-shaped strings, including a Stripe secret key, a Supabase service-role JWT, and a private key block. A hit is shown as the first four characters and a mask, never the full value.

    Anything in the script the browser downloads can be copied. A key next to a fetch is a common shortcut in generated code.

    API keys in the frontend
  • Supabase anon key

    If a JWT in those public scripts has the role anon, the check reports it as information. It does not treat that key as a failure by itself.

    Supabase documents the anon key as a client key when row level security is on. The check cannot see whether those policies exist.

    Is the Supabase anon key safe to expose?
  • Source maps

    It looks for a sourceMappingURL in the scripts it fetched, and requests a same-origin .map file. An embedded map, or a map that returns source-map JSON, is a warning.

    A public source map can include the original source, comments, and env names that were never meant for the browser.

    Pre-launch checklist
  • Rate limiting

    This pass does not send a burst of requests. The row stays at couldn't check.

    A public form or API with no limit is an abuse problem. The check cannot measure it without becoming that abuse.

    Rate limiting
  • Stripe webhook verification

    This pass does not send a webhook. The row stays at couldn't check.

    A handler that trusts the JSON body without the Stripe signature can be called by anyone who can reach the URL.

    Stripe webhooks

What the check cannot see

A pass on the rows above is not a clean bill of health. These are the gaps that matter on an app a builder generated.

Example result

Example only. These rows were written by hand so you can see the layout. They are not a scan of example.com, and they are not a result for any product. Nothing here was stored.

Illustration URL: https://example.com

Informational only. Passive public checks, not a security audit, no guarantees. ShipSafeStack.

  • Pass

    HTTPS

    Sample: the illustration URL is already https.

    Next step
  • Warn

    Strict-Transport-Security

    Sample: no HSTS max-age on this illustration.

    How to fix
  • Warn

    Content-Security-Policy

    Sample: no Content-Security-Policy header in this illustration.

    How to fix
  • Pass

    Exposed files

    Sample: the illustration paths did not match an env file or a git file.

    Next step
  • Fail

    Keys in public scripts

    Sample: a made-up key shape, sk_l****, in a script the illustration page loads. This is not a real key.

    How to fix
  • Info

    Supabase anon key

    Sample: Info: anon key present, make sure RLS is on (eyJh****).

    How to fix
  • Couldn't check

    Rate limiting

    Sample: this pass does not send repeated requests.

    How to fix

FAQ

Is the free website security check an audit?
No. It is a passive look at a public URL: the page, a few response headers, a short list of common files, and scripts the homepage loads. It is not a penetration test, a certification, or a guarantee. A quiet result means these particular checks did not flag a row. It does not mean the app is free of problems.
What does the check look at on an AI-built or vibe-coded app?
The same things it looks at on any public URL. Generated apps often ship a key in the client bundle, a missing security header, or a project file such as .env at the site root. The check looks for those on the public page. It does not log into the builder, and it does not read the builder's dashboard.
What can the check not see?
It cannot see row level security, database grants, server-side code, or secrets that never appear in the public page. It does not send a Stripe webhook or a burst of requests, so those two rows stay at couldn't check. A private GitHub token that was pasted into a chat is also outside this check.
Do you store the URL or the result?
No. The check runs when you submit the form, returns the rows, and does not keep the URL or the result. A link you copy is only the URL you typed, placed on /scan so the same check can run again in the browser.
Can I check a site I do not own?
Only scan sites you own or have permission to check. The requests are ordinary public GETs, and they are still requests against someone else's server.