Secrets Don't Belong in URLs
Last week, a security firm called Claroc discovered that 35,000 Grok Build apps — SpaceXSI’s AI coding agent — were wide open to anyone who knew where to look. Medical records, defense contractor rosters, employee databases, SpaceXSI’s own internal sales playbooks. All of it sitting behind “private” links that turned out to be anything but.
The root cause was a design decision about where to put the randomness in a shared URL. Grok Build used subdomains — cinder-crane-sand-frost.grok.me — for each app. The entropy was solid: three dice words, billions of combinations. The problem is that subdomains show up in passive DNS databases. Every DNS lookup for a new subdomain gets logged and becomes publicly searchable. A researcher pointed a passive DNS tool at *.grok.me and found all 43,601 of them.
The Ars Technica article covering the story noted that platforms like Claude, ChatGPT, and Gemini get this right by putting randomness in the URL path instead of the subdomain. And that’s true — DNS doesn’t see URL paths. But it misses the deeper point.
URLs Leak Everywhere
A reply on X from @pggalaviz put it well:
“Putting the secret in the URL is one of the oldest mistake there is. It shows up in DNS logs, proxy logs, referrers, browser history… A long random path doesn’t make anything private by default”
This is correct, and it’s an important distinction. Moving the randomness from a subdomain into a URL path fixes the DNS enumeration problem. It does not fix the URL-as-access-control problem. URLs with secrets in them leak through:
- Corporate proxy and web filter logs. Every enterprise with an SSL inspection proxy logs full URLs, paths included.
- Browser history. The URL persists on the recipient’s machine indefinitely.
- HTTP Referrer headers. If the recipient clicks any outbound link from the page, the full URL may be sent as a referrer to the destination.
- Chat and email logs. The URL was sent to the recipient somehow. That channel has a copy.
- URL shorteners, link-click trackers, email security scanners. All of them see and store the full URL.
A URL — no matter how random — is not a security boundary. It’s an address. Treating it as access control is the same class of mistake whether the randomness is in the subdomain, the path, or the fragment.
Ephemeral Design Is the Actual Answer
The Grok Build data was exposed for months because the data behind those URLs was persistent. It sat there, unchanged, accessible to anyone with the link, for as long as the app existed. That’s not a link-sharing problem. That’s a data-lifecycle problem.
Password Pusher was built around a different assumption: shared sensitive data should not persist. Every push has a configurable view limit and a time-to-live. Reach either threshold and the data is hard-deleted from the database. Not archived, not soft-deleted — gone. The URL becomes a pointer to nothing.
This changes the calculus entirely. If a URL leaks through a proxy log or browser history, the question isn’t whether someone unauthorized might find it. The question is whether the data is still there when they do. For a push configured with a single view and a one-hour expiration, the answer is almost certainly no.
Beyond the URL
We don’t rely on URL secrecy alone. Password Pusher layers additional controls that most link-sharing tools simply don’t have:
- Retrieval step. Before the payload is revealed, the recipient sees a confirmation page. This defeats URL scanners, email security gateways, and automated systems that follow links without human interaction. The scanner sees a landing page. The secret stays unrevealed.
- Passphrase protection. The push creator can lock the payload behind a passphrase that the recipient needs to know separately — sent over a different channel.
- Authenticated Recipients. The recipient must verify their email address via a one-time code before the payload is shown. Possession of the URL isn’t enough — you also need access to the intended recipient’s inbox. This is available on our Solo plan and above, and on Self-Hosted Pro.
- Full audit logging. Every access is logged with a timestamp and IP address. If someone unauthorized views a push, the creator knows.
Each of these reduces the blast radius of a leaked URL. Combined with ephemeral data, the threat model is fundamentally different from “anyone with the link gets the data forever.”
Zero-Knowledge Is Coming — but Not via the URL
We’re building end-to-end encrypted, zero-knowledge pushes for Password Pusher. When it ships, the hosted service won’t be able to decrypt push payloads at all.
One thing we won’t be doing: putting the decryption key in the URL.
Several tools in this space take that approach. They put the encryption key in the URL fragment — the part after the # symbol. The fragment isn’t sent to the server in HTTP requests, which means the server technically never sees the key. That’s the basis of their “zero-knowledge” claim.
But the fragment is still part of the URL. It’s in the browser’s address bar, in browser history, in any context where the full URL string is copied, shared, pasted, or logged by client-side code. Browser extensions can read it. Screenshot tools capture it. The moment someone shares the URL in a chat message, the key travels with it — sitting in the same logs, the same history, the same proxy records we just talked about.
Putting a decryption key in a URL is the same conceptual mistake as putting an access token in a URL — it assumes the URL string will only ever travel through channels the sender controls. The Grok Build incident is 35,000 examples of what happens when that assumption breaks down at scale.
We’ll share more details on our approach as it gets closer to release. The short version: the decryption key will not be embedded in the URL, and the security model will not depend on the URL staying secret.
This Is the Problem We Were Built For
I built Password Pusher in 2011 because I watched credentials get pasted into Slack messages, email threads, and Jira tickets — and then sit there forever. The problem was never “how do I make a secret URL.” The problem was “how do I share something sensitive and have it not exist after the recipient has it.”
That problem is getting bigger, not smaller. AI coding agents, vibe-coded internal tools, shared cloud documents — more data is being created and shared faster, with fewer people thinking about what happens to it after it’s been read. The Grok Build leak is 35,000 examples of that happening at once, but it’s the same pattern that plays out every day in every organization that pastes a credential into a chat window.
The approach has always been the same: make the data ephemeral, control access beyond the URL, log every access, and keep the security-critical code open source so anyone can verify the claims. Fifteen years in, I still think that’s the right foundation.
Peter Giacomo Lombardo Founder & Principal, Apnotic · Creators of Password Pusher