An EtherHiding skimmer is card-stealing JavaScript whose payload is kept in a smart contract on a public blockchain instead of on a web server. That is the whole innovation. The code that reads the card fields is the same kind of code Magecart operators have been writing since 2015, and it arrived on the payment page by one of the same three routes it always uses.
Guardio Labs first described the EtherHiding technique in October 2023, in a campaign that used Binance Smart Chain contracts to serve fake browser-update lures. Google’s Threat Intelligence Group published further analysis in October 2025, attributing use of the same method to a North Korean-linked cluster. Most of the write-ups are aimed at researchers: wallet addresses, contract addresses, payload staging. Useful work, and none of it tells a merchant what to change on Friday.
So this piece treats the problem as a loader problem. The contract only matters once attacker code is already running inside your checkout. Fix how it got there, control what the page is allowed to fetch, and the clever storage layer becomes irrelevant.
What an EtherHiding skimmer actually does on a payment page
The shape is two-stage. A small piece of JavaScript is injected into your site, either in a first-party file or through a script you load from somewhere else. That loader does not contain the skimmer. It contains an address and a read instruction.
When a shopper reaches checkout, the loader makes a read call against a smart contract on a public chain and receives back a string. The string is code. The loader evaluates it, the skimmer assembles itself in memory, and the card fields are watched from that point on. The card data then leaves the browser to an endpoint the attacker controls, exactly as it always has.
Why the move? Read calls against contract storage cost nothing and can be made by anyone, so there is no hosting bill. There is no domain registration to trace and no server to seize. A deployed contract cannot be taken down by an abuse report to a hosting provider. And if the attacker wants a different payload tomorrow, they write a new value into storage for a small transaction fee and never touch your site again.
Set against classic Magecart delivery, the change is narrow but real. The contract replaces the payload host. It does not replace the entry route. Something still had to put that loader on your page, and that something is a patch, a password or a supplier.
Why domain blocklists and threat feeds miss this skimmer
Three reasons, all practical.
First, the read traffic looks ordinary. Public RPC endpoints and blockchain gateway services are mainstream infrastructure used by legitimate applications. A JSON request to one of those hosts does not stand out in a proxy log next to your analytics and fraud-scoring calls.
Second, there is no file. URL reputation systems need a URL and hash-based scanners need a file on disk. An on-chain payload produces neither. It exists as a return value in a browser’s memory for the length of a session.
Third, indicators age out fast. Contract and wallet addresses published in research are worth checking once against your logs. Building a defence on them is a waste of effort, because the payload behind that address can be replaced in minutes and the operator can deploy a fresh contract for the price of a coffee.
The consequence is worth stating plainly. Detection has to be about what your page loads and executes, not about who it talks to.
How the loader gets in: the three entry routes to close first
Every published incident of this class fits one of three shapes. The eight best-documented Magecart incidents and the routes they took are worth reading alongside this section, because the pattern has not changed.
A compromised third-party supplier script. Ticketmaster UK, 2018. The malicious code was not written into Ticketmaster’s own files. It came down through a chatbot script supplied by Inbenta and hosted by the supplier. The ICO fined Ticketmaster UK £1.25 million in November 2020, according to its published penalty notice. Any script you load from someone else’s server is a script whose contents they can change without telling you.
Injected first-party JavaScript after account or server access. British Airways and Newegg, both 2018. In these cases the skimmer lived in code served from the victim’s own domain, which is why it passed every allowlist the browser applied. The ICO issued a £20 million penalty against British Airways in October 2020, again set out in its published penalty notice. This is the route that defeats a script-source allowlist, and it is the one people underestimate.
Unpatched or end-of-life platform code. Adobe ended support for Magento 1 in June 2020. In September 2020 Sansec reported roughly 2,000 Magento 1 stores skimmed over a single weekend, the largest such campaign it had recorded. No supplier involved, no stolen admin password needed. Just an unmaintained application on the open internet.
Triage in that order, and do it as an inventory rather than a scan:
- List every third-party script that loads on the checkout route, with an owner’s name against each one.
- Audit who holds admin, extension-install and deploy rights, remove the accounts nobody can account for, and put multi-factor authentication on what remains.
- Establish the patch state of the platform, the extensions and the server stack, and set a patch window you can actually hold to, measured in days rather than quarters.
Locking down the browser: CSP and SRI settings that survive an on-chain payload
A content security policy for the checkout page is the control that bites here, because it governs what the browser is permitted to fetch and where it is permitted to send. A working policy will not care that the payload lives on a blockchain. It will care that your page has suddenly tried to POST to a host that is not on the list.
Write the policy as explicit allowlists per directive. Relying on default-src and forgetting the rest is the usual mistake.
connect-src is the directive most merchants leave open. Plenty of checkout policies pin script-src with real care and then say nothing about connect-src, which is precisely the directive that would refuse the read call to an RPC endpoint and, afterwards, refuse the exfiltration request. Set it to your payment provider, your analytics and nothing else. Watch img-src too, because a skimmer that cannot use fetch will happily exfiltrate by building an image URL with the card data in the query string.
Roll it out in report-only mode first. Publish Content-Security-Policy-Report-Only on the checkout route alone, not the whole site, and collect violation reports across about two weeks of real traffic. Two weeks matters because you need mobile wallet flows, the fraud-scoring vendor’s occasional extra call and whatever the marketing team ships mid-sprint. When the report volume goes flat and every remaining entry is one you can name, promote it to enforcement. The step-by-step build is set out in this worked checkout CSP setup.
Two things undo the whole policy. ‘unsafe-inline’ in script-src, which lets any injected inline block run. And a wildcard in connect-src, which makes the egress control decorative. If a tag manager forces you into either, that is a conversation with the tag manager’s owner, not a reason to weaken checkout.
Be honest about the limit. CSP does not stop injected code inside a first-party file from executing. British Airways would have satisfied a script-src ‘self’ policy. What CSP does is take away the payload fetch and the outbound call, which is most of the attack.
Subresource Integrity covers the supplier route by pinning a cryptographic hash to each external script tag. The browser refuses any file whose contents no longer match. The trade-off is not technical, it is organisational: a supplier who ships an update without warning breaks your tag. Decide in advance that a failed hash means the script does not load on checkout, which is the safer answer, and write down who chases the supplier for the new hash. Note also that SRI only pins the file you name. A loader that fetches further code at runtime, which describes most tag managers, is outside its reach.
Taking the card fields out of reach with hosted payment fields
The cheapest structural fix is to stop the card number touching your DOM at all. With provider-hosted iframes or a full redirect, the PAN and CVV are typed into a document your page cannot read, so an injected loader has nothing to hook. Hosted payment fields remove more risk per pound spent than any product you can buy.
They remove the card from reach. They do not remove the attacker from the page. An injected loader can still draw a convincing overlay form on top of the iframe and collect the number itself. It can log keystrokes in the billing fields, harvest name, address, email and phone, read order contents, or lift session cookies and tokens. An on-chain payload still helps the attacker here, because the overlay markup can be swapped remotely to match your next theme change.
On scope: fully outsourcing the payment fields is what lets most UK e-commerce merchants use SAQ A. Read the current eligibility criteria rather than assuming. In SAQ A v4.0.1, published by the PCI Security Standards Council, requirements 6.4.3 and 11.6.1 were removed from the questionnaire, but an eligibility criterion was added requiring the merchant to confirm its site is not susceptible to script-based attacks affecting the payment page. The paperwork moved. The work did not. Check the current version in the PCI SSC document library and with your acquirer before you commit to a route.
Detection you can actually run: proving what your checkout loads
Two PCI DSS 4.0 requirements happen to fit this threat unusually well, and both have been mandatory since 31 March 2025. Requirement 6.4.3 asks you to inventory every script on the payment page, authorise it, and record a written justification for each. Requirement 11.6.1 asks you to detect and alert on unauthorised change to the payment page’s HTTP headers and content. Taken together, they would surface an injected loader even when no threat feed has ever seen the payload. The detail of what each one asks for is covered in this breakdown of requirements 6.4.3 and 11.6.1.
You do not need a product to start. A spreadsheet with script URL, owner, business purpose and date authorised satisfies 6.4.3 far better than a tool nobody reads. For 11.6.1, a scheduled job that fetches the checkout URL, hashes the response headers and the script tags in the served HTML, and emails on difference will cost an afternoon.
Then run a manual pass, monthly, by hand. To detect malicious JavaScript on an e-commerce site you mostly need a clean browser profile with no extensions and the network tab open:
- Load the checkout and complete a test order. Read every outbound request. You are looking for hosts you cannot name, particularly anything resembling an API or gateway endpoint you never integrated.
- Filter to fetch and XHR after the card fields gain focus. That is where exfiltration shows up.
- Diff the served JavaScript bundles against your build output. A file that differs from what your pipeline produced is the finding, whatever it contains.
- Check response headers on the payment route. A missing or altered CSP header is a change worth explaining.
Outside signals deserve immediate action rather than a ticket. An acquirer or issuer reporting a fraud cluster with your store as the common purchase point. Customers describing a payment prompt that does not match your flow, or a second card entry step. Admin logins from countries you do not operate in. None of these is proof on its own. Any of them justifies pulling the checkout apart today. The fuller checklist sits in how to tell if your checkout has been skimmed.
If you think you have found one: the first 24 hours
Preserve before you clean. Save the full served HTML of the checkout, the injected script exactly as delivered, the response headers, and web, application and admin access logs covering the period in question. The instinct is to delete the bad file immediately. Resist it for the ten minutes it takes to copy the evidence, because your acquirer’s forensic process and any ICO correspondence will both ask what was served and for how long.
Then remove the loader and assume the route is still open. Rotate admin credentials, API keys, integration tokens and session secrets, invalidate active sessions, and review every administrator account. A cleaned file with a live entry route reinfects within days.
Notify in parallel. Contact your acquirer and follow its incident path. For UK merchants, if personal or card data has been exposed, the 72-hour notification window under UK GDPR starts from the moment you become aware, not from the moment you finish investigating, and the ICO’s guidance on reporting a personal data breach sets out what to include when the facts are still incomplete.
Re-audit afterwards. Look for a second loader, because operators often leave one. Confirm your enforced policy now refuses the read call and the exfiltration request. Then re-sign your script inventory, so the next change has something to be measured against.
The short version
- An EtherHiding skimmer stores its payload in a smart contract instead of on a web server. The card theft, and the way the loader arrived, are unchanged.
- Blocklists and file scanning have nothing to grab: no file, no suspicious domain, and indicators that go stale in weeks.
- Close the three entry routes first, in order: supplier scripts, admin and extension access, platform patch state.
- Write connect-src as an explicit allowlist. It is the directive most checkout policies forget, and the one that refuses both the payload read and the exfiltration call.
- Roll the policy out in report-only on the checkout route for about two weeks, then enforce.
- Hosted payment fields take the card number out of reach. They do not take the attacker off the page, so keep monitoring overlays and billing fields.
- PCI DSS 4.0 requirements 6.4.3 and 11.6.1 have been mandatory since 31 March 2025, and a justified script inventory plus payment-page change detection is the detection method that works here.
- If you find one: preserve, then clean, then rotate every credential, then tell your acquirer and mind the 72-hour clock.
Frequently Asked Questions
What is an EtherHiding skimmer?
Card-stealing JavaScript that keeps its payload in the storage of a smart contract on a public blockchain rather than on a web server. A small loader injected into the merchant’s page reads that storage at runtime and executes the returned code. Guardio Labs documented the technique in October 2023, and Google’s Threat Intelligence Group published further analysis in October 2025.
Can a Content Security Policy stop an EtherHiding skimmer?
It can stop most of it, if the policy is written properly. An explicit connect-src allowlist refuses the read call to an RPC or gateway endpoint and refuses the later exfiltration request, and script-src without ‘unsafe-inline’ blocks injected inline blocks. What CSP cannot do is prevent injected code inside a first-party file from running, which is why entry-route work comes first.
Why do antivirus and domain blocklists fail to catch this technique?
There is no file to hash and no attacker-registered domain to reputation-score. The read traffic often goes through mainstream public blockchain endpoints that look like ordinary API calls, and the payload behind a contract address can be replaced without touching the merchant’s site, so any indicator collected today is likely stale within weeks.
Do hosted payment fields protect against a skimmer loaded from a smart contract?
They protect the card number, which is the most valuable part. The iframe or redirect means injected page code cannot read the PAN or CVV directly. It can still draw a fake overlay form, log keystrokes in your billing fields, take order data or steal session cookies, so hosted fields reduce monitoring scope rather than ending it.
Does PCI DSS 4.0 require me to detect this kind of script change?
Yes, for merchants in scope for those requirements. Requirement 6.4.3 requires an inventory of every script on the payment page with authorisation and written justification, and 11.6.1 requires detection of unauthorised change to payment page headers and content. Both became mandatory on 31 March 2025; confirm which questionnaire and requirements apply to you with your acquirer, since SAQ A eligibility criteria were revised in version 4.0.1.
