LIVE LOG · entries last verified against sources October 14, 2026 · site updated Oct 23, 2026, 9:35 AM ET
Research / security headers

The headers are set by the host: what 86 public vibe-coded apps send to your browser

By Ashe, VibeIncidents · Research · Data measured Oct 15, 2026

When a browser loads a web page, the server sends a few short instructions along with it. These are called response headers. Some of them are about security: "only talk to me over HTTPS," "don't let other sites put me in a frame," "only run scripts from these places." They don't fix bugs. They limit how much damage a bug, or a hostile page, can do. Think of them as seatbelts, not brakes.

We wanted to know how often apps built with AI coding tools ship with these seatbelts on. So on October 15, 2026 we viewed 95 publicly published apps, one at a time and at human pace: 25 built with Lovable, 25 with Bolt, 24 with Replit and 21 with v0. We recorded the security headers each page sent. 87 apps loaded and 8 did not. We later excluded one of the 87 because its robots.txt disallowed our crawler when we re-checked the results, which leaves 86.

Here is the short version:

What this is not: a list of hacked apps or vulnerable apps. A missing header is a hardening gap. It is not a breach, and nothing in this study shows that any app was compromised or exploitable. We measured only what any visitor's browser already receives. We did not log in, send attack traffic, read any data, or test any credentials.

The numbers

Missing security headers among the 86 analyzable apps, by platform:

Platform Analyzable apps Missing CSP Missing HSTS Missing X-Frame-Options / frame-ancestors Missing Referrer-Policy Missing Permissions-Policy Missing X-Content-Type-Options
Lovable 25 24 (96%) 0 (0%) 23 (92%) 0 (0%) 24 (96%) 0 (0%)
Bolt 25 24 (96%) 0 (0%) 24 (96%) 24 (96%) 24 (96%) 23 (92%)
Replit 17 17 (100%) 0 (0%) 17 (100%) 17 (100%) 17 (100%) 17 (100%)
v0 19 19 (100%) 0 (0%) 19 (100%) 19 (100%) 19 (100%) 19 (100%)
All 86 84 (98%) 0 (0%) 83 (97%) 60 (70%) 84 (98%) 59 (69%)

Grid chart showing the share of analyzable apps missing each security header, by platform. HSTS is present on every app. CSP, clickjacking protection and Permissions-Policy are missing on nearly all apps on every platform. Lovable apps send Referrer-Policy and X-Content-Type-Options by default; the other three platforms mostly do not.

Chart: share of analyzable apps whose page response did not include each header. Public, search-indexed published apps, not a random sample of all apps. 8 of 95 apps were unreachable and 1 was excluded because its robots.txt disallowed our crawler; all 9 are left out. RLS was not measured, and secret checks were out of scope. Snapshot of Oct 15, 2026.

Free to reuse: embed page and live chart.

We also checked two other things a browser can see:

Both results are good. HTTPS hygiene in this sample was clean.

The story is the defaults

Look across each row of the table and a pattern shows up. Inside each platform, nearly every app sent the same headers:

Most people who publish an app from one of these tools never touch a server configuration. Many don't know one exists. When almost every app on a platform sends the same headers, the most likely explanation is that the platform's hosting layer sets them by default and almost nobody changes them. That's a guess from the pattern, not something we confirmed with the platforms. But it's a strong pattern.

To be fair to the platforms, there's good news here too:

That's why we're framing this around defaults rather than builders. One platform change would move these numbers more than a thousand individual blog posts telling builders to "add security headers."

What each header does, in plain words

