Report URI vs c/side

One of these needs its own code running in your pages

Report URI is a client-side security platform: your policy is enforced by the browser itself, which refuses what it disallows and records what it ran. c/side is a JavaScript agent: a script of theirs loads first in your pages, watches the scripts that load after it, and their servers fetch and analyse those files. That difference decides what each one can see, what each one can stop, and what has to be working for either to do anything at all.

By Scott Helme — CEO and Founder · 24 July 2026, updated 11 August 2026

Client-side security platform
Report URI

Nothing is added to your pages. The browser refuses what your policy disallows, reports what it ran, and verified copies of that code are archived.

vs
JavaScript agent
c/side

A script of theirs loads ahead of everything else to observe what follows, and the files it sees are fetched and analysed on their servers.

What Each One Depends On

One of these has to be running.

Every client-side tool has one thing that must be working before it can do its job. For an agent, that thing is a script it puts in your pages, and it has to get there ahead of the code it is meant to be watching. For us it is the browser, which is already there and already enforcing. The diagram below is the whole comparison in one picture.

Client-side security platform
Script origin Browser Report URI

Your policy travels with the page, so the browser refuses unauthorised code at the moment it would have executed — and reports what it did. There is nothing of ours to load, so there is nothing of ours to fail.

JavaScript agent
Their agent Scripts it sees Their servers

Their documentation asks for the tag to be the first script in your head, because anything that executes ahead of it goes unobserved. What it does see is sent on to be fetched and analysed on their side.

The Cost Of Being First

First script in the head is the most expensive place to be

The tag carries neither async nor defer, and it is asked to go before everything else. That is the most render-blocking position a script can occupy. The parser stops there, and because the file comes from another origin, a DNS lookup, a TCP connection and a TLS handshake all have to complete before the first byte of it arrives — ahead of your own content, on every page load, on whatever network your visitor happens to be on. The standard guidance for third-party JavaScript is the exact opposite: mark it async or defer unless it genuinely belongs in the critical rendering path.

This is not an oversight, and it is not something a faster CDN fixes. Deferring the script would let other scripts run before it, and anything that runs before it is not observed. Being early is the mechanism, so the cost comes with the architecture rather than with the implementation. A response header has nothing to download, nothing to execute, and nothing to go before.

What Adoption Costs Your Policy

You loosen the policy to install the tool

Their setup instructions ask you to add their hostname to script-src and to connect-src. Those are the two directives that decide which code may run on your pages and where it may send data, and the entry is a wildcard covering the whole domain rather than the one file. So adopting a client-side security tool begins by widening the client-side security policy, in exactly the two places an attacker would want it widened.

The tag also carries no integrity attribute, and realistically cannot: a script that updates itself cannot be pinned to a hash without breaking on the next release. That leaves an unpinned third-party file, loaded before everything else, on every page including checkout. The vendor's own packages recommend a release-age delay on installs as protection against supply-chain attacks, so the risk is well understood — it is simply the customer who carries this instance of it.

With Report URI the policy is the product. Nothing is added to script-src, nothing is added to connect-src, and the directives stay as tight as you are willing to make them.

Head to Head

What follows from each architecture

Structural consequences rather than a feature scorecard. Both approaches are legitimate; they optimise for different things.

Consideration Report URI JavaScript agent
What runs on your pages Nothing — your policy is a response header Their script, on every page load, ahead of everything else
If it fails to load Nothing to fail; the policy is already in the page That session goes unwatched, and nothing says so
Effect on page load None — there is nothing to download or execute A render-blocking request to another origin, ahead of your content
Coverage Every real session, including authenticated pages and checkout Whatever loaded after their script did
Blocking By the browser itself, under your enforcing policy By their script, once it is running
Evidence of execution What the browser actually ran, reported by the browser What their agent observed
Script payloads Held, and hash-verified against the browser's own fingerprint Held, having been fetched on their side
Your own policy Unchanged, and enforcing — it is the product Widened, to allow their host to load scripts and send data
Report types Fourteen, spanning scripts, connectivity, isolation and identity Script monitoring, with a CSP endpoint alongside
Deployment One response header One script tag, placed before everything else
Worth Knowing

This architecture changed recently

Until late 2025, c/side's own documentation described a proxy: a proxy script, a proxy hostname, instructions for allowing it through your CSP, and a page explaining which URLs they proxied. Their documentation today describes a single script tag, and states plainly that no traffic is routed through their infrastructure. Older write-ups still describe the proxy, so it is easy to compare against a version of the product that is no longer shipped.

We mention it because architecture is the part of a tool you actually commit to. Integrations, runbooks, CSP allowances and audit evidence are all built on top of it, and they are what you rebuild when it moves. What is written above describes c/side as it is documented today, and the only claim we would make about the change itself is that it happened.

