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

HTML
<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)

HTML
<script
  src="https://cdn.focus-ui.de/v2.0.0/focus-ui.js"
  integrity="sha384-BCzathzuj+ySZndSOrGc2tVC9Dn1UZhwZhUsk4NnlTzM0oo9FYlb+0BrJt15QKGG"
  crossorigin="anonymous"></script>

JavaScript (Minified)

HTML
<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)

HTML
<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:

HTML
<!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

  1. Hash Generation: A cryptographic hash (SHA-256, SHA-384, or SHA-512) is computed for the file
  2. HTML Attribute: The hash is added to the integrity attribute in your HTML
  3. Browser Verification: When the browser downloads the file, it computes the hash and compares it
  4. 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.

HTML
<!-- ✅ 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)

Bash
# 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:

Using Node.js

JavaScript
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:

  1. GitHub Releases (Primary Source)
    Go to github.com/jannikjordan/focus-ui/releases
    Each release includes an SRI.txt file with verified hashes
  2. This Documentation (Reference Only)
    The hashes below are for quick reference, but always verify against GitHub releases
  3. 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:

Older browsers that don't support SRI will simply ignore the integrity attribute and load the file normally (without verification).

Best Practices

  1. Always use SRI for CDN resources - This is your defense against CDN compromise
  2. Pin to specific versions - Use /v2.0.0/ not /latest/
  3. Include crossorigin - Required for SRI to work
  4. Test after updates - When upgrading Focus UI, update both the URL and the hash
  5. 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":

  1. Check the hash - Make sure you copied the entire hash correctly
  2. Check the URL - Ensure the version in the URL matches the hash version
  3. Check crossorigin - Make sure you have crossorigin="anonymous"
  4. Verify the file - Generate the hash yourself to confirm it matches

How to Verify the Hash

Bash
# 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