All articles

Detect leaked credentials in JavaScript before launch

7 min read

Free security scan

Is your Next.js app secure? Find out in 30 seconds.

Paste your URL and get a full vulnerability report — exposed keys, missing headers, open databases. Free, non-invasive.

No code access requiredSafe to run on productionActionable report in 30

To detect leaked credentials in javascript, scan the browser-delivered app, not only the repository. The fastest answer is to inspect built assets, source maps, inline config, public routes, and network behavior before launch. If a credential appears in any file a browser can download, assume it is exposed, rotate it, and move the sensitive operation server-side.

How to detect leaked credentials in JavaScript?

Start with the same view an attacker gets: the public website, compiled bundles, static assets, and API calls visible from the browser. Repository scanning helps, but it misses build-time injections, environment variable mistakes, source map exposure, and secrets copied into deployment artifacts.

For a launch review, check these locations first:

  • built assets first, including hashed chunks, vendor files, and lazy-loaded routes
  • source maps, especially files ending in .map under public static paths
  • inline runtime config inside HTML, hydration data, and bootstrap scripts
  • public environment prefixes that intentionally expose values to the browser
  • client storage, including localStorage, sessionStorage, and indexedDB seed data
  • network calls that reveal bearer tokens, admin endpoints, or private service URLs

A useful workflow is to scan the deployed preview URL, then scan the production URL after the final build. Many leaks appear only after bundling because frameworks replace environment references during compilation. This is why a prelaunch JavaScript bundle scan is more realistic than reviewing source code alone.

Do not stop at obvious words like SECRET or TOKEN. Real leaks often look like ordinary config: a billing key named clientKey, a database URL stored in a helper file, or an admin API token copied into a demo component. Treat anything granting write access, privileged reads, billing actions, or account control as sensitive.

Where credentials usually hide?

The most common failure pattern is mixing public and private configuration. A frontend may need a harmless public identifier, but the same config object accidentally includes a server token. Once that object is imported by client code, the bundler can embed the value in a downloaded file.

Here is a simplified pattern that should fail a release review:

js
export const appConfig = {
  publicProjectId: 'proj_abc123',
  billingSecret: 'sk_live_REPLACE_ME',
  adminApiToken: 'adm_9f2c4e7b_secret',
  supportMailbox: 'help@example.com'
}

fetch('/api/admin/sync', {
  headers: { Authorization: `Bearer ${appConfig.adminApiToken}` }
})

The fix is not to rename the variable. The fix is to remove the secret from all browser paths. A browser can always reveal downloaded JavaScript, even when it is minified, obfuscated, or split across many chunks.

Source maps are another frequent problem. They are helpful for debugging, but public maps can expose original filenames, comments, test fixtures, and string constants. Even if the minified bundle looks clean, a .map file may reconstruct the readable source where the leaked value is easier to find.

Client-side credentials also appear in generated HTML. Look for serialized objects in script tags, framework hydration payloads, and route metadata. If your app renders server data into the page, review what gets embedded before the first JavaScript file even loads.

Public route mistakes are just as serious. Teams sometimes expose /config.json, /env.js, /debug, /api/status, or old staging files to make deployment easier. Those paths can reveal internal service names, private endpoints, or exposed API keys. If API key exposure is your main concern, compare your findings with this frontend API leak guide.

Also check deployment defaults. A file named .env, .env.local, .env.production, or backup.env should never be publicly reachable. If you are not sure whether your hosting setup blocks them, run a dedicated public env check before launch.

Fix findings without guessing

When you find a secret in a public asset, do not debate whether anyone accessed it. Treat it as compromised. Browser-delivered files can be cached by users, proxies, search engines, monitoring tools, and automated scanners. Removing the string from the next build is necessary, but it is not enough.

