← All articles · May 4, 2026 · CheckoutProof

PCI 6.4.3 for Stripe Elements Merchants: Exactly What You Owe

If you use Stripe Elements to take payments on your own domain — the card form is an iframe served by Stripe but rendered inside a page your site renders — this article is the precise division of PCI 6.4.3 responsibility between you and Stripe.

The short version: Stripe handles 6.4.3 for the iframe. You handle 6.4.3 for the page around it. The interesting question is what “the page around it” actually means, and that’s most of the article.

The setup we’re talking about

Stripe ships several payment integrations. They have very different PCI implications:

This article is about the middle one. If you’re not sure which you have: open your checkout page, view the source, search for stripe.js or js.stripe.com/v3. If those load and the card field looks like an iframe, you’re on Elements.

What Stripe handles

For the iframe itself — the part where the customer types the card number — Stripe handles:

If you read Stripe’s Responsibility Matrix for Elements, this is what they’ve taken on. None of those things involve you.

What you handle

Everything else on the page. Specifically:

The script inventory of your checkout page, including:

The card form is in an iframe, but the iframe is sitting inside your page. A skimmer on your page can:

PCI 6.4.3 exists because all of the above are real attacks, and the iframe-isolation argument doesn’t actually protect against them.

Why the iframe doesn’t save you

A common reaction: “But the card data is in an iframe Stripe controls. My scripts can’t read it.”

That’s true for the card data itself — same-origin policy prevents your page’s JavaScript from reading inside Stripe’s iframe. But the surrounding attacks don’t need to read inside the iframe.

Overlay attack. A skimmer on your page can position a transparent <input> over the iframe’s location and capture keystrokes from the user as they type. Modern browsers mitigate some of this, but not all variants.

Form-hijack attack. A skimmer can intercept the form submission, copy the customer’s name, address, and email (which are on your page, outside the iframe), and POST that to an attacker. Card numbers aren’t all you need to protect; PII is also a target.

Iframe substitution. A skimmer can find Stripe’s iframe element in the DOM and replace its src with a phishing site that looks identical. The customer types into what they think is Stripe’s form; it’s actually the attacker’s form on the attacker’s domain.

Keystroke logging from outside the iframe. The iframe’s input fields are protected from page scripts, but a skimmer can listen to page-level events that fire when the user clicks into the iframe (focus events on the parent element are visible) and combine that with timing attacks against publicly-observable browser metrics.

None of these are theoretical. Magecart groups have used variants of all of them.

What you specifically have to do

The 6.4.3 control breakdown for a Stripe Elements merchant:

1. Inventory the scripts on your checkout page

Same as any 6.4.3 inventory. Open the checkout in a real browser, capture every script that runs. The Stripe iframe loads js.stripe.com/v3/ — that’s one script in your inventory. Inside the iframe is Stripe’s problem. Outside is yours.

A typical Stripe Elements checkout has 15–25 scripts on the surrounding page even if “we just use Stripe.” The reason is everything else: GA4, Google Tag Manager, customer service chat, abandoned-cart, recommendation, A/B test, consent management, analytics-of-the-month.

Run a free scan and you’ll have the inventory in 30 seconds.

2. Document business justification for each script

Per the inventory, write down what each script does and who authorized it. The Stripe scripts are easy: “Stripe Elements card-input rendering, authorized by our payment integration.” The third-party scripts are where the audit pain lives.

3. Add SRI to every script that supports it

Stripe’s main script (https://js.stripe.com/v3/) is at a stable URL and supports SRI. Add the integrity attribute. (Stripe publishes the current hash in their integration docs; check it before going live.)

For your other third-party scripts, follow the SRI guide. Most CDN-hosted libraries support it.

4. Add a CSP

You need a script-src allowlist that includes https://js.stripe.com for the iframe init script and a frame-src directive that allows https://js.stripe.com https://hooks.stripe.com. The CSP for checkouts article has a working example specifically for Stripe Elements + WooCommerce.

A common Stripe-specific gotcha: forgetting to allow https://js.stripe.com in connect-src. Stripe.js makes XHR/fetch calls to validate the card data; if connect-src doesn’t allow it, the customer sees a vague “card declined” error.

5. Set up tamper detection per 11.6.1

Weekly automated scan of your checkout page that compares against last week’s baseline. Alerts on changes. See the 11.6.1 article for the full pattern.

6. Get and read your Stripe Responsibility Matrix

Per the January 2025 amendment, you need the matrix on file. It tells you exactly which controls Stripe handles and which they expect you to handle. See the Responsibility Matrix article for how to obtain and read it.

Common shortcuts that don’t work

“We’re SAQ A because Stripe is PCI Level 1.” No. Your eligibility for SAQ A depends on whether your site renders the page where card data is entered. Stripe being a Level 1 service provider has nothing to do with it.

“Stripe.js is in our CSP script-src, so we’re covered.” A script-src allowlist is one of three controls. You also need the inventory and the integrity proofs and the monitoring.

“We’ve never had an incident, so the controls aren’t worth the work.” Magecart attacks are silent by design. Most merchants who got hit didn’t know until card-fraud signals surfaced months later. “We’ve never had an incident” is consistent with both “we have good controls” and “we’ve been compromised and don’t know.”

“Stripe will tell us if our checkout is compromised.” Stripe is monitoring their infrastructure. They are not monitoring the third-party JavaScript on your storefront. That’s exactly what 6.4.3 made the merchant’s responsibility.

The fastest realistic path

If you’re starting from zero:

Today (15 minutes): Run a free scan on your checkout. Save the PDF. You now have your inventory.

This weekend (3 hours): Add SRI to the scripts that support it. Add a starter CSP in Content-Security-Policy-Report-Only mode. Wire up the report endpoint somewhere you’ll see it.

Next weekend (3 hours): Watch the report-only output for a week. Update the CSP based on what real users actually load. Switch to enforcing Content-Security-Policy.

Ongoing (10 minutes a week): Either you or a tool runs the weekly scan, you read the alerts, you investigate anything that changed.

Two weekends and ten minutes a week. That’s the bare minimum to be defensibly compliant on Stripe Elements. Skip it and you’re SAQ A-EP and quietly out of compliance — which is most Stripe Elements merchants today.

The free scan is a good place to start. It’s right here.


Run a free PCI 6.4.3 scan of your checkout page. Get the script inventory and a one-page PDF report. Try it now →