Web Skimming: How Attackers Steal Credit Card Data From Your E-Commerce Site
Somewhere right now, a small e-commerce store is processing orders normally. The checkout page works, payments go through, customers receive their products. Everything looks fine. But on every order, a few lines of injected JavaScript are quietly copying the credit card number, expiration date, CVV, and cardholder name and sending them to a server controlled by criminals.
This is web skimming. Also called Magecart attacks (named after the consortium of criminal groups that pioneered the technique), formjacking, or digital card skimming. It is the online equivalent of the physical skimmer devices criminals attach to ATMs and gas station card readers. Except it is invisible, it scales to millions of transactions, and most victims never know it is happening until their bank calls.
How Web Skimming Works
The fundamental concept is simple: inject JavaScript code into a checkout page that captures payment form data and sends it to a server controlled by the attacker. The implementation varies, but the main techniques are:
Keylogging
The injected script attaches event listeners to the payment form fields. Every keystroke is captured and logged. When the form is submitted (or at regular intervals), the captured data is sent to the attacker's collection server.
The script might look something like this (simplified for illustration):
document.querySelectorAll('input[type="text"], input[type="number"]')
.forEach(function(input) {
input.addEventListener('keyup', function() {
// Capture and exfiltrate card data
sendToAttacker(input.name, input.value);
});
});
In reality, skimming scripts are heavily obfuscated to avoid detection. They use encoded variable names, split strings, dynamic function construction, and other techniques to make the code unreadable to anyone reviewing it.
Form Grabbing
Instead of capturing individual keystrokes, the script intercepts the form submission event. When the customer clicks "Pay" or "Submit Order," the script grabs all form field values before or alongside the legitimate submission. The customer's payment processes normally, but the card data has been copied and sent to the attacker.
This is harder to detect than keylogging because the script only activates at submission time, making it less likely to trigger behavioral monitoring.
Iframe Injection
The attacker replaces the legitimate payment form with a fake one rendered in an iframe. The fake form looks identical to the real one (same styling, same fields, same button). The customer enters their card details into the attacker's form, which captures the data and then either redirects to the real payment form or displays a fake error message asking the customer to re-enter their details.
This technique is particularly effective because the fake form is under complete control of the attacker. There is no need to intercept an existing form; the attacker simply presents their own.
Overlay Attacks
Similar to iframe injection, but instead of replacing the payment form, the attacker overlays an invisible or transparent form on top of the legitimate one. The customer thinks they are typing into the real form, but their input goes to the attacker's overlay first.
How Attackers Get Their Code Onto Your Checkout Page
The skimming script needs to run on the checkout page of the target website. There are several ways attackers achieve this:
1. Direct Website Compromise
The attacker exploits a vulnerability in the e-commerce platform (unpatched CMS, vulnerable plugin, weak admin credentials) and directly modifies the checkout page template or injects a script include.
2. Third-Party Script Compromise
Many checkout pages load scripts from third-party services: analytics, A/B testing, chat widgets, ad tracking, review platforms. If the attacker compromises any of these third-party services, their skimming code runs on every website that loads the compromised script. This is the supply chain vector.
For a deeper analysis of third-party script risks, see our article on third-party JavaScript risks.
3. Compromised Payment Provider Integration
If the integration with the payment provider is done client-side (JavaScript-based), the attacker may be able to intercept or modify the payment data before it reaches the payment provider.
4. Server-Side Injection
In some cases, the attacker modifies server-side code (PHP, Python, Node.js) to inject the skimming script dynamically into the HTML response. This is harder to detect because the malicious code does not exist in the static files; it is generated on the fly.
Real Cases
British Airways (2018)
Attackers compromised a JavaScript file on the British Airways website and injected a skimming script that captured payment card details entered on the booking and payment pages. The attack ran for about two weeks and affected approximately 380,000 transactions.
British Airways was fined 20 million pounds by the UK Information Commissioner's Office under GDPR. The ICO found that BA could have prevented the attack with basic security measures that were available at the time.
Ticketmaster (2018)
Ticketmaster loaded a customer support chatbot from a third-party provider called Inbenta. Attackers compromised Inbenta's servers and modified the JavaScript file that Ticketmaster loaded on its payment pages. The skimming code captured payment details from Ticketmaster customers across multiple countries for several months.
This case highlights the supply chain risk: Ticketmaster's own servers were never directly compromised. The attack came through a trusted third-party script.
Magecart Group Campaigns
Magecart is not a single group but a collection of criminal groups using similar techniques. They have targeted thousands of e-commerce sites, from small independent stores to major retailers. Some Magecart campaigns have compromised website hosting providers, affecting hundreds of stores at once. Others have targeted specific CMS platforms (Magento in particular, hence the name "Magecart").
Small E-Commerce Sites
The cases that make headlines involve large companies, but the vast majority of web skimming attacks target small and medium e-commerce sites. These sites are less likely to have security monitoring, less likely to detect the compromise quickly, and often run outdated software with known vulnerabilities.
A small online store in Ticino processing 50 orders per day is a viable target. If the skimmer runs for three months before detection, that is approximately 4,500 stolen card numbers, each worth CHF 10-50 on the dark market. That is CHF 45,000-225,000 in value for the attacker, from a single small store.
PCI DSS Compliance Requirements
If you process, store, or transmit credit card data, you must comply with the Payment Card Industry Data Security Standard (PCI DSS). Web skimming is directly relevant to several PCI DSS requirements:
PCI DSS 4.0 and Client-Side Security
PCI DSS version 4.0 introduced specific requirements for managing JavaScript on payment pages:
- Requirement 6.4.3: All payment page scripts that are loaded and executed in the consumer's browser must be managed. This means you must maintain an inventory of all scripts, justify each one, and implement integrity checks.
- Requirement 11.6.1: A change and tamper detection mechanism must be deployed on payment pages to alert personnel of unauthorized modifications to HTTP headers and script content.
These requirements became mandatory in March 2025 for all organizations processing card payments. If your e-commerce site has not implemented these controls, you are not PCI DSS compliant.
What Compliance Means in Practice
- Know every script that runs on your checkout page
- Justify why each script needs to be there
- Implement integrity verification for each script (SRI hashes)
- Monitor for unauthorized changes to scripts
- Have a process for reviewing and approving new scripts before they are added to payment pages
How to Detect Web Skimming
Detection is challenging because skimmers are designed to be invisible. Here are practical detection methods:
1. Content Security Policy Reporting
Deploy a Content Security Policy (CSP) with reporting. CSP tells the browser which domains are allowed to load scripts, send data, and create connections. When a skimmer tries to send stolen data to an unauthorized domain, CSP blocks it and sends a report.
Start with a report-only policy to understand what your checkout page currently loads:
Content-Security-Policy-Report-Only: default-src 'self';
script-src 'self' https://payment-provider.com;
connect-src 'self' https://payment-provider.com;
report-uri /csp-reports
Review the reports to build a complete picture of what loads on your payment pages, then enforce the policy to block unauthorized sources.
2. Subresource Integrity (SRI)
Add integrity hashes to all external scripts loaded on your payment pages. If a script is modified (by an attacker compromising the source), the hash will not match and the browser will refuse to execute it.
3. Regular Script Auditing
Periodically review all scripts running on your checkout page:
- Open the checkout page in a browser
- Open the developer tools (Network tab)
- Review every script that loads. Do you recognize all of them? Are any loading from unexpected domains?
- Check the Sources tab for inline scripts that should not be there
4. File Integrity Monitoring
Monitor your website files for unauthorized changes. Any modification to checkout page templates, JavaScript files loaded on payment pages, or server-side code handling payments should trigger an alert.
5. Real User Monitoring (RUM)
Implement monitoring that captures what actually happens in users' browsers. This can detect unexpected network requests, unauthorized DOM modifications, and suspicious behavior that server-side monitoring cannot see.
6. External Scanning Services
Several security companies offer services that regularly scan your payment pages from the outside, simulating a real user and checking for skimming scripts, unauthorized form overlays, and data exfiltration attempts.
Defense: Content Security Policy
CSP is the single most effective defense against web skimming. A properly configured CSP can prevent skimming scripts from exfiltrating stolen data, even if the script is successfully injected into your page.
For a payment page, you want a tight CSP:
Content-Security-Policy:
default-src 'self';
script-src 'self' https://your-payment-provider.com;
connect-src 'self' https://api.your-payment-provider.com;
frame-src 'self' https://your-payment-provider.com;
style-src 'self';
img-src 'self' data:;
font-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self' https://your-payment-provider.com;
This policy ensures:
- Scripts can only load from your domain and your payment provider
- Data can only be sent to your domain and your payment provider's API
- Forms can only submit to your domain and your payment provider
- No plugins, embeds, or objects are allowed
- The base URL cannot be changed (preventing base tag injection attacks)
Even if an attacker injects a skimming script, it cannot send the stolen data anywhere because CSP blocks outbound connections to unauthorized domains.
Defense: Subresource Integrity
SRI ensures that external scripts have not been tampered with. Every external script on your payment page should have an integrity hash:
<script src="https://payment-provider.com/checkout.js"
integrity="sha384-abc123..."
crossorigin="anonymous"></script>
If the script file is modified by an attacker (supply chain compromise), the hash will not match and the browser will refuse to load it. This directly prevents the Ticketmaster-style attack where a third-party script is compromised.
Defense: Regular Code Audits
Automated tools catch known patterns, but targeted attacks use custom, obfuscated code. Regular manual code audits of your payment flow are necessary:
- Review all JavaScript that runs on payment pages
- Check for obfuscated code (base64 encoding, eval() calls, dynamically constructed function names)
- Verify that no unauthorized scripts have been added to templates
- Check server-side code for injection points
- Review third-party script integrations for changes
Defense: Use Server-Side Payment Processing
The most effective architectural defense is to never have credit card data touch your website's frontend at all. Payment providers like Stripe, Adyen, and PayPal offer hosted payment pages or tokenization that processes card data entirely on the provider's infrastructure.
With a hosted payment page (redirect or iframe from the payment provider), the customer enters their card details on the payment provider's domain, not yours. Even if your website is fully compromised, the attacker cannot skim card data because it never appears on your pages.
With tokenization, the payment provider's JavaScript collects card data directly and sends it to the provider's servers, replacing it with a token. Your server only sees the token, never the actual card number.
Why Swiss E-Commerce Sites Are Targets
Swiss e-commerce sites, including those based in Ticino, are attractive targets for several reasons:
- Higher average transaction values: Swiss consumers spend more per transaction than most European countries. Higher transaction values mean more valuable stolen card data.
- Lower security awareness: Many Swiss e-commerce sites, especially smaller ones, do not implement CSP, SRI, or regular security auditing.
- Outdated platforms: We regularly find Swiss e-commerce sites running outdated versions of Magento, WooCommerce, or PrestaShop with known vulnerabilities.
- Trust factor: Swiss domains carry trust. Stolen card data from Swiss e-commerce sites commands higher prices on dark markets because the cards are more likely to be premium cards with higher limits.
Financial and Legal Liability
If your e-commerce site is compromised and customer card data is stolen, the consequences are severe:
Financial
- PCI DSS fines: Card brands can levy fines of $5,000 to $100,000 per month for non-compliance. After a breach, these fines are applied retroactively.
- Forensic investigation costs: You are required to hire a PCI Forensic Investigator (PFI) to determine the scope of the breach. This typically costs CHF 20,000-100,000.
- Card reissuance costs: You may be liable for the cost of reissuing compromised cards, typically $3-10 per card.
- Chargeback liability: Fraudulent transactions made with stolen card data may result in chargebacks that you bear.
- Loss of payment processing: Your acquiring bank may terminate your merchant account, effectively shutting down your ability to accept card payments.
Legal
- GDPR / nLPD: Credit card data is personal data. A breach of card data triggers notification obligations under both EU GDPR and Swiss nLPD. Fines under GDPR can reach 4% of annual global turnover.
- Civil liability: Affected customers may sue for damages resulting from the breach.
- Reputational damage: News of a payment data breach can permanently damage customer trust in your brand.
What to Do Now
- Audit your checkout page. Open developer tools and review every script that loads. Do you know what each one does? Can you account for every domain that receives data?
- Implement Content Security Policy on your payment pages. Start with report-only mode, analyze the reports, then enforce.
- Add SRI hashes to all external scripts on payment pages.
- Consider hosted payment pages or tokenization to remove card data from your website entirely.
- Update your e-commerce platform and all plugins to the latest versions.
- Set up file integrity monitoring for your checkout page files.
- Review PCI DSS 4.0 requirements for client-side security and ensure compliance.
For a comprehensive look at web application vulnerabilities, see our guide on the OWASP Top 10.
If you operate an e-commerce site and want a professional security assessment of your payment flow, contact our team. We specialize in helping Swiss businesses protect their online stores and comply with PCI DSS requirements.
Want to know if your site is secure?
Request a free security audit. In 48 hours you get a complete report.
Request Free Audit