Mapping CVEs to PCI DSS 6.4.3

Permalink to "Mapping CVEs to PCI DSS 6.4.3"

Part of Vulnerability Tracking & Triage, this page shows how to connect the CVEs you already triage to the specific PCI DSS v4.0.1 controls for payment-page scripts, with a script inventory and integrity-assurance record as the evidence.

Quick Reference

Permalink to "Quick Reference"
Requirement (PCI DSS v4.0.1) Scope What it demands
6.3.1 All software Identify security vulnerabilities from a reputable advisory feed and assign a risk ranking
6.3.3 All software Install applicable security patches on a schedule driven by that risk ranking
6.4.3 Payment-page scripts Inventory every browser-loaded script, authorize each with justification, and assure its integrity
11.6.1 Payment-page change detection Alert on unauthorized modification of the payment page’s HTTP headers and script content

6.3.1 and 6.3.3 are your general CVE pipeline. 6.4.3 is the payment-page-specific overlay where Subresource Integrity does the heavy lifting.

What 6.4.3 asks for

Permalink to "What 6.4.3 asks for"

Requirement 6.4.3 exists because a payment page assembles code from many origins — your bundle, a tag manager, an analytics loader, a fraud-scoring widget — and any one of them can be swapped for a card-skimming variant at the CDN or upstream. The requirement breaks the defense into three obligations: inventory every script that loads and executes in the consumer’s browser, authorize each one with a written business justification, and assure the integrity of each so an unexpected change is caught. Integrity assurance is exactly what an SRI hash provides: the browser recomputes the digest of the delivered bytes and refuses to execute anything that does not match the value you authorized. Mapping a CVE into this world means joining two records — the advisory feed that says “package X version Y is vulnerable” and the script inventory that says “script S on the checkout page is built from package X, authorized by owner O, and pinned to SRI hash H.” When those records are linked, a new CVE routes straight to the owning team and the fix is a hash rotation, not an archaeology project. For the CSP directives that pair with the hash, see Configuring Content Security Policy with SRI.

CVE to payment-page script mapping An advisory feed links a CVE to a package, the package maps to an inventoried and authorized script, and the script carries an SHA-384 SRI hash the browser validates before allowing it on the payment page. CVE feed (6.3.1) script inventory + authorization SHA-384 SRI hash (6.4.3 integrity) match → execute tampered → block

Canonical example: script inventory + integrity-assurance record

Permalink to "Canonical example: script inventory + integrity-assurance record"

Keep a single machine-readable inventory that satisfies all three obligations at once — one row per payment-page script, tying it to its package, its CVE tracker, its authorizer, and its SRI hash.

// payment-page-script-inventory.json
{
  "page": "/checkout",
  "reviewed": "2026-07-09",
  "scripts": [
    {
      "id": "checkout-bundle",
      "src": "https://assets.example.com/checkout.4f2a9c.js",
      "package": "internal/[email protected]",
      "justification": "Renders the card entry form and tokenization flow",
      "authorizedBy": "payments-team",
      "cveTracker": "https://github.com/example/checkout-ui/security/advisories",
      "integrity": "sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/ux8JHrklT1RNnZ3d8l6+pNnS3lPmW2"
    },
    {
      "id": "fraud-widget",
      "src": "https://cdn.riskvendor.net/score.1.9.min.js",
      "package": "[email protected]",
      "justification": "Device fingerprint and fraud score at authorization",
      "authorizedBy": "risk-team",
      "cveTracker": "https://osv.dev/list?ecosystem=npm&q=riskvendor-score",
      "integrity": "sha384-h3mQK1p8lTfVn2rXcB9yUeD5oWgS7aZ0kJ4tYpL6xN1qMbC8vRfA2sHdE3uGkPz"
    }
  ]
}

Read a row field by field and each PCI DSS obligation has exactly one place to live: src is the inventory entry, justification and authorizedBy are the authorization, integrity is the assurance control, and cveTracker is the join back to the advisory feed that drives risk ranking.

