
How card skimmers steal card details depends entirely on where the skimmer sits. On a petrol forecourt it is a plastic overlay, a thin reader in the chip slot and a pinhole camera pointed at the keypad. On a checkout page it is a few dozen lines of JavaScript, added to a page the shopper already trusts, reading the card number out of the form field as the fingers move.
Most guides stop at the forecourt. This one follows the digital version through the whole chain: how the code reaches the page, how it reads the fields, how the data leaves the browser, and what happens to it after that. The defences come last, matched to each stage, because a control chosen against the word “malware”rather than against the actual route in tends to miss.
Two kinds of skimmer: the device on the pump and the code on the page
Physical skimming needs hardware and access. An overlay reader sits on the mouth of the card slot and copies the magnetic stripe. A shimmer is thinner, a flexible circuit pushed into the chip slot that reads the data passing between chip and terminal. A camera or a false keypad captures the PIN. All of it requires someone to walk up to the machine twice, once to fit it and once to collect.
Chip and PIN, and then contactless, made that trade harder and less profitable in the UK. Cloned stripe data is of limited use on a terminal that wants a chip. So the effort moved to where the card number alone is still enough, which is any website taking a card-not-present payment.
Digital card skimming needs no hardware and no physical access. The attacker gets a script onto the payment page, or onto a page that loads into the payment page, and the browser does the rest. Researchers called the method Magecart, and the name stuck. It is a label, not a gang. Several unconnected crews reuse the same field-capture and exfiltration patterns, which is why two skimmers pulled off two unrelated stores can look almost identical and share no operator at all. The name describes a method rather than a group, and that distinction matters when you are working out who to defend against.
The padlock tells the shopper nothing
HTTPS encrypts the connection between browser and server. It says nothing about what code is running inside the page. A skimmer runs in the shopper’s own browser, inside the trusted origin, with full access to the DOM. The padlock is closed. The certificate is valid. The brand in the address bar is the real one. The card number still leaves for a server nobody at the merchant has heard of.
Scale is the other difference. A pump skimmer harvests one forecourt until someone spots the overlay. A compromised checkout script harvests every order, on every store loading that script, for as long as it stays unnoticed. In September 2020, the Dutch security firm Sansec reported in its published research that roughly 2,000 stores still running end-of-life Magento 1 were compromised over a single weekend. One vulnerability, thousands of checkouts.
Stage one: how the skimmer gets onto a checkout page
Almost every named incident comes in by one of three routes. Pick your defences against the route.
A compromised third-party supplier
Checkout pages are rarely just checkout pages. Analytics, session recording, chat widgets, A/B testing, tag managers, review scripts and marketing pixels all load alongside the card form, each from a domain the merchant does not control. Compromise one supplier and the code arrives on every customer’s page, signed off by the merchant’s own template.
Ticketmaster UK, June 2018, is the textbook case. The skimming code reached the payment page through a customer support chat product supplied by Inbenta Technologies, not through any flaw in Ticketmaster’s own code. The ICO fined Ticketmaster UK £1.25m in November 2020 over the breach. A chat widget has no business on the page where card numbers are typed.
Injected first-party code
Here the attacker gets inside the merchant’s own estate, usually through stolen admin or hosting credentials, an exposed control panel or a compromised developer account. A legitimate JavaScript file on the merchant’s own domain is edited, and the skimmer is served from the same host as everything else.
British Airways, between 22 August and 5 September 2018, followed this pattern: a modified script served from the airline’s own infrastructure captured payment and personal data out of the booking flow. The ICO issued a £20m penalty in October 2020, its penalty notice recording that the personal data of around 429,000 customers and staff was affected. First-party injection is the hardest route to spot from outside, because the script comes from a domain you would never think to question.
An unpatched or end-of-life platform
Magento 1 reached end of life on 30 June 2020, the date Adobe had set for the platform. Ten weeks later came the mass compromise Sansec documented, driven by a known platform vulnerability against stores that had not moved. No supplier was breached. No credentials were stolen. The software simply had a hole and nobody was shipping fixes for it any more.
Notice what is not on this list: the payment form itself. The soft entry is almost always somewhere adjacent. A forgotten marketing tag from a campaign that ended in 2022. A staging site sharing credentials with production. A plugin installed once for a promotion and never removed. For a longer walk through the named cases, the breakdown of eight incidents grouped by the three routes in sorts them the same way.
Stage two: how the code captures card details as they are typed
A working skimmer is short. In plain English, a typical one does four things.
- It checks where it is. The script reads the page URL and does nothing at all unless the path looks like a payment step, commonly a match on /checkout, /onepage or /payment. On every other page it stays dormant, which keeps it out of sight.
- It finds the fields. Rather than hard-coding one store’s markup, it matches on the attributes payment forms nearly always carry: name and id values containing “card”, “number”, “cvv”or “expiry”, and the standard autocomplete values cc-number, cc-exp and cc-csc. Those attributes exist so browsers can autofill correctly. A skimmer uses them for the same reason.
- It listens. Event listeners on keyup, change and blur read each field as the shopper leaves it. Many also hook the form submit event to take a final snapshot, and some run a timer that sweeps every input on the page every few seconds, which catches fields the author never anticipated.
- It packages what it has. Not just the card number. Expiry, CVV, cardholder name, billing address, email address and phone number go too, because a full record sells for more than a bare sixteen digits. A number alone fails a billing-address check. A complete record does not.
Overlay skimmers are the variation worth knowing about. Where the card fields sit inside a payment provider’s iframe and cannot be read from the parent page, an attacker who controls the surrounding page can draw a convincing fake card form on top of it. The shopper types into the attacker’s input. The script then passes the details through to the real iframe so the payment goes ahead.
Because none of this interferes with the transaction. The card is authorised. The order is created. The confirmation email arrives on time. Skimmers are written to throw no errors and change nothing the shopper can see, and that is precisely why they last. The payment succeeds. So does the theft.
Stage three: exfiltration, and why it is so hard to spot
Captured data has to leave the browser. The usual method is deliberately boring: base64-encode the record, or run it through a simple XOR, then send it out as a POST request or as the query string on an image request. An image beacon is quiet because it needs no response and triggers no visible error.
The destination is chosen to survive a glance at the network tab. Domains are registered to resemble a CDN, a font host or an analytics endpoint. VisionDirect, the UK contact lens retailer, disclosed in November 2018 that customer and payment card data, including CVV, had been taken between 3 and 8 November via a fake Google Analytics domain. Newegg’s checkout was skimmed in 2018 by a script served from a look-alike domain built around the company’s own name. Scrolling a list of requests, neither looks out of place.
Good skimmers also behave defensively. They deduplicate, so the same browser does not send twice and flood the collection server. They fire only on payment paths. Many check whether developer tools are open, whether the browser is headless, or whether the visitor’s IP falls in a range associated with security researchers, and go dormant if so. This is why a manual look at your own checkout can come back completely clean while the skimmer is live for customers.
After collection, the records are sold in bulk as card-not-present data. Buyers test them with small authorisations on low-friction merchants, then spend the ones that clear on goods bought online, where no physical card is ever presented. The full mechanics of how details are copied at the moment of payment are worth reading alongside this if you want the shopper’s view of the same event.
Signs of a payment page skimmer
The uncomfortable truth first: most merchants find out from outside. An acquirer or card scheme raises a common-point-of-purchase report, having noticed that a cluster of fraudulent cards all passed through your store. Or customers start emailing about fraud a few weeks after ordering. Neither signal comes from your own logs, because a working skimmer produces nothing to log.
What you can check yourself:
- What the page actually loads. Open your live checkout in a browser, open the network tab, filter to scripts, and write down every domain. Compare that against the list you intended to allow. The gap between the two is the finding.
- File modification dates. A JavaScript file in your theme that changed on a date with no deployment behind it deserves an explanation.
- Appended blocks. Skimmers are often bolted onto the end of a known library, as a long encoded string after otherwise ordinary code. Minified code is dense but structured. A single vast base64 blob is not.
- Entry points. Admin accounts you cannot name, core files failing an integrity check, a platform two versions behind, a supplier script whose contents changed without any notice to you.
None of these is proof on its own. Taken together they are usually enough to decide whether to escalate. There is a longer procedure in the guide on how to tell if your checkout has been skimmed.
Breaking the chain: defences that stop each stage
Take the card fields off your page
Hosted payment fields, where the card inputs are individual iframes served by your payment provider, remove the card number from your DOM entirely. Your JavaScript cannot read it, and neither can an attacker’s. This is the cheapest single reduction in risk available to most merchants, usually a configuration change within a provider you already pay. The case for hosted fields is mostly that it costs nothing extra.
It is not total, and anyone selling it as total is overstating it. An attacker who controls the surrounding page can still draw an overlay form on top of the iframe. They can still take name, billing address, email and phone from your own fields, all of which have value for card-not-present fraud and for follow-on phishing. Hosted fields shrink the target. They do not remove it.
Content Security Policy, report-only first
A tight script-src policy tells the browser which origins may execute JavaScript on that page, and blocks the rest. Deploy it in Content-Security-Policy-Report-Only mode on the live checkout before you enforce anything. Two things happen: checkout keeps working while you learn, and you discover scripts you did not know were loading. That report is most of the script inventory PCI DSS asks for, produced for free by real traffic. There is a worked CSP setup for a checkout page if you want the header syntax.
Subresource Integrity, with a supplier process behind it
SRI pins a third-party script to a cryptographic hash. If the file changes by one byte, the browser refuses to load it. Against the Ticketmaster route it is the single most direct control there is.
The operational cost is real and people underestimate it. When a supplier updates their script, the hash stops matching and the script silently stops loading. If that script is doing something on your page that matters, something breaks, and the usual outcome is that a developer removes the integrity attribute at 5pm on a Friday and never puts it back. Agree a change notification process with the supplier, or version-pin the file, before you deploy integrity hashes on scripts you do not control.
What PCI DSS 4.0 now requires
Two requirements became mandatory on 31 March 2025, having been future-dated in the PCI Security Standards Council‘s version 4.0. Requirement 6.4.3 says you must manage all scripts loaded and executed in the consumer’s browser on the payment page: authorise each one, justify why it is necessary, and assure its integrity. Requirement 11.6.1 says you must detect and alert on unauthorised change to payment page HTTP headers and script content, checked at least weekly. Read plainly, that is an inventory plus a change detector. The detail of 6.4.3 and 11.6.1 covers what evidence an assessor tends to want.
A checklist for this week, cheapest first
- List every script your live checkout loads, from the browser network tab. Free, one hour.
- Delete the ones that do not belong there. Chat, session recording, heatmaps, dead campaign tags. Free, and it shrinks the attack surface more than any product will.
- Audit admin and hosting accounts. Remove dormant ones. Turn on multi-factor authentication everywhere it is offered.
- Check your platform is still receiving security patches, and note the version you are on. If it is end of life, that is now your biggest problem.
- Deploy CSP in report-only mode on checkout with a reporting endpoint. Leave it a fortnight. Read the reports.
- Move card entry to hosted fields or a provider iframe if it is not there already.
- Add SRI hashes to third-party scripts you cannot remove, once you have a change process with the supplier.
- Then, and only then, consider paid client-side monitoring to satisfy 11.6.1 continuously.
The short version
Physical skimmers copy a card at a machine. Digital ones copy it in the browser, from inside a page the shopper has every reason to trust. The code arrives through a compromised supplier, through injected first-party files, or through a platform nobody patched. It reads the fields on keyup and submit, encodes the record, and posts it to a domain dressed up as a CDN. Nothing breaks, so nobody looks, and the bank usually finds out first.
Understanding how card skimmers steal card details is mostly useful for one reason: each stage of the chain has a cheap break in it. Fewer scripts on checkout, card fields inside the provider’s iframe, CSP in report-only, integrity hashes on what remains. Start with the free ones.
Frequently Asked Questions
How do card skimmers steal card details from a website rather than an ATM?
There is no hardware involved. An attacker adds JavaScript to the checkout page, usually by compromising a third-party script the page loads, editing a file on the merchant’s own server, or exploiting an unpatched platform. The script attaches listeners to the card fields and reads the values as the shopper types, then sends them to a server the attacker controls. The payment itself completes normally.
Can a skimmer capture my CVV if it is never stored by the merchant?
Yes. The prohibition on storing CVV applies to the merchant’s systems after authorisation, not to the moment of typing. A skimmer reads the value out of the input field in your browser before it goes anywhere, so the merchant’s storage policy is irrelevant to it. VisionDirect confirmed in November 2018 that CVV data was among what was taken in its breach.
Does HTTPS or a padlock icon protect a checkout page from a skimmer?
No. HTTPS protects data in transit between the browser and the server. A skimmer runs inside the page itself, on the same trusted origin, and can read form fields before encryption is ever relevant. British Airways and Ticketmaster UK both had valid certificates throughout.
How long can a JavaScript skimmer run on a checkout before anyone notices?
Longer than most people expect, because a working skimmer gives nobody a reason to look. Published cases have run from days to weeks: VisionDirect reported a window of roughly five days, while the ICO found the British Airways code was active on the booking flow for about a fortnight. The limiting factor is usually how quickly issuers correlate fraud back to a common point of purchase.
What should a merchant do first if they suspect their checkout has been skimmed?
Preserve evidence before you clean anything: take copies of the suspect files, server logs and the current page source, because overwriting them destroys your only record of what happened and when. Contact your acquirer and your payment provider, since scheme rules and reporting obligations apply, and consider whether the UK GDPR 72-hour notification to the ICO is triggered. Then remove the injected code, rotate every administrative credential, and close the entry route rather than only the symptom.
