A blockchain Magecart skimmer takes away the part of incident response that most teams rely on. There is no host to email, no registrar to file a complaint with, no server for anyone to seize. The malicious code sits in the storage of a smart contract on a public chain, and contract storage does not have an abuse desk.
Everything else about the attack is familiar. A customer types a card number into your checkout. The payment succeeds. The order confirmation arrives. Somewhere in that same second, a copy of the details leaves the browser. Magecart has always been a name for a method rather than a single group, and chain-hosted delivery is a choice within that method, not a new crew. Expect to see the same payload pattern bolted onto completely different entry routes, and stolen data going to completely different places.
What a blockchain-hosted skimmer looks like on a live checkout
The design is split in two. What lands on your site is a loader: small, plain, often under a couple of kilobytes, with nothing in it that a scanner would recognise as a skimmer. What does the stealing never touches your server at all.
At runtime the loader makes a read-only call to a public RPC endpoint or a hosted node provider. In Ethereum-style chains that call is eth_call, and it costs nothing. The contract returns a long hex or base64 string. The loader decodes it, hands the result to a function constructor, and the browser executes it. Only then do the card-field selectors, the exfiltration address and the encoding routine exist, and they exist only in memory.
Guardio Labs described this pattern publicly in October 2023 under the name EtherHiding, using BNB Smart Chain contracts to serve malicious JavaScript to compromised WordPress sites. The idea moved to checkouts quickly enough. If you want the block-it-now walkthrough rather than the response problem, the EtherHiding skimmer piece covers it.
The awkward part for defenders is the diff. When you compare your deployed files against your repository, the injected code contains no suspicious domain, no card_number selector, no base64 blob of stolen data, no string anyone would flag in review. It reads like telemetry. Read plainly, that is: a fetch, a decode, a call. The delivery method changed. The theft did not.
Why registrar takedowns and blocklists stop working here
A conventional skimmer has a weak point off your site. It loads from a domain, that domain has a registrar, the registrar has an abuse process, and the exfiltration endpoint sits on a host that can be notified. Response teams have twenty years of muscle memory built on that. None of it applies.
Nobody can delete data from a public chain. The operator can update what the contract returns with a single transaction, usually for a fraction of a pound in gas, and that write is visible on-chain to anyone who already knows the contract address. Which is the problem. You have to know the address first, and by the time an indicator reaches a threat feed, the stored payload may have been rewritten twice. An indicator you captured on Monday can be worthless by Tuesday.
The reads are worse. A read-only call is served by a node and never recorded on-chain, so there is no public ledger of which sites are pulling the payload. Investigators cannot enumerate victims from the chain. Nobody is going to telephone you.
Blocking the RPC endpoint is the obvious reflex and it is blunt. The large node providers serve a great deal of legitimate traffic, and the operator can move to another provider, or run their own node, faster than your change control can approve the block. The conclusion is uncomfortable but simple: containment has to happen on your own page, at the point where the loader runs.
Which means indicator-based defence is the wrong shape for this. Blocklists expire. Allowlists do not. Every control below works because it enumerates what is permitted, not what is forbidden.
How the loader gets onto your payment page in the first place
The payload source is beyond your reach. The entry route is not, and it is the only thing you actually control.
- A compromised supplier. Ticketmaster UK, June 2018: the skimming code arrived through a chatbot script supplied by Inbenta. The merchant had approved the script. The merchant did not write it, did not host it, and could not see when it changed.
- Modified first-party code. British Airways, August to September 2018: an existing script on the airline’s own pages was altered. Around 380,000 transactions were affected, and the ICO issued a £20m penalty in October 2020.
- An unpatched platform. Over the weekend of 11 to 13 September 2020, Sansec reported roughly 2,000 Magento 1 stores compromised at scale through a known-vulnerable admin path. Entry route beat payload sophistication by a wide margin.
Those three routes account for most of what happens in practice, and the pattern across well-documented incidents repeats with little variation. A chain-hosted payload does not change the front door. It only changes what walks through it.
The controls that still hold
Content Security Policy, with connect-src actually tightened
Content Security Policy is the control that survives contact with this attack, and most merchants implement exactly half of it. Teams spend weeks on script-src, cataloguing every analytics tag and A/B testing vendor, then publish a policy with connect-src absent or set to a wildcard.
connect-src governs fetch, XMLHttpRequest, WebSocket and beacon. It is the directive that decides whether the browser is allowed to talk to an RPC endpoint. It is also, in a great many skimmers, the channel the stolen data leaves by. Tighten script-src and leave connect-src open and you have locked the door while the window is off its hinges.
Roll it out in report-only mode first. Collect reports for a week or two, longer if your checkout has seasonal third parties, then move to enforcement. Do not enforce a new policy on a Friday afternoon. The working CSP setup for a checkout page goes through the directives line by line.
Subresource Integrity, and the cost nobody mentions
Subresource Integrity pins a supplier script to a cryptographic hash. If the file changes by one byte, the browser refuses to run it. Against the Ticketmaster route it is the single most effective control available.
It also has an operational cost the guides skip. Your supplier ships a bug fix, the hash no longer matches, and their script silently stops loading. Decide three things before you deploy it: who owns re-pinning, how fast they can turn it around out of hours, and whether a failed hash on a non-critical script is allowed to break the page. SRI on a live chat widget that fails closed at 2am on Black Friday is a self-inflicted outage. SRI on a script that touches the payment form failing closed is correct behaviour.
Hosted payment fields, with honest limits
Hosted payment fields put the card inputs inside an iframe served by your payment provider, so the card number never enters your DOM. That is the cheapest meaningful reduction in risk available to most merchants, and it should be the first thing on the list.
It is a scope reduction, not an all-clear. The loader still runs on your page. It can still read the cardholder name, billing address, email address, telephone number and order value, all of which are worth money. It can still draw a convincing replica form over the top of the real iframe and collect the card that way, which is a well-documented technique, not a theoretical one. The iframe protects the field. It does not protect the page.
Detecting a blockchain skimmer with no feed to consult
Nothing in a threat feed is going to help you here, so the work is first-party and manual.
Open your live payment page in a browser, with developer tools on the Network tab, and go through a real order. Read every request. You are looking for POST requests carrying JSON-RPC bodies, method names such as eth_call, and hosts belonging to node providers. A checkout has no business reason to talk to a blockchain node. If you cannot name the vendor and the feature, treat it as hostile until proven otherwise.
Then read the code rather than the file list. The tell is the pattern, not the content: a long hex or base64 string feeding atob, String.fromCharCode or a similar decoder, whose output goes straight into eval or new Function. Compare the scripts present in the rendered DOM against the scripts in your server-side HTML. Anything appended after page load deserves an explanation.
Check the entry points as well as the symptom. Admin accounts and their last login times. Platform and extension patch levels. Template, layout and theme files modified outside a deployment window. And take outside signals seriously, because they usually arrive first: a call from your acquirer, a common point of purchase report from an issuer, or three customers in a week saying their card was used somewhere odd after ordering from you. A working skimmer gives you no reason to look, which is why the question tends to be asked by a bank rather than by you.
Evidence for PCI DSS 6.4.3 and 11.6.1 when the source is a smart contract
Both requirements stopped being future-dated on 31 March 2025. They apply now, to any merchant with a payment page that takes card data in the browser, and a payload that rewrites itself daily is precisely the scenario they were written for. The current standard is published by the PCI Security Standards Council.
6.4.3 asks you to manage every script loaded into the payment page in the consumer’s browser: confirm each one is authorised, assure its integrity, and hold an inventory with a written justification for each script. A chain-hosted loader fails this immediately, because no auditor is going to accept “unknown”as a justification.
11.6.1 asks for a change- and tamper-detection mechanism that alerts on unauthorised modification to the HTTP headers and the content of the payment page as received by the browser, evaluated at least weekly unless a targeted risk analysis justifies otherwise.
You do not need a six-figure product for either. A CSP report endpoint doubles as a live script inventory feed, because anything trying to load from outside your allowlist reports itself. A scheduled job that fetches the rendered payment page, extracts the script tags and response headers, hashes them and diffs against the last run will satisfy 11.6.1 for most single-checkout merchants. Keep the inventory and the justifications in version control, with dated commits, so the evidence trail is something a QSA can read rather than a spreadsheet someone updated the night before. The detail of what each requirement expects is set out in the breakdown of what 6.4.3 and 11.6.1 ask of your payment page. If budget is the constraint, a separate piece compares six low-cost ways to detect payment page tampering and the evidence each one yields.
The short version
A blockchain Magecart skimmer cannot be taken down, so stop planning as though it can. There is no registrar, no host and no abuse desk, the payload can be rewritten in one transaction, and any indicator you collect has a short shelf life. Move your defence from blocklist-shaped to allowlist-shaped: a tight script-src, a connect-src that is actually restricted, SRI on supplier scripts with a named owner for re-pinning, and hosted payment fields to get the card number out of your DOM. Fix the entry route, because that is the only end of the problem you own. Then keep the script inventory and the weekly page-change evidence current, because since 31 March 2025 that is not optional.
Frequently Asked Questions
What is a blockchain Magecart skimmer?
It is a card-skimming attack in which the malicious JavaScript is stored in a smart contract on a public blockchain rather than on a web server. A small loader is injected into your site, and at runtime it fetches the encoded payload through a blockchain RPC endpoint, decodes it and runs it in the customer’s browser. The theft itself is identical to any other Magecart attack. Only the hosting has moved.
Can a skimmer hosted in a smart contract be taken down?
Not in the usual sense. Data written to a public chain cannot be deleted, and there is no registrar, hosting provider or abuse contact to approach. You can block the loader at your own page with CSP and remove the injection from your site, and you can ask node providers to consider the abuse, but the contract itself will remain readable.
Does Content Security Policy stop a blockchain-hosted skimmer?
A properly written policy does, provided connect-src is restricted as well as script-src. The loader has to reach a node endpoint to retrieve its payload, and connect-src is the directive that decides whether the browser permits that request. A policy that allowlists scripts but leaves network connections open will not stop it.
How do I check whether my checkout is calling a blockchain RPC endpoint?
Open the payment page in a browser with developer tools on the Network tab, complete a test transaction, and read every request. Look for POST requests with JSON-RPC bodies, method names such as eth_call, and hostnames belonging to node providers. If you find one and cannot name the business reason for it, treat the page as compromised and investigate the entry route.
Do hosted payment fields make this type of skimmer irrelevant?
No, though they help a great deal. The card number sits inside the provider’s iframe and is out of reach of scripts on your page, which removes the highest-value target. The loader still runs on your domain, so it can read the cardholder name, billing address, email and order value, and it can overlay a fake form on top of the genuine iframe. Treat it as scope reduction rather than immunity.