Anatomy of an inventory row Four fields of a single payment-page script inventory row are shown across the top, each connected downward to the PCI DSS obligation it satisfies: src is the inventory entry, justification and authorizedBy are the authorization, integrity is the integrity assurance, and cveTracker is the vulnerability identification link. One inventory row: which field satisfies which obligation src justification + authorizedBy integrity cveTracker Inventory 6.4.3 element 1 Authorization 6.4.3 element 2 Integrity assurance SHA-384 SRI token Identification 6.3.1 advisory feed A row missing any column cannot stand as 6.4.3 evidence

Each inventoried script renders into the payment page with its authorized hash. The integrity and crossorigin attributes together are what let the browser enforce 6.4.3’s integrity element:

<!-- Correct: integrity + crossorigin both present -->
<script
  src="https://cdn.riskvendor.net/score.1.9.min.js"
  integrity="sha384-h3mQK1p8lTfVn2rXcB9yUeD5oWgS7aZ0kJ4tYpL6xN1qMbC8vRfA2sHdE3uGkPz"
  crossorigin="anonymous"></script>

Regenerate the sha384-… token whenever the vendor ships a patched build in response to a CVE — that hash rotation is the auditable link between the advisory and the deployed fix.

Variants

Permalink to "Variants"

Enforce the inventory with a CSP allow-list

Permalink to "Enforce the inventory with a CSP allow-list"

Back the inventory with a header so an un-inventoried script cannot execute even if it is injected:

Content-Security-Policy:
  script-src 'self' https://assets.example.com https://cdn.riskvendor.net;
  require-sri-for script;
  report-to pci-6-4-3

require-sri-for script refuses any payment-page <script> lacking an integrity attribute — a direct control for the integrity-assurance obligation. The report-to pci-6-4-3 endpoint turns every refusal into a report you can retain as evidence; wiring that endpoint to a pager is covered in Alerting on SRI Failures from CSP Reports.

Assign a risk ranking (6.3.1) per inventoried script

Permalink to "Assign a risk ranking (6.3.1) per inventoried script"

Extend each row with the triaged severity so patch scheduling under 6.3.3 is data-driven:

{ "id": "fraud-widget", "openCves": ["CVE-2026-11842"], "risk": "high", "patchDue": "2026-07-16" }

Feed this from your Triaging npm audit Findings output so severities stay consistent across the program.

Change detection for 11.6.1

Permalink to "Change detection for 11.6.1"

Diff the deployed script hashes against the authorized inventory on a schedule and alert on any drift:

curl -sL "$SRC" | openssl dgst -sha384 -binary | openssl base64 -A
# Compare the output to the inventory's integrity token; a mismatch is an unauthorized change

A mismatch on its own is not yet an incident — it is a question. The diff tells you the bytes moved; only the deploy log tells you whether the move was authorized. Route the two answers differently, because a rotation you approved and a rotation you did not are the same signal with opposite consequences.

Routing a hash-diff result A decision tree starting from the nightly hash diff: if the live hash matches the authorized token the run is logged as change evidence, otherwise the deploy log is checked, and an authorized change becomes a hash rotation while an unauthorized one raises an 11.6.1 alert. Nightly hash diff Live hash = authorized token? yes Hashes agree: log the run as 11.6.1 evidence no Authorized deploy or vendor patch? yes Rotate the inventory hash and re-record the approver no Unauthorized modification: raise the 11.6.1 alert and freeze the deploy

Gotchas and Edge Cases

