Subresource integrity for ecommerce: protecting payment page scripts
Subresource Integrity (SRI) is a browser security feature that lets you verify that files fetched from external sources have not been tampered with. It works by comparing a cryptographic hash you specify in your HTML against the hash of the file the browser actually downloads. If they do not match, the browser refuses to execute the file.
For ecommerce payment pages, SRI is one of the two technical controls that directly address PCI DSS 4.0 Requirement 6.4.3's mandate to protect scripts from unauthorized modification. The other is Content Security Policy. Together, they form a defense-in-depth approach to payment page script security.
How SRI works: the integrity attribute
SRI is implemented via the integrity attribute on script and link elements. The value is a hash algorithm prefix followed by the base64-encoded hash of the expected file content.
A script tag with SRI looks like this: <script src="https://cdn.example.com/analytics.js" integrity="sha384-abc123..." crossorigin="anonymous"></script>
The crossorigin="anonymous" attribute is required for SRI to work with cross-origin resources. Without it, the browser cannot perform the integrity check because it cannot access the response headers needed to compare the hash. When crossorigin is set, the server must respond with appropriate CORS headers (Access-Control-Allow-Origin) for the resource to load.
The process: the browser downloads the script file, computes the hash of the downloaded content, compares it to the hash in the integrity attribute. Match: the script executes. Mismatch: the browser blocks execution and logs a network error. No warning to the user, no fallback, just a blocked script.
Which hash algorithms to use
SRI supports SHA-256, SHA-384 and SHA-512. SHA-256 is the most common. SHA-384 offers higher security and is recommended by PCI DSS guidance. SHA-512 offers the highest security but produces a longer hash string.
You can specify multiple hashes in a single integrity attribute, separated by spaces: integrity="sha256-HASH1 sha384-HASH2". The browser uses the strongest algorithm it supports. This is useful when deploying to environments with older browser versions that may have different algorithm support.
For PCI DSS compliance, use SHA-256 at minimum. SHA-384 is safer and the string length difference is negligible in practice.
Generating SRI hashes
There are several ways to generate the hash for a resource:
- Online tool: srihash.org accepts a URL and returns the integrity attribute string. Convenient for one-off hash generation.
- Command line (macOS/Linux):
curl https://cdn.example.com/script.js | openssl dgst -sha384 -binary | openssl base64 -Aproduces the base64 hash. Prefix withsha384-to form the complete integrity value. - Node.js:
crypto.createHash('sha384').update(fileContent).digest('base64'). This is the approach used in build pipelines to automate SRI generation. - Webpack SRI plugin: the
webpack-subresource-integrityplugin automatically adds integrity attributes to all script and link tags in the build output. This is the most reliable approach for bundled assets.
One critical detail: the hash must be computed from the exact bytes that the browser will download. If the CDN compresses the resource with gzip or Brotli before sending it, the hash must be of the uncompressed content. The browser decompresses before hashing, so you hash the uncompressed version. Most SRI hash generation tools handle this correctly.
Which scripts on payment pages need SRI
PCI DSS 4.0 Requirement 6.4.3 requires script authorization and integrity protection for scripts loaded on payment pages. In practice, this means every script tag on your checkout page that loads from a third-party domain.
Priority scripts for SRI:
- Payment processor scripts: Stripe.js (js.stripe.com), Braintree (js.braintreegateway.com), Adyen (checkoutshopper-live.adyen.com). These have the highest sensitivity: a compromised version could intercept payment data directly in the hosted fields.
- Analytics and tracking: Google Analytics, Google Tag Manager, Facebook Pixel, TikTok Pixel. These scripts run on checkout pages and have DOM access. A compromised analytics script is a viable Magecart vector.
- A/B testing: Optimizely, VWO, Adobe Target. These tools inject and modify DOM elements, giving them significant access to page content.
- Customer support: Zendesk, Intercom, Gorgias. Chat widgets loaded on checkout pages have full DOM access.
Scripts loaded from your own domain (hosted on your CDN or server) are covered by your deployment pipeline integrity: if an attacker modifies a self-hosted script, that is a server compromise, which is addressed by other PCI DSS controls (file integrity monitoring, access controls). SRI is primarily a protection against third-party supply chain compromise.
Limitations of SRI
SRI is a strong control but has several limitations that the security team must understand:
- Dynamic scripts cannot be integrity-checked: SRI requires knowing the exact content of the script at the time you write the integrity attribute. Scripts that are generated dynamically (different content per request, A/B test variants, personalization-driven content) cannot have a fixed hash. The hash would be different every time the script is fetched.
- Versioned CDN URLs break on updates: many vendors serve scripts from versioned or unversioned CDN URLs. An unversioned URL (e.g.,
/analytics.jswith no version number) means the file content changes when the vendor updates it. Your SRI hash immediately fails after any vendor update. You must regenerate and redeploy the hash after every vendor update. - Inline scripts are out of scope: SRI applies to externally loaded scripts, not inline scripts. Inline script integrity is addressed by CSP hashes and nonces.
- Browser support is required: all modern browsers (Chrome 45+, Firefox 43+, Safari 10.1+, Edge 17+) support SRI. Internet Explorer does not. For virtually all ecommerce stores, this is not a practical constraint in 2025.
- CORS must be supported: the CDN serving the resource must send
Access-Control-Allow-Originheaders. Most major CDNs and script vendors do. Obscure or self-managed CDNs may not.
Handling versioned scripts and the update challenge
The practical challenge with SRI on third-party scripts is keeping hashes current. When a vendor releases a new version of their script, the content changes, the hash changes, and any SRI check against the old hash fails. The script is blocked. Users see broken functionality.
Mitigation strategies:
- Pin to versioned URLs: use versioned script URLs where the version is explicit in the URL (e.g.,
stripe.js/v3where v3 is a stable major version). Major versions are rarely deprecated without notice. Minor updates are still applied but typically do not change the integrity hash because Stripe serves the same bytes for the same version identifier. - Self-host third-party scripts: download the third-party script, host it on your own CDN and add SRI based on your own copy. You control updates: when the vendor releases a new version, you review it, host the new version and update the hash. This is more work but gives you full control. Note: self-hosting breaks automatic updates, which is both the security benefit and the operational burden.
- Automate hash checking: build a pipeline job that periodically fetches the live version of each critical third-party script, computes its hash and compares it to the hash in your HTML. An alert fires when they diverge. This detects both vendor updates (requiring your hash update) and compromised scripts (requiring incident response). The PCI DSS 4.0 penetration testing requirements also cover testing for script tampering.
SRI and CSP working together
SRI and CSP are complementary controls. CSP prevents scripts from unauthorized sources from loading. SRI verifies that authorized scripts have not been tampered with.
A strict CSP without SRI: an attacker who compromises a script on an authorized CDN can inject malicious code, because the CSP only checks the source domain, not the content.
SRI without CSP: an attacker who injects a reference to a new unauthorized script (on a domain not in your SRI inventory) can bypass SRI because SRI only applies to script tags you have added an integrity attribute to. New script tags injected via a CMS vulnerability or XSS would load without SRI checking. This is exactly how payment page security breaks down in practice.
Together: CSP blocks scripts from unauthorized domains. SRI blocks scripts from authorized domains that have been tampered with. The combination closes both attack vectors.
Implementing SRI on Shopify
Shopify Online Store templates are Liquid files. Adding SRI to a third-party script in a Shopify theme means modifying the Liquid template to include the integrity attribute on the script tag.
Shopify's CDN (cdn.shopify.com) uses versioned asset URLs that change when assets are recompiled. Self-managed theme assets should be integrity-checked as part of the theme deployment process.
For Shopify Checkout (hosted on checkout.shopify.com), you do not control the HTML. Shopify manages SRI for their own checkout scripts. This is part of why using Shopify's hosted checkout reduces your PCI DSS scope.
Implementing SRI on WooCommerce
WordPress enqueues scripts via wp_enqueue_script(). WordPress 5.7+ added native SRI support: you can pass the integrity hash as an additional argument to wp_enqueue_script() and WordPress will add the integrity attribute to the script tag.
For third-party scripts on the checkout page specifically, the implementation is in your theme's functions.php or a custom plugin. Filter the checkout page scripts, add integrity attributes and set the crossorigin attribute.
WooCommerce extensions (plugins) that load scripts on checkout pages are the same challenge as any third-party dependency: you need to add SRI to their scripts or self-host them.
Implementing SRI on Magento
Magento uses a RequireJS-based asset pipeline. Adding SRI to Magento scripts requires modifying layout XML files or creating a custom module that adds integrity attributes during the layout rendering process.
Magento's built-in minification and merging of JavaScript files means the actual bytes served differ from the source files. Hash generation must happen after the build process produces the final merged/minified output, not against the source files.
Magento's deployment pipeline (setup:static-content:deploy) is the right place to automate SRI hash computation. Build tools like Grunt and Webpack can be integrated into Magento's static content deployment to generate and inject integrity attributes.
Frequently asked questions
- What is Subresource Integrity (SRI)?
- SRI is a browser security feature that verifies files fetched from external sources have not been tampered with. It compares a cryptographic hash you specify in your HTML against the hash of the downloaded file. If they do not match, the browser refuses to execute the file.
- Which hash algorithm should I use for SRI?
- Use SHA-384 for PCI DSS compliance. SHA-256 is the minimum acceptable. SHA-384 offers stronger security with negligible performance difference.
- Does SRI work with dynamically updated scripts?
- No. SRI requires knowing the exact content of a script at build time. Scripts that change on every request or auto-update via unversioned URLs will break when the hash no longer matches. Pin scripts to versioned URLs or self-host them.
- How do SRI and CSP complement each other?
- CSP prevents scripts from unauthorized domains from loading. SRI verifies that scripts from authorized domains have not been modified. Together they block both unauthorized sources and tampered content.
Complyko scans your checkout and payment pages for third-party scripts missing SRI hashes. See the full inventory of unprotected scripts in your checkout flow and understand your PCI DSS 6.4.3 exposure.
Get your free scan →