Use this response sequence:

  1. rotate before redeploying so the exposed value stops working immediately.
  2. Remove the credential from client imports, public config, and static files.
  3. Replace direct browser calls with a server-side proxy or backend endpoint.
  4. Limit the new secret with scope, environment, IP, domain, or role controls.
  5. Redeploy, then perform a cache purge for CDN and hosting layers.
  6. Rescan the live URL and preview URL to confirm the old value is gone.

For quick local triage, search the final build output, not just source folders:

bash
BUILD_DIRS="dist build .next public"
grep -RInE "(sk_live_|ghp_|AKIA[0-9A-Z]{16}|SECRET|TOKEN)" $BUILD_DIRS 2>/dev/null
find $BUILD_DIRS -name "*.map" -type f -print 2>/dev/null
curl -s https://example.com/config.json | head
curl -s https://example.com/.env | head

This command is not a complete scanner. It is a sanity check that catches obvious strings and exposed files. A real scanner should use token fingerprints, entropy checks, provider-specific patterns, source map parsing, and allowlists to reduce false positives.

Be careful with values that look public. Some browser keys are intentionally public, but that does not make every use safe. A public identifier can still become dangerous if it enables unrestricted reads, account enumeration, quota abuse, or calls to privileged backend functions.

After the fix, verify behavior as an anonymous user. Open a private browser session, load the production site, inspect downloaded files, and replay critical requests without an authenticated session. If a sensitive request still works with a token from the frontend, the architecture is still wrong.

For broader coverage, run a deep scan that checks public pages, hidden routes, headers, exposed files, and secret patterns together. Credential leaks rarely exist alone. They often sit next to permissive CORS, debug endpoints, or admin paths left from development.

Prevent repeat leaks

The best prevention is a release gate, not a one-time cleanup. Add scanning where the mistake is most likely to appear: after dependency install, after build, and against the deployed preview URL. This catches both source mistakes and deployment-time injections.

Use this checklist before every public release:

  • release-blocking check for high-confidence secrets in built assets
  • Scan preview deployments before merging to production
  • Block public source maps unless intentionally approved
  • Keep private variables out of client-exposed prefixes
  • Review config files copied to public, static, or asset folders
  • Rotate test tokens before turning a prototype into a real app
  • Require no approved exceptions for write-capable credentials

A practical policy is simple: if the browser can download it, it cannot be a secret. Use least-privilege keys for public identifiers, and keep private authority on the server. That means payment actions, email sends, database writes, admin reads, and account management should flow through authenticated backend code.

AISHIPSAFE is built for this prelaunch moment. Run a security scan on the URL your users will actually visit, then fix exposed secrets before announcing, buying ads, or onboarding customers. For related source and deployment checks, a hardcoded secret scanner can help catch values before they reach the browser.

The final launch rule is strict but effective: never ship a frontend until public assets, maps, config endpoints, and anonymous requests have been reviewed. One exposed token can turn a clean launch into account abuse, billing damage, or data exposure within hours.

Faq

Can minification hide leaked credentials?

No. Minification only makes code smaller and less readable. It does not protect secrets because the browser must still download the value to use it. Attackers can search bundles, pretty-print files, inspect source maps, and watch network requests. Sensitive credentials must be removed from client-delivered code entirely.

Are public API keys always dangerous?

Not always. Some public keys are designed for browser use, but they still need restrictions. Check allowed domains, permissions, quotas, and backend rules. A public key becomes dangerous when it can read private data, write records, trigger billing, bypass authentication, or call privileged functions without server validation.

Should i rotate a leaked test credential?

Yes, if it touched a real service, shared account, production-like data, or billing-enabled project. Test credentials are often reused during rushed launches. Rotate them, remove them from history and build artifacts, and confirm the old value fails. Do not rely on intent or naming to judge exposure.

Need a quick prelaunch check? Run AISHIPSAFE against your public URL and fix exposed credentials before users, bots, or attackers find them.

Free security scan

Is your Next.js app secure? Find out in 30 seconds.

Paste your URL and get a full vulnerability report — exposed keys, missing headers, open databases. Free, non-invasive.

No code access requiredSafe to run on productionActionable report in 30