Report URI shows you what runs in real browsers, catches changes as they happen, and enforces what's allowed at the point of execution. Policy-based control, not another dashboard nobody reads.
A deployed policy isn't runtime visibility. You know what you intended to allow. You don't know what actually fired in a real browser this morning.
You don't know what changed since last week, or what a third-party dependency quietly pulled in behind your allow-list.
Make it concrete: a CDN domain you allow-listed years ago can change owners, and your policy keeps trusting it because you trusted the domain, not the code. Report URI's founder, Scott Helme, found exactly this digging through CSP report data — netdna-ssl.com, a dead CDN's asset domain still referenced by thousands of sites, re-registered by someone who now controls DNS across the old namespace.
The allow-list never noticed. It was still doing exactly what you told it to do.
CSP Reporting
Every violation from real browsers, searchable. Tune your policy against what's actually happening, not what you assumed would happen. See how CSP reporting works →
Script Watch
Every JavaScript dependency monitored. You get told the moment one changes, moves, or starts behaving differently. Unexpected changes in an authenticated session are one of the most reliable early signals of a client-side attack. See how Script Watch monitors your JavaScript →
Data Watch
Detect data leaving the page to destinations it shouldn't reach. See how Data Watch tracks your data →
You've deployed monitoring tools before, and they became dashboards nobody looked at. The objection is worth answering head-on.
Policy-based enforcement is what separates a real alert from noise. You define what's allowed, so a violation means something actually broke policy — not just “something happened”.
Scott Helme's framing from the Instructure Canvas breach makes the point: with a strict, nonce-based CSP, an injected inline script generates a violation report on every page load. In that incident, the signal was there for four days. The problem was that nobody was piping the reports somewhere they'd get looked at.
The useful version: reports go to an aggregator you actually watch, and the injection announces itself on day one.
Move from detection to control. Define what's allowed, blocked, or reported, and enforce it at runtime.
This runs on what actually executed in the browser — not simulated traffic or inferred behaviour from a scanner.
Subresource Integrity is part of the toolkit: a swapped third-party script fails closed instead of executing. As Scott notes, SRI won't save you from first-party XSS — different problem, different control. The precision is the point. See how integrity monitoring works →
Report URI works through the browser's Reporting API. Add your reporting endpoint to your Content-Security-Policy header. That's the entire deployment.
Content-Security-Policy: default-src 'self';
report-uri https://your-subdomain.report-uri.com/r/d/csp/enforce
One header. Browser-native. No code changes, no proxy in the path, and the site is unaffected if Report URI is unavailable.
| Pairs with | Doesn't replace |
|---|---|
| Your WAF | Penetration testing |
| Your SIEM | Secure code review |
| Your SOC | Framework-level XSS defence |
It tells you when your other controls have already been bypassed, before the session or the data is gone. The full guide to client-side security →
Have I Been Pwned runs Report URI to monitor for malicious JavaScript and unauthorised data exfiltration — a team that treats the browser as an execution environment, not a display layer.
Report URI was founded by Scott Helme, who finds and publicly discloses client-side attacks from real CSP report data — the netdna-ssl takeover and the Canvas breach analysis among them. Read the case studies →
One header. No agent, no proxy.