Subresource Integrity (SRI)
Secure your application by verifying that CDN-hosted Focus UI files haven't been tampered with using Subresource Integrity hashes.
What is SRI?
Subresource Integrity (SRI) is a security feature that enables browsers to verify that files they fetch from a CDN are delivered without unexpected manipulation. It works by providing a cryptographic hash that the browser checks against the downloaded file.
Why use SRI? If a CDN is compromised, an attacker could inject malicious code into the files. SRI prevents this by ensuring the file matches the expected hash.
Current Version SRI Hashes
Trusted Source
IMPORTANT: Always verify SRI hashes from the GitHub Releases page,
not from the CDN itself. Each release includes an SRI.txt file with verified hashes.
If the CDN is compromised, an attacker could modify both the files AND any documentation on the CDN. GitHub releases are immutable and cryptographically signed, making them the source of truth.
SRI hashes for Focus UI v2.0.0 (verified from GitHub Release):
CSS
<link
rel="stylesheet"
href="https://cdn.focus-ui.de/v2.0.0/focus-ui.css"
integrity="sha384-6Hu/ziK6k/v37QJ71CE74k5b3yiCB7bzjoSEBzEgiACNXOGuOl2mqprjy0tgjDiN"
crossorigin="anonymous">
JavaScript (UMD Bundle)
<script
src="https://cdn.focus-ui.de/v2.0.0/focus-ui.js"
integrity="sha384-BCzathzuj+ySZndSOrGc2tVC9Dn1UZhwZhUsk4NnlTzM0oo9FYlb+0BrJt15QKGG"
crossorigin="anonymous"></script>
JavaScript (Minified)
<script
src="https://cdn.focus-ui.de/v2.0.0/focus-ui.min.js"
integrity="sha384-GDpJYcUtWAkXeEY/ue8/sOuXYpDByN+yjFe52qcCpTwGYyVze1NxcY1qeImkQNHH"
crossorigin="anonymous"></script>
JavaScript (ES Module)
<script
type="module"
src="https://cdn.focus-ui.de/v2.0.0/focus-ui.esm.js"
integrity="sha384-MkaWlGf4sKXNEF9pVcg6Z8NqQ6UBYIPjxc/4PVAA5s/4YORciZdKk5A/kTN5p5T8"
crossorigin="anonymous"></script>
Complete Example
Here's a complete HTML page using SRI for both CSS and JavaScript:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Focus UI with SRI</title>
<!-- Focus UI CSS with SRI -->
<link
rel="stylesheet"
href="https://cdn.focus-ui.de/v2.0.0/focus-ui.css"
integrity="sha384-6Hu/ziK6k/v37QJ71CE74k5b3yiCB7bzjoSEBzEgiACNXOGuOl2mqprjy0tgjDiN"
crossorigin="anonymous">
</head>
<body>
<h1>Hello, Focus UI!</h1>
<button class="focus-btn focus-btn-primary">Click me</button>
<!-- Focus UI JavaScript with SRI -->
<script
src="https://cdn.focus-ui.de/v2.0.0/focus-ui.min.js"
integrity="sha384-GDpJYcUtWAkXeEY/ue8/sOuXYpDByN+yjFe52qcCpTwGYyVze1NxcY1qeImkQNHH"
crossorigin="anonymous"></script>
</body>
</html>
How SRI Works
- Hash Generation: A cryptographic hash (SHA-256, SHA-384, or SHA-512) is computed for the file
- HTML Attribute: The hash is added to the
integrityattribute in your HTML - Browser Verification: When the browser downloads the file, it computes the hash and compares it
- Success or Failure: If hashes match, the file loads. If not, the browser blocks it and throws an error
SHA-384 vs SHA-256
Focus UI uses SHA-384 hashes, which provide a good balance between security and hash length. SHA-256 is also supported by browsers, but SHA-384 offers stronger security with minimal performance overhead.
The crossorigin Attribute
When using SRI, you must include the crossorigin="anonymous"
attribute. This tells the browser to perform a CORS request without sending credentials.
<!-- ✅ CORRECT - Has crossorigin attribute -->
<script
src="https://cdn.focus-ui.de/v2.0.0/focus-ui.min.js"
integrity="sha384-GDpJYcUtWAkXeEY/ue8/sOuXYpDByN+yjFe52qcCpTwGYyVze1NxcY1qeImkQNHH"
crossorigin="anonymous"></script>
<!-- ❌ WRONG - Missing crossorigin attribute -->
<script
src="https://cdn.focus-ui.de/v2.0.0/focus-ui.min.js"
integrity="sha384-GDpJYcUtWAkXeEY/ue8/sOuXYpDByN+yjFe52qcCpTwGYyVze1NxcY1qeImkQNHH"></script>
Generating SRI Hashes
If you're self-hosting or want to verify the hashes yourself:
Using OpenSSL (Linux/macOS)
# Download the file
curl -O https://cdn.focus-ui.de/v2.0.0/focus-ui.min.js
# Generate SHA-384 hash
openssl dgst -sha384 -binary focus-ui.min.js | openssl base64 -A
# Output:
# GDpJYcUtWAkXeEY/ue8/sOuXYpDByN+yjFe52qcCpTwGYyVze1NxcY1qeImkQNHH
Using an Online Tool
You can also use online SRI hash generators:
- SRI Hash Generator - Enter a CDN URL to generate the hash
Using Node.js
import { createHash } from 'crypto'
import { readFileSync } from 'fs'
const file = readFileSync('focus-ui.min.js')
const hash = createHash('sha384').update(file).digest('base64')
console.log(`sha384-${hash}`)
SRI Hashes for All Versions
Where to Find Official SRI Hashes
For security, always get SRI hashes from the trusted source:
-
GitHub Releases (Primary Source)
Go to github.com/jannikjordan/focus-ui/releases
Each release includes anSRI.txtfile with verified hashes -
This Documentation (Reference Only)
The hashes below are for quick reference, but always verify against GitHub releases -
Generate Yourself (Most Secure)
Download the files and compute hashes yourself using the methods in the "Generating SRI Hashes" section
Never Trust Hashes from the CDN
DO NOT rely on any versions.json or documentation hosted on the CDN itself.
If the CDN is compromised, all files on it (including metadata) could be modified.
Only trust:
- GitHub Releases (cryptographically signed by GitHub)
- This repository's source code (protected by git integrity)
- Hashes you generate yourself from downloaded files
Current Version Hashes
The following hashes are provided for convenience. Always verify against the GitHub Release.
| Version | File | SHA-384 Hash |
|---|---|---|
| v2.0.0 | focus-ui.css |
sha384-6Hu/ziK6k/v37QJ71CE74k5b3yiCB7bzjoSEBzEgiACNXOGuOl2mqprjy0tgjDiN |
focus-ui.js |
sha384-BCzathzuj+ySZndSOrGc2tVC9Dn1UZhwZhUsk4NnlTzM0oo9FYlb+0BrJt15QKGG |
|
focus-ui.min.js |
sha384-GDpJYcUtWAkXeEY/ue8/sOuXYpDByN+yjFe52qcCpTwGYyVze1NxcY1qeImkQNHH |
|
focus-ui.esm.js |
sha384-MkaWlGf4sKXNEF9pVcg6Z8NqQ6UBYIPjxc/4PVAA5s/4YORciZdKk5A/kTN5p5T8 |
Don't Use /latest/ with SRI
Never use SRI with the /latest/ URL path:
<!-- ❌ WRONG - /latest/ content changes, hash will break -->
<script
src="https://cdn.focus-ui.de/latest/focus-ui.min.js"
integrity="sha384-..."
crossorigin="anonymous"></script>
Why? The /latest/ path points to the most recent version,
so its content changes with each release. This will cause SRI verification to fail.
Solution: Always use versioned URLs like /v2.0.0/ when using SRI.
Browser Support
SRI is supported in all modern browsers:
- Chrome/Edge 45+
- Firefox 43+
- Safari 11.1+
- Opera 32+
Older browsers that don't support SRI will simply ignore the integrity attribute
and load the file normally (without verification).
Best Practices
- Always use SRI for CDN resources - This is your defense against CDN compromise
- Pin to specific versions - Use
/v2.0.0/not/latest/ - Include crossorigin - Required for SRI to work
- Test after updates - When upgrading Focus UI, update both the URL and the hash
- Self-host critical apps - For maximum security, self-host instead of using CDN
Troubleshooting
File Won't Load / SRI Verification Failed
If you see errors like "Failed to find a valid digest in the 'integrity' attribute":
- Check the hash - Make sure you copied the entire hash correctly
- Check the URL - Ensure the version in the URL matches the hash version
- Check crossorigin - Make sure you have
crossorigin="anonymous" - Verify the file - Generate the hash yourself to confirm it matches
How to Verify the Hash
# Download and verify the hash matches
curl https://cdn.focus-ui.de/v2.0.0/focus-ui.min.js | \
openssl dgst -sha384 -binary | \
openssl base64 -A
# Should output:
# GDpJYcUtWAkXeEY/ue8/sOuXYpDByN+yjFe52qcCpTwGYyVze1NxcY1qeImkQNHH