Sensitive data shared with analytics services
CWE-200CWE-359OWASP A05:2021Updated September 4, 20265 min read
Scripts for analytics, error reporting and session recording run in your page with the same rights as your own code. They forward URLs, page titles and sometimes form contents by default. On a page carrying a case number, a diagnosis or a recovery token, that is a transfer of sensitive data you did not intend.
Analytics, error reporting and session recording are set up by people who want to know how the application is used. The scripts added for that, however, run in your page with the same rights as your own code, and they collect more by default than what they were placed for. What follows is what actually travels along, and how to rein it in without losing your insight.
What travels along?
An analytics script collects by default the full URL of every page visited, the title of that page, the referring page and an identifier tying visits together. Error reporting scripts also forward the stack trace and often the contents of variables at the moment of the error. Session recording scripts capture what the visitor actually does, including what they type.
We speak of sensitive data shared with analytics services when information sits among that which does not belong with a third party. That rarely happens deliberately; it happens because the default settings were adopted and nobody checked what sits in the URL and the title on the pages in question.
The comparison that fits: you ask someone to keep count of how many visitors come by, and they proceed to note down where everyone went and what was on the forms. They do nothing malicious, they note everything, because that is what they do by default.
What does such an analytics request look like?
Vulnerable:
<!-- Default installation, everything is forwarded -->
<script>
analytics.init({ site: 'PORT-4471' }); // sends URL, title and referrer
</script>
On most pages that is harmless. On this one it is not:
URL : /case/38921/outcome?client=j.walker%40company.com&type=employment-dispute
Title : Investigation outcome | J. Walker | employment dispute | Example Ltd
Both are forwarded to the analytics service. In that party’s reporting there is now a case number, an email address and the subject of the matter: information you never wanted to share. It becomes more serious on a page with a recovery token in the URL: that token then travels to an external party and sits in their log files, at which point it is no longer secret.
With error reporting the pattern is comparable. An error in communication with an external API often carries the full request along, including the key used:
{
"message": "Request failed with status 401",
"config": {
"url": "https://api.paymentservice.example/v2/transactions",
"headers": { "Authorization": "Bearer sk_live_51H8xQ2..." }
}
}
Safe:
// Decide yourself what gets forwarded
analytics.init({
site: 'PORT-4471',
automaticPath: false,
});
function reportPage(path) {
// Replace identifiers with a template
const clean = path
.replace(/\/case\/\d+/, '/case/:id')
.replace(/\?.*$/, '');
analytics.page({ path: clean, title: document.title.split(' | ')[0] });
}
// And error reporting that filters secrets before sending
errorReporting.init({
beforeSend(event) {
delete event.request?.headers?.Authorization;
delete event.request?.cookies;
event.request.url = event.request.url?.split('?')[0];
return event;
},
maskFields: ['password', 'ssn', 'iban', 'token'],
});
The starting point is reversed: you determine what gets sent rather than the script. The statistics stay usable, you still see how many case pages were viewed, but the identifying data stays inside.
Referrer-Policy limits one of those routes and does not solve the underlying problem.What is the impact of data sharing with analytics services?
The severity is low to medium, depending on exactly what leaks. If it concerns page titles and path names without identifying data, it stays a privacy point of attention. If personal data, case numbers or medical, legal or financial designations appear, it is a transfer you are responsible for under the GDPR and one you probably do not have in your processing register.
It becomes a security problem as soon as values travel that grant access. A recovery token or a session identifier in the URL landing in an external party’s log files is a secret you no longer control. Whoever has access to those logs, employees of that party, an attacker who compromises them, thereby has access to your accounts.
There is also a risk unrelated to the data itself. These scripts run in your page with full rights. If the supplier or the distribution network is compromised, modified code runs on your domain for all your visitors. That is precisely why integrity checking and a strict Content Security Policy matter here.
How do you detect data sharing with analytics services?
A tester examines the application’s outgoing network traffic and inventories which external parties receive data. Then, per request, they look at exactly what travels along: the URL, the title, the referrer, and with error reporting the contents of the reported object.
Attention goes to the sensitive pages, not the home page. What sits in the URL and the title of a case page, an outcome, a payment confirmation or a recovery page? Is an identifier or a token passed there? They also check whether session recording is running and whether input fields are masked. Beyond that they test whether the scripts are loaded with integrity checking and whether they are bounded in the Content Security Policy. AssistSec also assesses whether the number of external parties is proportionate to what the organisation actually uses, because scripts are added more often than they are removed in practice.
How do you prevent data sharing with analytics services?
- Determine yourself which data you forward rather than adopting the default settings.
- Replace identifiers in paths with a template and do not send query parameters along.
- Use neutral page titles containing no names, case numbers or subjects.
- Filter headers, cookies and tokens out of error reports before sending.
- Mask input fields explicitly in session recording, and always skip password fields.
- Never put tokens or personal data in a URL.
- Load external scripts with an integrity check and bound them in your Content Security Policy.
- Periodically inventory which external parties are listening in and remove what is no longer used.
- Record the transfer in your processing register and assess whether there is a lawful basis for it.
Sources
Frequently asked questions
What do analytics scripts send by default?
The full URL including parameters, the page title, the referring page, screen details, language and an identifier linking visits together. Error reporting adds the stack trace and often the contents of variables; session recording adds the actual actions on screen.
Is this a security or a privacy matter?
Both, and which dominates depends on what leaks. If it concerns page titles, it is mainly privacy. If a recovery token or session identifier sits in the URL, it is a security problem, because those values grant access.
What exactly is session recording?
Scripts that capture a visitor's actions and replay them as a film: mouse movements, clicks and typed text. Without careful masking that means capturing everything someone enters, including personal data and sometimes passwords.
How do I limit this without losing my statistics?
By sending what you want to measure rather than what the script collects by default. Pass a cleaned path instead of the full URL, use neutral page titles, and mask fields explicitly. Your statistics stay usable; only the level of detail at the external party drops.
Related articles
- VulnerabilitiesCWE-693A05:2021Missing Content Security PolicyWithout a Content Security Policy the browser may load scripts from any source. Learn what a CSP does, how to build one, and which mistakes make it useless.
- VulnerabilitiesCWE-200A01:2021Information disclosureInformation disclosure explained: how stack traces, .git directories, source maps and over-sharing API responses leak data, and how to stop it.
- VulnerabilitiesCWE-200A05:2021Missing Referrer-PolicyWithout a Referrer-Policy the browser passes your page's full URL to every external site. Learn what leaks and how to stop it.
- VulnerabilitiesCWE-598A07:2021Session identifier in the URLA session ID in the URL ends up in log files, browser history and referrer headers. Learn why that leaks sessions and how to fix it.
- VulnerabilitiesCWE-353A08:2021External scripts without integrity checkingLoading JavaScript from a CDN without an integrity attribute means every change there runs straight on your site. Learn how SRI blocks that.