Worth Correcting

We do read the JavaScript — and ours is the copy that ran

The standard argument against anything built on browser reporting is that it sees policy violations but never script contents. That is a fair description of a plain CSP endpoint, and not a description of this one. The harder question is whose copy of a script the evidence actually is.

Script Vault

Fetched, hash-verified, and kept

Any tool that fetches a script from its own servers is a known client asking for a file, and a server can answer it differently: clean JavaScript for the address that keeps requesting it, a skimmer for everyone else. Cloaking like that is ordinary attacker behaviour, and it defeats analysis performed on a copy nobody's browser ever ran.

Browsers report a cryptographic fingerprint of every script they actually execute. We fetch the file, hash what we receive, and archive it only when the bytes match what a real visitor's browser reported. The stored copy is therefore provably the code that ran on that visitor's machine, which is the artefact an investigation needs and the one an assessor can rely on.

Learn more about Script Vault →
Enforcement Without an Agent

The browser is already an enforcement point

Blocking does not require code of ours in your pages. An enforcing Content Security Policy has the browser refuse unauthorised scripts outright; Integrity Policy requires that scripts carry integrity metadata; Permissions Policy withdraws capabilities entirely. All of it is enforced by the browser, before any script gets the chance to run, with nothing that has to load first.

Learn more about Content Security Policy →
Get Started

Try it without adding anything.
Free for 30 days.

One header. No code. Nothing added to your site, and nothing that has to load before your own scripts do.

30-day free trial  ·  One header  ·  No code  ·  Cancel anytime

FAQ

Frequently asked questions

A plain endpoint receives violation reports and never sees a line of code, which is a fair description of most of them and not of this one. Browsers report a cryptographic fingerprint of every script they execute; Script Vault fetches that file, re-hashes it, and archives the copy only when the bytes match.

Anything that fetches a script itself is a known client that can be served something other than what your visitors get, so clean code for the fetcher and a skimmer for everyone else defeats it. A hash reported by the browser that ran the code cannot be cloaked that way, because it describes what actually executed on a real visitor's machine.

Blocking is usually presented as something that needs a vendor's code running alongside yours, when the browser is already an enforcement point and is closer to the visitor than any script can be. An enforcing Content Security Policy refuses unauthorised scripts outright, Integrity Policy requires that scripts carry integrity metadata, and Permissions Policy withdraws capabilities entirely. None of it involves anything of ours loading.

Where the watching is done by a script in your page, that script has to load, has to execute, and has to get there before the code it is meant to be watching, which is why agents ask to be placed first. Anything ahead of it is unobserved, and an injected skimmer has every reason to be early. A policy arrives in the response headers, so it constrains the very first request the page makes and every one after it, with no race to lose.

A third-party tag with neither async nor defer, placed before everything else, is the most render-blocking position available: the parser stops, and a DNS lookup, a TCP connection and a TLS handshake to another origin all complete before your own content continues. Standard guidance for third-party JavaScript is to defer it precisely to avoid this, but deferring would let other scripts run first and escape observation, so the cost is structural rather than fixable. A response header has nothing to fetch and nothing to execute.

It widens it. The vendor's host has to be allowed in script-src so their file may execute and in connect-src so it may send what it collects, usually as a wildcard across the whole domain rather than the single file, which means adopting the tool starts by loosening the policy in the two directives that matter most. The tag also carries no integrity attribute and cannot really have one, because a script that updates itself cannot be pinned to a hash. With Report URI the policy is the product: nothing is added to it, and Integrity Policy lets you require that everything else on the page is pinned.

When the tool is a script on your pages, an outage tends to mean the watching stops for those sessions without anything announcing it, so you lose coverage rather than availability and find out afterwards. Report URI is not in your pages at all: the policy is already there and keeps enforcing, so if we are unavailable your site serves exactly as normal and reports queue until we are back.

Both requirements ask you to inventory the scripts on your payment pages, justify them, and detect when they change. Script Watch maintains that inventory from what browsers really loaded, Script Vault keeps the verified file behind each entry, and both cover authenticated checkout pages rather than only what an external scan can reach.
Track Record

Who runs this

Report URI has collected browser security telemetry since 2015. Have I Been Pwned has run on it for years, and our case studies cover several of the most examined client-side incidents in the industry — the British Airways and Ticketmaster Magecart attacks, the European Space Agency, and the cryptojacking compromises at the Information Commissioner's Office and the United States Courts.

The platform is built by people who work on the standards themselves, including Device Bound Session Credentials, passkeys and WebAuthn, with an open-source library published for the former.

Keep Comparing

Other tools in this category