The files you forgot you deployed

Your Next.js or Cloudflare Pages build output is leaking secrets it was never meant to serve

The exposed-file classics, .env, .git, backup.sql, are old problems with old fixes. The modern front-end stack invented new ones. When you build a Next.js app or deploy to Cloudflare Pages, the build process writes a set of internal manifest and map files that were never meant to be public. On a correct deploy they aren't. But a mis-configured serve directory, a wrong adapter, or a default that bites, and these internal files become downloadable, each one leaking something the framework assumed only the server would ever read.

These are the leaks the scanner catches that a 2015-era checklist wouldn't even know to look for. They're gated tightly, on the framework-internal markers and real secret payloads, because the whole point is that a correctly deployed app doesn't serve them, so a hit means something genuinely went wrong.

.next manifests: your env block and a cookie-forging key

Next.js writes two manifest files during a build that are pure internal plumbing. /.next/required-server-files.json carries the fully resolved next.config, and that includes the inlined env: {} block, every server-side environment variable the build baked in. /.next/prerender-manifest.json carries the previewModeSigningKey and EncryptionKey, the 64-hex secrets Next uses to sign and encrypt the preview-mode bypass cookie.

Neither is meant to be web-reachable. The .next/ directory with the leading dot is a build artifact directory; a normal Next.js URL never touches it. So when these 200, it's because a deploy mis-served the build directory itself, pointed the web root at the wrong folder, copied .next into something served statically. And when they do, the damage is real: the env block is your server config, and the preview signing key lets anyone forge the signed-and-encrypted cookie that bypasses your published pages and renders draft/preview content on demand.

request
GET /.next/prerender-manifest.json HTTP/1.1 Host: yoursite.com
response
HTTP/1.1 200 OK
Content-Type: application/json
{ "version": 4,
"preview": {
"previewModeSigningKey": "9f2c1e7b4a8d...64hex...",
"previewModeEncryptionKey": "a1b2c3d4...64hex..." } }
These keys sign and encrypt the preview-bypass cookie. With them, a stranger forges a valid one and reads your unpublished content.

_worker.js.map: your server code, de-minified

Cloudflare Pages has an "advanced mode" where SvelteKit, Astro, and Remix adapters compile your server logic into a single _worker.js. By default, the adapter also emits _worker.js.map, the source map, and it gets served. A source map turns minified, unreadable output back into your original, commented source.

That's bad enough for client-side bundles. Here it's worse, because _worker.js is your server code: the request handlers, the auth checks, the logic that was never supposed to leave the server. With the map, a stranger reads your backend the way you wrote it, every internal route, every conditional, every hardcoded value sitting in the original source. The scanner gates this on the real source-map shape ("version":3 plus a populated sourcesContent), so a stray .map filename doesn't trip it, only an actual de-minifiable map of your worker.

_redirects: the "hide my key behind a rewrite" trap

Netlify and Cloudflare let you define routing in a _redirects file. A common, dangerous pattern: someone wants to call a third-party API from the browser without exposing the key, so they add a proxy rule that rewrites a clean path to the upstream URL with the API key embedded as a query param. The browser hits /api/weather, the edge rewrites it to https://api.vendor.com/v1?key=SECRET, and they think the key is hidden.

It isn't. _redirects is a plaintext file the platform serves, and the key sits right there in the rule. The scanner only flags this when a proxy rule actually carries a credential param, so a benign SPA-fallback _redirects (the normal, fine case) doesn't fire, only the anti-pattern where a real key is parked in a rewrite.

$ yoursite.com
$ curl -s yoursite.com/_redirects
/* /index.html 200 # fine: SPA fallback
/api/weather https://api.vendor.com/v1?key=sk_live_9fA2... 200
# the 'hidden' key is in a plaintext file anyone can GET
The proxy rule was meant to hide the key from the browser. It published the key to anyone who reads the file.

The fixes are framework-specific, but the shape is one thing

Each of these has a precise cause and a precise cure, but they share a root: build output that should stay private got served.

# .next directory served as static files
#   -> /.next/required-server-files.json   (env block)
#   -> /.next/prerender-manifest.json       (preview keys)
# Cloudflare adapter emits _worker.js.map by default
# _redirects proxies to ...?key=sk_live_...
Serve only the publish directory, disable server source maps, and never embed a key in a redirect.

For the Next manifests: don't serve the raw .next directory as static files; deploy to a real Next runtime or expose only the public output. For _worker.js.map: disable server source maps in your adapter config before deploying. For _redirects: move the secret to a real server-side function that reads the key from an environment variable, so the key never appears in a file the platform serves.

Reading it from outside

Whether your build output leaks is something a stranger settles with a handful of GETs against known framework paths, and that's exactly the check SurfaceCheckr runs, from outside, no credentials. Each path is gated on the framework-internal signature, the Next-specific manifest keys, the real source-map shape, the credential-carrying proxy rule, so it fires only on a genuine mis-serve, not on a benign file that happens to share a name. It reads enough of the response to confirm the leak and stops there. These are the leaks that the move to Next, SvelteKit, and edge deploys created, the same exposed-file problem wearing a 2026 outfit, and the scanner reads them the same way an attacker would: by typing the URL and seeing what comes back.

Find it before someone else does.

Paste your domain. The grade and issue count are free, and you'll see in a couple of minutes exactly what's reachable from outside.