Skip to main content
  1. Posts/

Magecart Moved Its C2 On-Chain. PCI DSS 6.4.3 and 11.6.1 Were Built for This

The takedown model just stopped working
#

Telemetry research on a fresh digital skimming campaign turned up a detail that changes the response playbook: the command-and-control infrastructure lives on Ethereum. The skimmer doesn’t phone home to a domain you can report and sink. It resolves its next instruction and its exfiltration endpoint from smart contracts on-chain, then rotates through dynamically generated infrastructure. The campaign already spans more than 15 smart contracts, several coordinated infrastructure clusters, and dozens of associated domains.

If you’ve worked an e-commerce skimming case, you know the usual flow. You find the injected script, you trace the exfil domain, you get it blocked or taken down, you rotate whatever was exposed. That flow assumes a chokepoint exists: a host to notify, a registrar to lean on, a reputation feed to update. On-chain C2 removes the chokepoint. There’s no provider to contact and nothing to sinkhole. The contract sits on a public ledger that isn’t going anywhere, and the skimmer just reads its next endpoint from it whenever it needs one.

So the detection point moves. If you can’t reliably kill the infrastructure, you have to catch the tampering at the one place it’s guaranteed to surface: the page the customer’s browser actually renders.

On-chain C2 means domain blocklists and takedown requests are no longer a primary control for this class of attack. If your Magecart response still centers on sinkholing the exfil domain, it’s built for the previous generation of this threat.

Why this lands squarely on 6.4.3 and 11.6.1
#

Here’s the part that’s significant for anyone who works PCI e-commerce scope: the two requirements that answer this attack were written for this attack.

PCI DSS 4.0 introduced Requirements 6.4.3 and 11.6.1 to address client-side skimming, and Magecart is the named archetype the Council pointed at. They’ve been mandatory since March 31, 2025, and they carry into 4.0.1 unchanged in intent. The short version:

  • 6.4.3 covers the scripts that load and execute in the consumer’s browser on a payment page. You confirm each script is authorized, you assure the integrity of each script, and you keep an inventory with a written justification for why each one is there.
  • 11.6.1 covers change and tamper detection. You implement a mechanism that alerts on unauthorized modification to the security-impacting HTTP headers and the script contents of the payment page as received by the consumer browser.

Read those two together and you have a control set that assumes exactly what the on-chain campaign does. The attacker doesn’t breach your server. They alter a script the browser loads, and card data leaves straight from the form as the shopper types it. Your server-side logs show a clean transaction the whole time. That gap between “looks fine from the backend” and “card data is walking out the front” is the entire problem, and it’s the reason these requirements exist.

When I went through QSA training, Magecart came up as the canonical example for why the client side needed controls of its own. The point being made then was that a processor iframe protects the fields inside the frame, not the page that frames it. A script in the top-level context can read the DOM, overlay a fake input on top of the iframe, or redirect the form on submit. The training framing has aged well. The campaigns changed their infrastructure, but the reason for the control set didn’t move an inch.

If you’re mapping this internally: 6.4.3 is your inventory and integrity control, 11.6.1 is your detection and alerting control. One tells you what should be running, the other tells you when what’s running changed. You need both, because an inventory without monitoring is a snapshot, and monitoring without an authorized baseline is noise.

The compliant-on-paper trap
#

The failure mode I’d watch for is treating these as a scan you run on a schedule. A weekly crawler that pulls the payment page and diffs the scripts will check a compliance box and miss the attack, for a specific technical reason.

Modern skimmers fingerprint the environment before they fire. They read signals like navigator.webdriver, missing browser runtime objects, DevTools Protocol artifacts, and impossible timing to decide whether they’re looking at a real shopper or an automated check. If the session smells synthetic, the skimmer stays dormant and serves clean code. Your scanner sees nothing. The shopper’s real browser gets the payload.

That’s why 11.6.1 insists on the page as received by the consumer browser, not a lab approximation of it. The control is written against the thing the attacker is actively trying to evade. A monitoring approach that only works against instrumented sessions is measuring the one case the skimmer is built to detect and dodge.

What to actually check
#

If you own e-commerce scope, or you’re advising someone who does, this is where I’d spend time:

  1. Get the script inventory real, not aspirational. Every script that executes on the payment page, including third-party analytics, A/B tooling, session replay, chat widgets, and anything they pull in. Each entry needs an owner, a justification, and an integrity method. If nobody can say why a script is there, that’s your first finding.

  2. Assure integrity, don’t assume it. Subresource Integrity on the scripts that support it, and a Content Security Policy that constrains what can load and where data can go. CSP won’t catch everything on its own, but a tight connect-src and script-src raise the cost of quietly exfiltrating to a new endpoint, on-chain-resolved or not.

  3. Detect against the delivered page. Your 11.6.1 mechanism should reflect what real browsers execute, not what a headless crawler sees. If your current tooling can’t distinguish those two, that’s a gap worth naming out loud before an assessor does.

  4. Alert on header and script change, then rehearse the response. Tamper detection that fires into a queue nobody watches is not detection. Decide how fast you can act on an alert, and make sure the runbook doesn’t depend on a takedown step that no longer works here.

  5. Re-check your SAQ eligibility. The eligibility criteria for the lighter self-assessment path narrowed, in part because so few real payment pages are free of third-party scripts. If you assumed you were out of scope for 6.4.3 and 11.6.1, confirm that assumption still holds.

The infrastructure story is the attention-grabber, and moving C2 on-chain is a real shift in how takedown works. The defensive story is quieter and more durable: the client side is where card data actually leaks, the two requirements that cover the client side were written for exactly this threat, and they hold up whether the C2 sits on a bulletproof host or a smart contract. The attackers changed their plumbing. The control set didn’t need to.

Juan Carlos Munera
Author
Juan Carlos Munera
Passionate about cybersecurity, governance, risk, and compliance. Sharing insights on security best practices, frameworks, and industry trends.

Related