URL privacy audit
A URL is the least private part of a request. It is written to your access logs, your CDN's logs, every analytics tool on the page, the browser's history, and the Referer header sent to third parties. Anything personal in it has been copied to all of those places. Paste your URLs — from analytics, from logs, from a crawl — and see what is in them.
Findings
Summary
How to use
- Paste the URLs. Good sources: a GA4 page-path export, a week of access-log paths, the URL list from a HAR file, or the outbound URLs your page sends to third parties.
- Read the Level column. high means a credential or a direct identifier. medium is personal data. low is contextual — meaningful in combination with something else.
- Each finding says where it was found: the path, the query, a named parameter, the fragment, or inside a base64-encoded parameter value.
- The cleaned box strips the parameters that produced findings, plus the fragment — a starting point for a redirect or a log-sanitisation rule, not a remedy for data already collected.
Where a URL actually goes
Your server logs. Every request line, in clear text, retained for as long as your log policy says — typically far longer than you would keep the same data in a database, and usually outside whatever deletion process you built for personal data.
Every analytics and tag script on the page. Google Analytics, Meta Pixel, session recorders and heatmap tools all send the full page URL as a matter of course. If an email address is in the query string, it is now in those systems too — which for Google Analytics is a direct violation of their terms on PII, and can get an account suspended.
The Referer header. When a user clicks a link to another site or your page loads a third-party resource, the browser may send the current URL as the referrer. The default policy in modern browsers (strict-origin-when-cross-origin) sends only the origin cross-site, which helps — but the full URL is still sent on same-origin requests, and older or misconfigured policies send everything. A Referrer-Policy header is the mitigation.
Browser history and sync. Stored on the device, and synced to the user's account across their devices. Shared computers, screen sharing and screenshots all expose it, and autocomplete will happily suggest a URL containing a token to the next person typing in the address bar.
Anywhere it gets pasted. URLs are shared by design: chat, email, tickets, bug reports. A URL with a session token in it is a credential that can be forwarded, and unlike a cookie it does not stay in the browser.
The two findings to treat as incidents
Credentials. A JWT, an API key, a Stripe or AWS key, a session id, a password parameter. Do not just remove it from the URL — assume it is compromised and rotate it. It is already in logs you may not control (a CDN, a load balancer, a monitoring service) and in browser histories you certainly do not. The right long-term fix is that credentials travel in an Authorization header or a cookie, never in a URL.
Identifiers in the fragment. Historically the OAuth implicit flow put access tokens after the #, on the reasoning that fragments are never sent to the server. They are still fully visible to every script on the page, land in browser history, and survive in the address bar. The implicit flow was deprecated for exactly this reason — authorisation code with PKCE replaced it.
For the rest — emails, names, addresses, coordinates — the fix is structural: pass an opaque identifier in the URL and look the real data up server-side. Where a personalised link must exist, as in an email campaign, use a short random token that maps to the recipient in your database and expires, rather than the email address itself.
FAQ
Is my URL list uploaded?
No. The patterns are regular expressions running in your tab, which matters here more than anywhere else on this site — the whole point is that these URLs contain things that should not be sent to a third party. Confirm it in the Network panel.
How accurate is it?
Pattern-based, so it will produce both false positives and false negatives. A card-shaped number is only reported if it passes the Luhn check, which cuts most false positives there; the phone and date patterns are the loosest and will match some ordinary numbers. Absence of findings is not proof of cleanliness — a custom identifier format will not match anything here.
Why does it decode base64 parameters?
Because a base64 blob is where PII most often hides in practice: a client encodes a JSON object of user details into one parameter and it reads as opaque. If a parameter decodes to printable text, that text is scanned too.
What should I do about historical data?
Rotate anything credential-shaped, then work through the places the URLs went: log retention and any log-scrubbing rules, analytics data deletion requests, and your CDN's logs. Under GDPR this may be a reportable breach depending on what leaked and to whom — that is a decision for whoever owns privacy at your organisation, not a technical judgement.