Use an exposed secrets scanner before launch to inspect public pages, JavaScript bundles, source maps, and accidental files for leaked credentials. The goal is simple: find anything a browser, crawler, or attacker can fetch without logging in. If a key is already shipped to the client, treat it as public and rotate it before release.
What an exposed secrets scanner checks?
A good scan starts from the outside, because attackers do not need your repository to find leaks. They request the same URLs, assets, and static files that a browser can reach, then look for credential-shaped values and risky configuration.
The first pass should cover:
- public JavaScript that contains API keys, tokens, or backend URLs
- environment file paths such as
/.env,/env.local, and backup variants - source maps that reveal original source code or hidden comments
- third-party tokens for payments, email, analytics, storage, and AI APIs
- admin routes that are visible even when protected by a login screen
- build artifacts left by frameworks, hosting tools, or quick deploy scripts
This is different from a dependency audit. A dependency audit asks whether packages are vulnerable. A secret scanner asks whether sensitive values are reachable from the public internet.
For AI-built apps, the most common pattern is not an advanced exploit. It is a generated helper file that reads from process.env, then accidentally gets imported into client code. Another common pattern is a demo key hardcoded during testing and never removed.
If you are checking a frontend before launch, pair this process with frontend secret checks. If your app is heavily bundled, also run a JavaScript bundle scan so minified files are not ignored.
Where leaked secrets usually hide?
Secrets rarely appear in neat files named secret.txt. They hide in build output, comments, test routes, logs, and configuration that looked harmless during development.
The highest-risk places are browser-delivered assets. Anything inside the final HTML, CSS, JavaScript, source maps, or public folder must be considered readable. A key can be restricted, but it cannot be private once shipped to users.
Watch these failure patterns:
- A server-only API key imported into a shared utility
- A
.envfile copied intopublic/during deployment - A source map exposing comments with test credentials
- A webhook secret printed into a debug endpoint
- A storage bucket token embedded in upload code
- A payment secret placed beside a publishable key
The fix depends on the key type. Some browser keys are designed to be public, but they still need origin restrictions, quota limits, and least privilege. Private keys need removal, rotation, and server-side proxying.
Use assume compromise as the rule. If a private credential was reachable publicly, do not only delete it. Revoke it, create a new one, review logs, and check whether it was used.
Here is a small local preflight that catches obvious leaks before an external scan. It is not a replacement for a full review, but it prevents basic mistakes from reaching production.
set -euo pipefail
npm run build
SCAN_PATHS="dist build .next/static public"
grep -RInE "(sk_live_|AKIA[0-9A-Z]{16}|AIza[0-9A-Za-z_-]{35})" $SCAN_PATHS || true
find $SCAN_PATHS -maxdepth 3 \( -name ".env*" -o -name "*.map" \) -printThis kind of secret scanner is useful because it tests the artifact you actually ship, not only the source you intended to ship. Generated apps often change structure quickly, so artifact-level validation catches mistakes that code review misses.
Run a safe scan
Scanning for leaks should not break production or trigger dangerous actions. A safe process uses read-only requests, avoids authenticated mutations, and clearly separates discovery from exploitation.
Start with a public URL and define scope. Include the main domain, app subdomain, static asset host, and common deployment preview paths if they are public. Exclude destructive routes and anything that could create records, send emails, or charge cards.
A practical workflow:
- Scope public assets: list domains, subdomains, and deploy previews.
- Check static paths: request common env, backup, map, and config files.
- Inspect bundles: search built JavaScript for token patterns and secrets.
- Review findings: separate public identifiers from private credentials.
- Rotate before rescanning: revoke exposed secrets before confirming cleanup.
- Document decisions: record false positives and accepted public keys.
A public app scan should use no authenticated actions unless you explicitly configure a test account. Even then, it should avoid writes unless you are running a controlled staging review.
For launch checks, AISHIPSAFE provides a security scan designed around public-facing AI-built apps. For broader crawling and deeper route discovery, use a deep scan when you need more coverage than a quick homepage test.
If an environment file is exposed, follow a dedicated public env check. Those leaks are usually severe because they may include database URLs, backend tokens, OAuth secrets, and webhook signing keys in one place.
You can also compare your process against the OWASP guidance on secrets management, especially for rotation, storage, and access control.
Fix findings before release
The most important part of a credential leak scan is what happens after detection. A report is not a fix. You need to remove the exposure, rotate the credential, and verify that the new value never enters public code.
Use this triage order:
- Critical: private API keys, database URLs, service tokens, signing secrets
- High: source maps exposing sensitive code, admin URLs, internal endpoints
- Medium: public keys without origin limits or excessive permissions
- Low: harmless identifiers, sample values, or already-revoked tokens
For critical leaks, rotate first. Then remove the exposed value from bundles, source maps, files, and logs. After deployment, rescan the exact production URL and confirm the old value is gone.
Do not rely on git cleanup alone. A value can be removed from the repository and still remain in a CDN cache, static build folder, old deploy preview, or source map. Check the live artifact, then purge caches where needed.
Good fixes usually include runtime configuration changes. Server-only secrets should live only in server execution contexts. Client code should call your backend, and the backend should call the third-party provider.
Before launch, add CI before deploy checks. They should scan source code, built assets, and public folders. The external scan still matters because it verifies the final deployed result from an attacker’s viewpoint.
Keep a short key rotation log with the affected service, old key status, new key creation time, deploy time, and rescan result. This gives you evidence for teammates, customers, or future incident reviews.
A clean result does not prove the app is perfect. It proves that common public credential exposures were not found in the tested scope. That is still a valuable launch gate, especially for small teams shipping quickly.
Ship only after the live app has been rescanned, critical findings are closed, and public keys have proper restrictions. Treat the process as a repeatable release check, not a one-time cleanup. Fast builders can stay fast without leaving credentials in the open.
Faq
What counts as an exposed secret?
An exposed secret is any credential, token, signing key, database URL, or private configuration value reachable by unauthenticated users. Public identifiers are different, but they still need restrictions. When unsure, check the provider documentation and treat powerful keys as private until proven otherwise.
Can scanning break my production app?
A safe scan should use read-only requests and avoid actions that submit forms, create records, send messages, or trigger payments. The safest setup is unauthenticated public crawling first. If authenticated scanning is needed, use a test account with limited permissions and clear exclusions.
Should i rotate keys after a leak?
Yes, if the leaked value could grant access or authorize requests. Deleting it from code is not enough because it may exist in caches, logs, browser history, or old deployments. Rotate the key, redeploy, purge caches if needed, and rescan production.
If you want a practical launch check, run AISHIPSAFE before publishing and fix any credential exposure before users find it.