Today we're announcing the open beta of a brand new and incredibly powerful feature on the Report URI platform, CSP Integrity! Having the ability to collect integrity metadata for scripts running on your site opens up a whole new realm of possibilities, and it couldn't be simpler to get started. If you have a few seconds spare, you have enough time to get started now!

A revolution for Content Security Policy
Content Security Policy (CSP) is an incredibly powerful mechanism, allowing you to leverage control over a wide range of resources on your site. You can control where resources are loaded from or where data is sent to, and you can be alerted when things don't go according to plan. But regular readers will already know all of the existing benefits of CSP, so today, let's focus on the latest addition to the CSP arsenal; the collection of integrity metadata.
It's so easy to get started that we can boil it down to two simple steps.
- Ask the browser to send integrity metadata for scripts.
- Tell it where to send the integrity metadata for scripts.
That's really all there is to it, so let's break it down. If you already have a CSP in place, you will need to add the 'report-sha256'
keyword to your script-src
directive, and if you don't have a CSP in place, you can add one with just this directive. This is what your CSP script-src
might look like after you add the new keyword, which I've highlighted in bold:
script-src 'self' some-cdn.com 'report-sha256';
Now that you've added the new keyword to your policy, the browser will send integrity metadata for scripts that load on your site, but you will need to tell the browser where to send it, and for that, we will use the Reporting API. All you have to do to enable this is add a new response header:
Report-To: {"group":"default","max_age":31536000,"endpoints":[{"url":"https://scotthelme.report-uri.com/a/d/g"}],"include_subdomains":true}
This defines a new group called default
and sets the destination for telemetry data to https://scotthelme.report-uri.com/a/d/g
. Please note that you should copy this value from the Setup page in your Report URI account as it will be unique to you and the one shown here is my unique URL for demonstration purposes.
With that, we can now link the two together by adding the report-to
directive to your CSP:
script-src 'self' some-cdn.com 'report-sha256'; report-to default;
All you have to do now is sit back and wait for the telemetry to start rolling in!
Surfacing this in the UI
Processed in the same way that any telemetry sent to us would be, this data will only take a few minutes to start showing up in your dashboard. I've used our 'aggregate' search filter here to grab a list of unique dependencies that have been loaded on our site, and we can start to see the value we can extract from this data.

If we focus on just one of these entries, we can see that a Bootstrap JS file has been loaded.

The browser has reported that the hash of the asset is sha256-wMCQIK229gKxbUg3QWa544ypI4OoFlC2qQl8Q8xD8x8=
, which is helpful in various different ways. If we were loading this file from an external location for example, we could now track the hash over time to see if the file we are being served has changed. We can also use the hash to try and identify if the file we were served is the file we were expecting.
Identifying verified JavaScript files
As you can see from the screenshot above, we have identified that the particular file loaded was a verified file from the 'bootstrap' package, hence the green marker with the library name. Using the hash as a fingerprint to uniquely identify a file is a common approach, but you need to have a reliable and verified library of fingerprints to reference against in order to lookup the fingerprint and know for sure. This is something that we've been working hard to build and so far we have verified fingerprints for 4,268,847 unique JS files from common packages, libraries and dependencies across the Web! As we have the fingerprints for each of those files stored in their sha256, sha 384 and sha512 variants, it means we have a running total of 12,806,541 fingerprints in our database so far! This is a huge amount of valuable information to draw from, and it's something that's available right there in the dashboard.
That's not all, though, there's something even better to add!
Identifying JavaScript vulnerabilities
You may notice that the marker for that file is green, and that means that there are no known issues reported with that particular version of that file/library. If you keep scrolling through your data, you might, if you're unlucky, come across a file that has a red marker instead...

This particular file is from a version of the Bootstrap library that has a known security vulnerability, and we can now surface that information directly to you in our UI. If you click the warning, it will open a small dialog box to give you some quick information on what the minimum version of the library you need to upgrade to is, and it will even link out to the disclosure notice for the vulnerability.

This will be an awesome feature to have, allowing you to keep a close eye on exactly how problematic your JS dependencies are, and potentially avoiding costly issues from using dependencies with known vulnerabilities.
Looking at the new telemetry payload
Defined in the specification as a csp-hash
report, it has a very familiar JSON payload, similar to your typical CSP violation report. Here's a sample of one of our payloads:
{
"csp-hash": {
"destination": "script",
"documentURL": "https://report-uri.com/login/",
"hash": "sha256-wMCQIK229gKxbUg3QWa544ypI4OoFlC2qQl8Q8xD8x8=",
"subresourceURL": "https://cdn.report-uri.com/libs/refresh/bootstrap/bootstrap.bundle.min.js",
"type": "subresource"
}
}
Breaking the fields inside this payload down, it's fairly self-explanatory:
destination
- Only script
is supported for now, with new destinations being planned for future updates.
documentURL
- This is the URL the browser was visiting when the reported resource was observed.
hash
- This is the hash of the resource, which in this case is the sha256 hash as that is what we requested.
subresourceURL
- This is the URL of the script that was requested and the hash is of the content of this file.
type
- Only subresource
is supported for now, with the ability to expand to new types in the future.
Now, with the 'report-sha256'
keyword in place, one of these payloads will be sent for each script that loads on your page!
Quick Tips
I'm sure many people will have some questions that spring to mind after reading this, so let me address some of the most common ones that I encountered during our closed beta testing.
Do I need to build a full CSP?
No! You don't need any CSP at all, you can start monitoring scripts and collecting integrity metadata right away:
Content-Security-Policy-Report-Only: script-src 'report-sha256'; report-to default
Is integrity metadata sent for scripts that load, or scripts that are blocked?
Integrity metadata is only sent for scripts that load on your page. If a script is blocked, it is not requested, so there is no file to provide integrity metadata for.
Will this use a lot of my event quota?
No, we're going to downsample CSP Integrity reports for all customers at a rate of 1/10, so whilst it will of course use some event quota, it should not use excessive amounts.
What happens after the open beta?
CSP Integrity will become an add-on feature for customers on our Ultimate plan and customers on an Enterprise plan in 2026.
Get started now
I will be announcing a webinar to go through the new CSP Integrity feature so keep an eye out for that, but everything you need to get started is right here. It really is as simple as adding those two new values to your CSP and just waiting for the valuable data to start rolling in!