Permalink to "Gotchas and Edge Cases"
  • Omitting crossorigin="anonymous" breaks the integrity control silently. On a cross-origin payment-page script the browser makes a no-CORS request and receives an opaque response whose bytes it cannot read, so it blocks the script without ever checking the hash — or, worse in an audit, the check is skipped rather than enforced. Every SRI-protected tag must carry crossorigin="anonymous"; this is the single most common way a 6.4.3 integrity control is deployed but not actually functioning. The request-mode details behind that behaviour, including the Access-Control-Allow-Origin header the vendor must return, are set out in How CORS and crossorigin Affect SRI.

  • 6.4.3 covers executed scripts, not just your bundle. Tag managers, A/B tools, and vendor loaders inject additional scripts at runtime that never appear in your source HTML. If the inventory only lists build-time scripts, the injected ones are unauthorized and unhashed. Enforce require-sri-for and inventory the tag manager’s payloads too — Applying SRI to Google Tag Manager walks through hashing a container and the tags it injects.

  • A stale hash after a vendor patch fails closed. When a fraud or analytics vendor pushes a CVE fix, the served bytes change and the old SRI hash stops matching — the script is blocked and checkout can break. Treat vendor patch notifications as a hash-rotation task with an SLA, not an afterthought.

  • SRI does not prove the code is safe, only unchanged. A hash authorizes a specific version, including a version that itself contains a CVE. Integrity assurance (6.4.3) and vulnerability identification (6.3.1) are separate obligations; a matching hash on vulnerable code still needs patching under 6.3.3.

  • Inline scripts have no src to hash. SRI applies to externally fetched resources. Inline payment-page scripts need a CSP hash or nonce instead, so an inventory built only around SRI tokens will miss them.

Verification Steps

Permalink to "Verification Steps"

1. Confirm every inventoried script has a matching live hash

Permalink to "1. Confirm every inventoried script has a matching live hash"
jq -r '.scripts[] | "\(.src) \(.integrity)"' payment-page-script-inventory.json | \
while read SRC HASH; do
  LIVE="sha384-$(curl -sL "$SRC" | openssl dgst -sha384 -binary | openssl base64 -A)"
  [ "$LIVE" = "$HASH" ] && echo "OK   $SRC" || echo "DRIFT $SRC"
done

Expected output — OK for every row. A DRIFT line is an unauthorized change and an 11.6.1 alert.

2. Confirm the browser enforces the hash

Permalink to "2. Confirm the browser enforces the hash"

Load /checkout in Chrome with DevTools open and tamper with one served script. A blocked script logs:

Failed to find a valid digest in the 'integrity' attribute for resource
'https://cdn.riskvendor.net/score.1.9.min.js'. The resource has been blocked.

3. CI gate — no un-inventoried payment-page script

Permalink to "3. CI gate — no un-inventoried payment-page script"
- name: Assert payment-page scripts are inventoried
  run: node scripts/verify-payment-inventory.js --page dist/checkout.html \
       --inventory payment-page-script-inventory.json

The script exits non-zero if the rendered page loads a <script> whose src is absent from the inventory or whose integrity token does not match, blocking the deploy.

Frequently Asked Questions

Permalink to "Frequently Asked Questions"
What does PCI DSS 6.4.3 actually require?

Requirement 6.4.3 says every script loaded and executed in the consumer’s browser on a payment page must be inventoried, authorized with justification, and assured of integrity. Subresource Integrity is the primary browser-native control that satisfies the integrity-assurance element.

How is 6.4.3 different from 6.3.1 and 6.3.3?

6.3.1 requires identifying vulnerabilities via an advisory feed, and 6.3.3 requires installing security patches on a risk-based schedule. 6.4.3 is specific to payment-page scripts and adds the inventory, authorization, and integrity-assurance obligations on top of general vulnerability management.

Does an SRI hash satisfy 6.4.3 on its own?

SRI satisfies the integrity-assurance element, but 6.4.3 also demands inventory and authorization. You still need a maintained script inventory with justifications and a change-detection method. SRI plus a CSP allow-list plus the inventory record together satisfy the requirement.

How often does the change-detection check have to run?

Requirement 11.6.1 expects the change- and tamper-detection mechanism to evaluate the payment page at least once every seven days, or at a frequency justified by a targeted risk analysis performed under requirement 12.3.1. Nightly is the common choice because the diff is cheap to run and it shortens the window between a silent vendor swap and the alert that catches it.

Does self-hosting a vendor script remove the 6.4.3 obligation?

No. The script still loads and executes in the consumer’s browser, so it stays in the inventory with a justification, an approver, and an integrity control. What self-hosting changes is where the change-control point sits: the vendor can no longer swap the served bytes without you republishing them, so hash rotation becomes a deliberate step inside your own pipeline.

Permalink to "Related"

Related Articles

Triaging npm audit Findings
Vulnerability Tracking & Triage Supply Chain Auditing & Depend…