Features

Payment-page script authorization

PCI DSS 4.0 requirement 6.4.3 asks that every script on a payment page is authorized, that its integrity is assured, and that an inventory records why it is needed. HeaderHawk keeps the decision itself. A named person authorizes or rejects each script and writes down why, and no later decision overwrites an earlier one.

A Content Security Policy lists the hosts a page may load scripts from. It is the control, and it belongs in front of every checkout. It does not record who approved a script, what they looked at, or why the page needs it, and an assessor asks all three.

Plans
The Professional and Business plans
In the dashboard
Scripts › Payment pages

What's at stake

An allowlist is not a decision

Most teams can show which hosts their checkout may load from. Far fewer can show who decided each script belonged there, and what it was when they decided.

No record

The policy says where, not who or why

A host added to script-src last spring is still there, and nobody remembers the ticket. When the assessor asks why each script is there, the policy has no answer.

Unannounced change

The approved script is not the same file any more

Vendors ship to the same URL. An approval of js.vendor.com in March says nothing about the bytes your customers ran in September, and neither does the policy that allowed it.

Gone by audit

The version you decided about has been replaced

When someone asks what was in that file on the day, the origin serves today's version, and nobody kept the old one.

What it does

A decision per script, kept like evidence

Authorize or reject, and say why

Every script browsers report on your payment pages, and every script the daily scan finds in their HTML, arrives in a review queue. Someone authorizes or rejects it and gives a reason. A decision with no justification is refused, so every approval in the inventory can be explained.

Members and above decide, and every role, viewers included, can read the decisions. A justification can run to 2,000 characters, room for a paragraph an assessor can follow.

One decision, in the inventory's own columns
Script URL       https://js.stripe.com/v3/
Status           authorized
Integrity mode   any_content
Justification    Stripe Elements renders the card fields in
                 an iframe. Required by our payment provider;
                 reviewed with the payments team.
Decided by       A. Rivera
Decided at       2026-09-18T14:02:11Z
Seen by          browsers and scan
First seen       2026-08-02T09:15:40Z

Pin the versions you reviewed, or accept the URL

Each authorization has an integrity mode. Pin up to 50 hashes you reviewed, and any other version is flagged as a change. Or accept any content from the URL, which suits a vendor that ships several times a week, and new versions raise no alert.

Every hash a script has been seen with is listed beside it, marked as reported by browsers, found by the daily scan, or both.

Scripts › Payment pages, on the Professional and Business plans: eight scripts on a shop's Checkout and Payment methods pages, one row each with its risk, its decision, the pages it ran on and when it was last seen. Six are authorized, four of them for their pinned hashes only, one awaits review and one, a tag manager, is rejected. jQuery 3.4.1 is identified from its bytes and marked Medium for its advisories, Alpine.js 3.15.0 has none known, and four scripts are marked No SRI because a browser loaded them with no integrity check.
In the dashboard: Scripts › Payment pages

An append-only history

Decisions are append-only. The newest becomes the script's status, and every earlier one stays, with who made it and when. Moving to a smaller plan keeps the record. A team that has made decisions can still read, filter and export them.

The inventory exports as CSV, one row per script and payment page, with the library each hash was identified as, its advisories, the decision, its justification, who made it and when. The file opens by saying what it cannot show.

The top of the export (lines wrapped here to fit)
# This is what browsers reported and what HeaderHawk's
# daily scan of each payment page found. It is not proof
# that nothing else ran.
Payment page,Page pattern,Script URL,Library,
  Library version,Identification,Advisories,
  Advisory IDs,Worst severity,Fixed in,Status,
  Integrity mode,Pinned hashes,Hashes seen,
  Justification,Decided by,Decided by email,
  Decided at,First seen,Last seen,Seen by,
  Last scanned,Gone from page (last found)

Alerts when a payment page's scripts change

A script new to the site running on a payment page, an unpinned version of a pinned script, or a rejected script running again raises an alert through your rules. Anyone can post a report, so these wait until browsers on two different networks have reported the script within 24 hours, or until the page's daily scan fetches it, which alerts on that scan. A site gets at most five new or changed script alerts an hour, then one summary.

The daily scan also reports when a script has left a payment page, and when it seems to have moved host, a pairing by file name that the alert calls a guess. Both come from what the scan found, never from browsers going quiet. A site's first day and a page's first scan set the baseline without alerting.

The five script alerts, as a rule lists them
New script on a payment page
Pinned script changed
Rejected script seen again
Script gone from a payment page
Script moved to another origin

The file behind the decision, kept

When a new version of a payment-page script appears, HeaderHawk fetches it once and keeps the file only if its SHA-256 matches the reported hash, so the copy is the code your visitors ran. Owners and admins can download it from the script's page. Every download is recorded, and copies are kept for twelve months.

The fetch is never retried. A file changed or removed before the fetch is recorded as a mismatch, with the fingerprint of what was served instead, and no copy is kept. A short-lived injected payload usually ends up here, and the record says so.

Known vulnerabilities next to the decision

Where a script's hash identifies a library version, the advisories published against that version appear beside the decision, with their severity and the release that fixes them. A high or critical one raises an alert once. The check runs every day, so a script authorized months ago still meets an advisory published this morning.

The 6.4.3 answer, on every plan

The dashboard's Compliance page reads these records for one site and says whether 6.4.3 is met, partially met or not met, with the facts behind the verdict and what is missing. It is a readiness view, not an attestation. The PCI DSS page sets out which parts of 6.4.3 and 11.6.1 the browser layer covers.

How it runs

One keyword in your policy. Nothing on the checkout page.

A site's setup panel writes the headers for the report types you switch on. With script hashes on, the policy gains one keyword:

Reporting-Endpoints: headerhawk="https://k3x9mp2nq7ab.ingest.us.headerhawk.com/r"
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' 'report-sha256'; report-uri https://k3x9mp2nq7ab.ingest.us.headerhawk.com/r; report-to headerhawk
  • The hashes come from 'report-sha256' in your script-src, which asks Chrome and Edge to report each script they fetch. It allows and blocks nothing.
  • No agent, SDK, tag or proxy goes on the payment page, so none of our code runs on the page you are keeping clean.
  • The daily scan fetches each payment page once from our infrastructure, never through your visitors.
  • A decision is recorded, not enforced. Your policy and your deploys decide what runs, and the record shows what you decided.

Scope

One layer, and where it stops

Authorization is the record half of 6.4.3. The control half is your policy and the integrity attributes on your tags, which the browser enforces. A rejected script runs until your site or your policy stops it. The inventory shows what browsers reported and the scan found, which is not proof that nothing else ran.

Script authorization doesIt does not replace
Records who authorized or rejected each payment-page script, when, and whyYour Content Security Policy, which stops an unapproved script loading
Pins the versions you reviewed, and alerts on one you did notSubresource Integrity on the tag, which stops a changed file running
Keeps a verified copy of new versions it could fetch unchangedThreat intelligence on script hosts. HeaderHawk records decisions and does not score domains
Exports the inventory and its decisions as CSV for your assessorYour QSA's judgement, since a readiness view is not an attestation

Put a reason next to every script

Script authorization is on the Professional and Business plans. Mark your checkout as a payment page and the review queue fills from the next report.