← Blog

Why CSP reports fill up with browser extension and bot noise

Browser extensions, crawlers and data: URIs trigger CSP violation reports your site didn't cause. How HeaderHawk identifies that noise and keeps it out of your alerts.

Michael Cameron4 min readUpdated

Turn on Content Security Policy reporting and many of the first reports aren’t about your site at all. A browser extension injects a script, a search crawler renders the page, or something on the page loads an image from a data: URI, and the browser reports each one as a violation. They look just like the reports you need to act on.

HeaderHawk labels those reports as noise when they arrive. They stay out of your alerts, the clear-cut ones stay out of your issues list, and every one of them is still stored if you want to look.

Where CSP report noise comes from

Browser extensions run their own scripts inside your pages. When your policy blocks one, the report’s blocked URI starts with the extension’s scheme, such as chrome-extension:// or moz-extension://, instead of a URL on your site or a service you use.

Crawlers, link previews and automation tools load your pages too. Search engines render them, chat apps fetch them to build a preview, and headless browsers and test scripts run against them. Any of those visits can send violation reports.

about:, data: and blob: URIs appear when something creates content inside the browser rather than loading it from a server, and a policy that doesn’t list those schemes reports them.

How HeaderHawk identifies noise

Each report is classified once, after the raw report has been stored, using the blocked URI, the directive that blocked it and the user agent of the browser that sent the report. Three rules mark a report as known noise, and the first match decides.

  1. The blocked URI starts with a browser extension scheme, such as chrome-extension://, moz-extension://, safari-web-extension://, webkit-masked-url:// or ms-browser-extension://.
  2. The blocked URI is an about: URI, or a data: or blob: URI that was not blocked as a script.
  3. The user agent belongs to a known crawler, link-preview fetcher, headless browser, test driver or HTTP library, such as Googlebot, Bingbot, HeadlessChrome, Puppeteer, Playwright or curl.

A data: or blob: URI blocked as a script (by script-src, script-src-elem, script-src-attr or worker-src) is likely noise instead. Extensions and in-page tooling load scripts that way all the time, but so does an attacker who has found a way to inject one, so it is not hidden with the rest.

A report that matches none of the rules is signal. The rules are fixed lists, with no scoring and no machine learning, so the same report is classified the same way every time.

Blocked URI Directive User agent Classified as
chrome-extension://abc/inject.js any any known noise
data:image/png;base64,… img-src any known noise
blob:https://example.com/uuid script-src-elem desktop Chrome 120 likely noise
https://cdn.example.com/script.js script-src-elem Mozilla/5.0 (compatible; HeadlessChrome/90.0) known noise
https://cdn.example.com/script.js script-src-elem desktop Chrome 120 signal
inline script-src-elem desktop Chrome 120 signal

For what a real script violation contains, the cross-site scripting guide walks through one.

What happens to noise reports

Nothing is deleted. Noise reports are stored and kept for as long as any other report, and the reports explorer shows every report however it was classified.

The issues list hides known noise by default. Turn on Show noise to bring those issues back. Likely noise is never hidden: its issues stay in the list, dimmed and marked Noise.

How noise affects CSP alerts

HeaderHawk groups violations by signature into 15-minute windows before deciding whether to alert. Known noise is left out before a window is counted, so an extension that fires on thousands of page views can’t set off an alert. Likely noise is counted but is not signal, so a window of nothing else alerts nobody.

A window sends a real-time alert when two or more browser families reported the same violation, or when twenty or more signal reports arrived from one. Anything below that can go to a daily or weekly digest instead, and the digest leaves out issues with no signal reports, which covers both kinds of noise. The features page shows how issues, alerts and digests fit together.

Why HeaderHawk uses simple rules

A report marked as noise is one you won’t see unless you look for it, so the reason should be something you can check. Every noise decision comes from one of the rules above, and every noise report is still there when you turn noise on.

Read your own reports this way

Point your policy's reporting at HeaderHawk and see violations grouped by directive, blocked source and page. The Free plan covers 1 site.