Header What it tells the browser What it helps with How bad is it to be missing?
Content-Security-Policy (CSP) "Only load scripts, styles, images and connections from these places." Limits the damage if someone manages to inject a script into the page (cross-site scripting). It's a second line of defense. Missing CSP doesn't mean the app has an injection bug. It means there's no backstop if one turns up. It's also the hardest header to get right. (MDN, Vercel)
Strict-Transport-Security (HSTS) "Always use HTTPS for this site, even if someone types http://." Stops downgrade tricks on hostile networks, like public Wi-Fi. Present on all 86 apps. (MDN)
X-Frame-Options / CSP frame-ancestors "Don't let other websites show me inside a frame" (or "only these sites may"). Clickjacking: a hostile page loads your app in an invisible frame and tricks people into clicking buttons in it. Matters most for pages with sensitive actions, like login, payments or settings. frame-ancestors is the modern version, and X-Frame-Options is the older one that browsers still honor. (MDN XFO, MDN frame-ancestors)
Referrer-Policy "When someone clicks a link off my site, share only this much about where they came from." Keeps full page addresses, which can include IDs or tokens in the URL, from leaking to other sites. Modern browsers already default to a fairly safe policy. Setting it explicitly makes the behavior predictable. (MDN)
Permissions-Policy "This page (and anything embedded in it) may or may not use the camera, microphone, location, and so on." Stops embedded third-party content from asking for powerful features the app never needs. Low risk for most apps. It's a cheap way to switch off what you don't use. (MDN)
X-Content-Type-Options: nosniff "Trust the file type I declared, and don't guess." Stops a browser from treating, say, an uploaded text file as a script. A one-line fix with almost no chance of breaking anything. (MDN)

One gotcha: these need to be real HTTP response headers. Putting X-Frame-Options in an HTML <meta> tag does nothing (MDN). A CSP can be set with a <meta http-equiv="Content-Security-Policy"> tag (MDN), but the frame-ancestors directive is not supported there (MDN).

A sensible starting set

This is a reasonable baseline for a typical single-page app. Treat it as a starting point and test it before you rely on it:

X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https://*.supabase.co wss://*.supabase.co; frame-ancestors 'self'; object-src 'none'; base-uri 'self'

Notes:

How to add these headers, platform by platform

We only used each platform's own documentation (and the docs of the host it points to). Where a platform doesn't document a way to set headers, we say so. Checked Oct 15, 2026.

Lovable (apps published to *.lovable.app or a custom domain through Lovable)

Bolt (Bolt hosting on *.bolt.host, or Netlify)

Replit deployments (*.replit.app)

[[deployment.responseHeaders]] path = "/*" name = "X-Content-Type-Options" value = "nosniff"

[[deployment.responseHeaders]] path = "/*" name = "Referrer-Policy" value = "strict-origin-when-cross-origin"

[[deployment.responseHeaders]] path = "/*" name = "Permissions-Policy" value = "camera=(), microphone=(), geolocation=()" `` Replit reserves a short list of headers you can't set, such asSet-CookieandServer. None of the six security headers are on that list. - **Apps that run a server (non-static deployments):** we didn't find a Replit platform setting for response headers on these. Your server code sets them, for example in middleware. Replit's [security checklist](https://docs.replit.com/learn/security-checklist) says to add security headers "in index.html or through your back-end." One caution: its example puts X-Frame-Options and X-Content-Type-Options in` tags, and browsers ignore X-Frame-Options there (MDN). Send them from the server as real headers.

v0 / Vercel (*.vercel.app or a custom domain on Vercel)

v0 deploys to Vercel, so Vercel's header configuration applies. Use one of these:

After any change: republish, then load your live site with your browser's developer tools open (Network tab → the page request → Response Headers) to confirm the headers are there.

Methodology

Scope caveats (please read before quoting)

What's next

This was a narrowed first pass. We'd like to run a larger, more systematic study, including a bigger sample per platform. Before we automate anything, we're asking each platform for written permission. We've also shared these aggregate numbers with Lovable, StackBlitz (Bolt), Replit and Vercel (v0) ahead of publication. As of October 23, 2026, none had sent a human reply; we'll update this piece if any of them comments or changes its defaults.

If you build on one of these platforms, the fix for most of this is a few lines of configuration. If you run one of these platforms, the fix for all of your users is one default.

If you want a quick check of what your live site sends to browsers, LockedVibe, our sister company (same owner), has a free Leak Checker that looks for secret keys and public source maps. Disclosure.

Corrections and platform responses: research@vibeincidents.com