# WooCommerce security: protect the admin, the checkout and your customers

> WooCommerce security is WordPress security plus three store-specific risks: card-testing bots on the checkout, skimming scripts on the payment page, and customer data in orders, logs and backups. Here is the checklist for each.

Updated 2026-09-26 · WordPress & WooCommerce · HTML version: https://getreport.app/guides/woocommerce-security

WooCommerce security starts with WordPress security: updates, two-factor login and few administrators. A store then adds three risks a blog does not have: bots that run stolen cards through your checkout, scripts that copy card details from the payment page, and customer names, addresses and orders stored in your database, logs and backups. This guide is for store owners and the people who run their sites. It goes through each risk with the settings that close it, in the order that matters. It is part of the [WooCommerce store checklist](https://getreport.app/guides/woocommerce-store-checklist), which covers speed, caching and schema for the same store.

## Quick answer

- **Update WooCommerce, the payment gateway and every extension** as soon as security releases appear. Delete extensions you do not use.
- **Give staff their own accounts** with the Shop Manager role instead of Administrator, and two-factor login for everyone.
- **Keep card data off your server.** Use a gateway with hosted payment fields or a hosted payment page.
- **Stop card testing** with WooCommerce's checkout rate limit (Settings → Advanced → Features), your gateway's fraud rules and a bot challenge.
- **Watch what loads on the checkout.** A Content Security Policy and a list of expected scripts catch skimmers.
- **Review REST API keys, webhooks and logs**, and set retention for old customer data.

## Why a store is a bigger target

A blog is hacked for its reputation: attackers want its links and its visitors. A store is hacked for money. Card details typed into the checkout are worth more than any spam link, customer lists can be sold, and a checkout that accepts payments can be used to test stolen cards.

That changes what "secure" means. On a blog, the worst case is spam in Google and a cleanup. On a store, it is card data stolen from your customers, chargebacks, a payment provider that closes your account, and data-protection duties towards every affected customer. The cost of the basics is the same; the cost of skipping them is much higher.

## 1. Keep the code current

Most WordPress compromises start with a plugin that has a known hole. On a store, that includes WooCommerce itself, the payment gateway, and extensions for shipping, invoices, subscriptions and product options.

- Turn on auto-updates for WooCommerce minor releases and for extensions with a good record (Plugins → Enable auto-updates).
- Update the payment gateway the day a security release appears; it touches every payment.
- Delete deactivated extensions and unused themes. Their files stay on the server and stay exploitable.
- Replace extensions that are no longer maintained. [Abandoned and closed plugins](https://getreport.app/guides/abandoned-and-closed-plugins-how-to-find-replacements) shows how to judge a replacement.

Test updates on a staging copy first when the store is complex, but do not let testing turn into months of delay.

## 2. Lock down accounts and roles

WooCommerce adds two roles to WordPress: **Customer**, for shoppers with an account, and **Shop Manager**, for staff. A Shop Manager can manage products, orders, coupons, reports and WooCommerce settings, but cannot install plugins, switch or edit themes, or edit code. That is what nearly everyone who runs the shop day to day needs.

- One account per person. No shared "shop" login.
- Administrator only for the people who maintain the site. Everyone else is a Shop Manager or Editor.
- Two-factor login for every administrator and shop manager. WordPress core has none, so it needs a plugin; [WordPress login security](https://getreport.app/guides/wordpress-login-security) shows how to set it up and how to rate-limit the login.
- Review Users → All Users every quarter and remove people who left.

Customer accounts cannot reach the admin, but they can be taken over with reused passwords. Offer guest checkout, so fewer accounts exist, and let the login rate limit cover the my-account page too.

## 3. Keep card data off your server

The safest card number is one your server never sees. Modern gateways offer two ways to take payments without it:

- **Hosted payment fields.** The card fields on your checkout are iframes served by the payment provider. The card number goes from the shopper's browser straight to the provider.
- **A hosted payment page.** The shopper is redirected to the provider's page to pay and comes back to your order confirmation.

Both shrink your PCI DSS scope, the card industry's security standard, compared with a form that posts card numbers to your server. They do not remove it: your checkout page still loads the iframe, and a script injected into that page can overlay a fake form. That is why the PCI Security Standards Council's January 2025 update to the self-assessment questionnaire for these merchants (SAQ A) asks them to confirm their site is not susceptible to attacks from scripts. Ask your payment provider which questionnaire applies to your setup.

Never store card numbers yourself, in order notes, custom fields or emails. Saved cards for returning customers should be tokens held by the gateway.

## 4. Stop WooCommerce card testing

Card testing is a bot attack in which criminals run lists of stolen card numbers through your checkout, usually with small amounts, to find out which cards still work. The signs are hard to miss:

- Dozens or hundreds of failed or pending orders in a short time, often for the same cheap product.
- Random or disposable email addresses, and billing names that do not match anything.
- A sudden rise in declined payments in the gateway dashboard, and sometimes a warning or a suspension from the provider.

Even when the payments fail, each attempt can cost an authorisation fee, and a provider can close an account with too many declines. Defend in layers:

**Turn on WooCommerce's checkout rate limit.** Since WooCommerce 9.6, WooCommerce → Settings → Advanced → Features has a "Rate limit Checkout" option. It limits placing orders through the Checkout block and the Store API's `/checkout` endpoint to 3 requests per 60 seconds per visitor. Developers can tune the wider Store API rate limit with the `woocommerce_store_api_rate_limit_options` filter; it is off by default and, behind a CDN, needs its proxy support switched on to see real IP addresses.

**Use the gateway's fraud tools.** Payment providers score each payment and can block by risk, country or velocity. Turn on the card-testing and fraud rules your gateway offers and require CVC and address checks.

**Challenge bots before they reach PHP.** A CAPTCHA or a challenge such as Cloudflare Turnstile on the checkout stops scripted orders. Check that the plugin covers the Checkout block and the Store API, not only the classic shortcode checkout: bots often post to `/wp-json/wc/store/v1/checkout` directly. A CDN rate-limiting rule on that path and on `?wc-ajax=checkout` adds another layer.

**Clean up afterwards.** Cancel the fake orders, tell the provider what happened, and remove any test products or 0-price items the bots exploited.

## 5. Spot fraudulent orders

WooCommerce fraud is not only bots. Real orders placed with stolen cards come back weeks later as chargebacks, and you lose the goods and the money. Review orders that match several of these before shipping:

- Billing and shipping addresses in different countries, or a shipping address at a freight forwarder.
- A first order far above your average, especially of easily resold goods.
- Several cards tried for one order, or the same card on several accounts.
- Failed address or CVC checks reported by the gateway, visible in the order notes.
- Rushed shipping to a new customer.

When in doubt, contact the customer or refund before shipping. A refunded order costs less than a chargeback.

## 6. Protect the checkout page from skimmers

Card-skimming scripts, known as Magecart attacks, are injected into the checkout to copy what shoppers type or to show a fake payment form, then send the data to the attacker. They arrive through a hacked plugin, a stolen admin login or a compromised third-party script.

Three habits catch most of them:

- **Keep a list of scripts the checkout should load**, and compare it with what actually loads each month.
- **Load as little as possible on the checkout**: no chat widget, no A/B testing tool, no unnecessary tracking.
- **Add a Content Security Policy** that allows scripts only from your own domain and your payment provider, and reports anything else.

[Magecart card skimming on WooCommerce](https://getreport.app/guides/magecart-card-skimming-woocommerce) explains how skimmers hide in the database and in fake plugins, and how to detect them from the outside and the inside.

## 7. Review API keys, webhooks and integrations

Stores connect to accounting, shipping, marketplaces and email tools, and each connection is a key to your data.

- **REST API keys:** WooCommerce → Settings → Advanced → REST API. Delete keys you do not recognise, and give each integration its own key with the lowest permission it needs (Read, not Read/Write).
- **Webhooks:** WooCommerce → Settings → Advanced → Webhooks. Remove webhooks to addresses you do not recognise; they receive order data.
- **Application passwords:** Users → Profile → Application Passwords. Revoke the ones for apps you no longer use.

A webhook or API key added by an attacker keeps working after you change every password. Check these during any incident.

## 8. Customer data in logs, backups and staging

Order data is personal data, and it spreads further than the database.

- **Retention.** WooCommerce → Settings → Accounts & Privacy → Personal data retention can remove inactive accounts and anonymise old orders automatically. Set it to what your accounting rules require and no longer.
- **Logs.** WooCommerce writes logs to `wp-content/uploads/wc-logs/` with hard-to-guess file names and an `.htaccess` file that denies access. nginx ignores `.htaccess`, so on nginx add a rule that denies that folder. Gateway debug logging should be off in production.
- **Backups** contain every order. Store them off the server, encrypted, and never in a public folder.
- **Staging** copies of the store carry real customer data. Password-protect them, or anonymise the data when you copy it.

## 9. Do you need a WooCommerce security plugin?

A WooCommerce security plugin is a WordPress security plugin; there is no separate category. What matters for a store is that it covers the store's own endpoints. When you compare them, check that the login protection also covers the my-account login, that the bot protection covers the Checkout block and the Store API, and that the firewall does not break payment callbacks from your gateway.

The same rule applies as on any site: one plugin, never two, and prefer your host's or CDN's firewall. [WordPress security plugins: what they do and when you need none](https://getreport.app/guides/best-wordpress-security-plugins) breaks the products down job by job.

## How getReport helps

getReport checks the public side of the store. The [WordPress security scan](https://getreport.app/tools/wordpress-checker) flags an outdated WordPress version, closed or abandoned plugins, readable `.env` or `.git` files and missing HTTPS:

> **Free tool:** [WordPress security scan and health check](https://getreport.app/tools/wordpress-checker): Free WordPress security scan and health check from the outside: outdated core, closed plugins, exposed files, blocked indexing and classic launch mistakes.

> **Check: No detected plugin has been closed on wordpress.org.** wordpress.org closes plugins for unfixed security issues or guideline violations. A closed plugin gets no updates and often has a known vulnerability.
>
> 1. Replace the plugin now; the reason shown by wordpress.org tells you how urgent it is.
> 2. Until then, keep the site behind a firewall plugin and check the vulnerability databases for the plugin name.

> **Check: Every detected plugin has a recent update.** A plugin nobody maintains will not get security fixes and eventually breaks with a WordPress update. Two years without a release is the usual sign that it is abandoned.
>
> 1. Look for a maintained alternative with the same feature and replace the plugin; test on staging first.
> 2. If it is essential and small, consider paying a developer to take it over.

> **Check: CMS version.** Old CMS versions have published security holes that bots scan for automatically, and the generator tag advertises the exact version to them.
>
> 1. Back up the site, then update the CMS from its admin dashboard; update plugins and themes at the same time.
> 2. Remove the generator tag (WordPress: remove_action('wp_head', 'wp_generator') in functions.php).

> **Check: No sensitive files are readable.** /.env holds database passwords and API keys; /.git exposes your source code and every secret ever committed. Both are the first things an automated scanner asks for.
>
> 1. Block dotfiles at the web server (nginx: location ~ /\. { deny all; }; Apache: RedirectMatch 404 /\..*$).
> 2. Move .env outside the web root and rotate every credential in it; assume the file has already been copied.

> **Check: The site is served over HTTPS.** Browsers label HTTP pages "Not secure" and Google uses HTTPS as a small ranking signal. Anyone on the network can read or alter what visitors see.
>
> 1. Get a certificate (Let's Encrypt is free) and enable HTTPS on your host.
> 2. Redirect every http:// URL to https:// with a 301.

The [WooCommerce checker](https://getreport.app/tools/woocommerce-checker) tests whether `/cart/` or `/checkout/` are served from a cache. That is a speed finding, but also a privacy one: a cached cart can show one shopper another shopper's basket.

> **Check: Cart and checkout bypass the page cache.** A cached /cart/ or /checkout/ shows one visitor another visitor's basket, breaks nonces and payment forms, and produces the "session expired" errors shoppers abandon on. Every caching plugin excludes these pages by default; a CDN or host cache in front of them often does not.
>
> 1. Exclude /cart/, /checkout/ and /my-account/ (and their translations) from every cache layer: the caching plugin, the host's page cache and the CDN (Cloudflare: a Cache Rule with "Bypass cache" for those paths and for requests with a woocommerce_* cookie).
> 2. Re-test after purging: the responses should carry cache-control: no-store or a cache status of BYPASS/MISS.

The [security headers checker](https://getreport.app/tools/security-headers) shows whether the page sends a Content Security Policy, the header that limits which scripts a checkout may load:

> **Check: Content-Security-Policy header is set.** A CSP blocks most cross-site scripting attacks by listing where scripts may load from. Without one, a single injected script can steal sessions or card data.
>
> 1. Start in report-only mode with Content-Security-Policy-Report-Only to see what would break.
> 2. Move to an enforcing policy once the report is quiet; keep "unsafe-inline" out of script-src.

None of these tools log in, submit a form or place an order, so card testing protection, roles and API keys are for you to check inside the admin.

## Common mistakes

- **Everyone is an Administrator.** A stolen shop-assistant login then installs a plugin. Use Shop Manager.
- **CAPTCHA on the classic checkout only.** Bots post to the Store API behind the Checkout block. Check what your plugin covers.
- **Payment gateway debug logs left on.** They can hold order and payment details. Turn them off after troubleshooting and delete the files.
- **Old API keys from a former agency or tool.** They keep working. Review WooCommerce → Settings → Advanced → REST API.
- **A live staging copy with real orders.** It is usually older, less protected and full of personal data. Lock it or anonymise it.

## Questions people ask

### Is WooCommerce secure?

Yes, WooCommerce itself is maintained by a dedicated team and receives regular security releases, and card data stays with the payment provider when you use hosted fields or a hosted payment page. The risks are around it: outdated extensions, weak staff logins, card-testing bots and injected scripts on the checkout. Keep everything updated, use two-factor login and the Shop Manager role, and watch what loads on the checkout.

### How do I stop card testing on WooCommerce?

Turn on the "Rate limit Checkout" option under WooCommerce → Settings → Advanced → Features (WooCommerce 9.6 or later), enable your payment gateway's fraud and card-testing rules, and add a bot challenge that covers the Checkout block and the Store API, not only the classic checkout. A CDN rate-limiting rule on the checkout endpoints adds a layer before PHP. Then cancel the fake orders and tell your payment provider.

### What is the Shop Manager role in WooCommerce?

It is a role WooCommerce adds for store staff. A Shop Manager can manage products, orders, coupons, reports and WooCommerce settings, but cannot install plugins, switch or edit themes, or edit code. Give it to everyone who runs the shop day to day and keep Administrator for the people who maintain the site, so a stolen staff login cannot install malware.

### Does WooCommerce store credit card numbers?

Not when you use a modern payment gateway. With hosted payment fields or a hosted payment page, the card number goes from the shopper's browser straight to the payment provider, and WooCommerce stores only the order, the last four digits and a token for saved cards. Never collect card numbers in custom fields, order notes or emails, and ask your provider which PCI questionnaire applies to you.

### How can I tell if a WooCommerce order is fraudulent?

Look for several warning signs together: billing and shipping in different countries, a freight-forwarding address, a first order far above your average, several cards tried, failed address or CVC checks in the order notes, and rushed shipping. Hold such orders, contact the customer, or refund before shipping. Your gateway's risk score, shown in the order or the provider's dashboard, is the best single signal.
