KeyDrift
Free scan
← Leak scenarios

postgres:// and mongodb+srv:// URLs in client code

Scheme-plus-password in a bundle is the shortest possible breach report. Both Postgres/Mongo shapes detected — free scan.

3 min read

No decoder, no dashboard, no prefix lookup required: everything needed to connect sits between scheme and slash. This is the finding that ends arguments about whether scanning matters.

Both families, tutorial-noise calibration, relocation fix.

What a database connection string is

Full DSNs embed auth inline: postgresql://user:pass@host/db, mongodb+srv://user:pass@cluster/host.

postgresql://app:FAKEPASSWORD@db.example.internal:5432/prod

The prefix is the claim: scanners and attackers alike identify the format before they know anything else about it, which is why recognition starts at the first characters rather than the last.

What it grants

Protocol-direct access:

  • Every operation the role permits — CRUD and often DDL.
  • Total bypass of application-layer authorization.

How it ends up in a bundle

Three arrival routes cover nearly every case we see:

  1. Prototype direct-query code surviving into prod bundles.
  2. Analytics dashboards querying DBs from the client for speed.

Does it belong in a browser?

Drivers belong server-side; clients consume JSON APIs.

Rotate it

Change password/role at DB layer; update server configs; consider network ACLs tightening.

Find it in seconds

Open DevTools on the deployed site and search the built assets for postgres. If the search hits, the credential shipped; if it does not, check the chunks loaded on authenticated or interactive views, not just the landing page — the calling code often sits behind a route.

The faster path is to let a machine do the fetching. KeyDrift downloads the same JavaScript a visitor gets — HTML, every referenced chunk including ones named only in the route manifest, and the server-streamed data frameworks inline into the document — and reports credentials with a masked prefix, a fingerprint, and the exact file they live in. Paste your deployed URL into the scanner; no account needed.

Make sure it stays gone

It bears saying because it happens constantly: the fix holds until the next prompt that needs the query to return rows. Drift monitoring exists for precisely this — it diffs consecutive scans and pages you when a previously resolved finding reappears, naming the regression as a regression rather than repeating the first alert.

Tutorial-default calibration

compose-style defaults (postgres:postgres@localhost) get downgraded confidence/local-host flags rather than critical alarms — precision keeps signal trustworthy at scale.

Why this keeps happening industry-wide

It helps to name the economics honestly. Fixing this class of leak costs minutes when caught at deploy time and days when caught at invoice time, because by then the credential has been harvested, validated, resold or drained — often all four. Detection latency is the entire game, which is why the monitoring half of KeyDrift exists alongside the scanning half.

How KeyDrift reports this exact finding

When KeyDrift finds this on your deployment, the report shows a masked value (first 8 and last 4 characters only), a salted fingerprint for tracking, the exact chunk filename carrying it, and a severity with written rationale. Public-by-design neighbours — anon keys, publishable keys, Firebase web constants — appear as informational context rather than noise, because knowing what should be there is what makes the real findings credible.

Manual check, step by step

A five-minute version you can run anywhere: view-source on the landing page, copy every src= script URL, fetch each and search the results for postgres. It misses manifest-only chunks and streamed payloads — which is precisely the gap between "I checked" and "it is clean" — but it catches the loud majority and builds the pattern-recognition that makes scanner output legible.

Close the loop with monitoring

Monitoring closes the loop that one-time verification leaves open. A scheduled scan refetches everything, diffs against history, and fires only on transitions: created, regressed, resolved. Regression alerts matter most here — they fire when a previously fixed finding returns, which in agent-era codebases is less a possibility than a schedule.

Common questions

Pooler/Prisma URLs different?

Same exposure semantics regardless of pooling layer.

SSL mitigates?

Encrypts transit; does nothing about credentials being public.


Run a free scan at keydrift.dev/scan — paste a URL or the bundle source itself, no account. Findings arrive masked, with the exact chunk they live in.

Published by PostHat, KeyDrift’s content pipeline. Every factual claim is grounded in KeyDrift’s product documentation.