Leave a request
Thank you for your request
We will review the details of your project and prepare a commercial offer for you.

WordPress Store Security: Common Vulnerabilities and How to Fix Them

Store owners usually find out about a security problem one of two ways: a call from hosting support saying “we found malicious code on your account,” or a customer complaining their card was charged after checking out on the site. A third option barely exists – a hack rarely looks like a skull-and-crossbones popup. Most of the time it’s just a slightly slower site, a strange folder inside /wp-content/uploads full of .php files, and rankings that quietly slide because the store has been serving links to a casino site without anyone noticing.

WordPress itself isn’t the weak point. The weak points are almost always plugins, themes, and admin habits. Here’s where WooCommerce stores actually break, and what to do about each one – not the generic “keep everything updated” advice.

Laptop with website code and a suspicious activity alert

Outdated plugins and themes – the most common way in

On sites that have already been hacked, the pattern is often a familiar one: an old slider plugin, an abandoned theme pulled from a template marketplace, a shipping calculator the author stopped updating three years ago. Someone publishes the vulnerability in a database like WPScan, and within days bots are scanning the web for sites running that exact version.

That means checking the “needs update” list weekly and removing anything you don’t actually use – a deactivated plugin is still the same code sitting on disk, just as exploitable. Nulled themes and plugins deserve extra suspicion: a pirated copy of a paid plugin almost always ships with a backdoor baked in by whoever cracked it. Not an urban legend, just a routine finding when cleaning infected sites.

Weak admin passwords and no two-factor login

The username admin with a password built from the store name plus 2026 is still common. Brute-force bots try exactly those combinations thousands of times an hour – they don’t need to be clever, just patient.

  • Rename the admin username away from admin – create a separate account and remove or downgrade the old one.
  • Turn on two-factor authentication. Wordfence Login Security or miniOrange 2FA take about ten minutes to set up.
  • Cap login attempts. Limit Login Attempts Reloaded, or the equivalent built into a broader security plugin.

Then there’s staff access – anyone with admin or FTP credentials. One weak password on a manager account that just adds products can undo every other layer of protection.

File upload forms with no restrictions

An “upload a photo for your review” form or an “attach a file to your return request” field is genuinely convenient for shoppers. But if the plugin or custom code doesn’t check the file extension, and the server allows PHP to execute inside the uploads folder, an attacker doesn’t upload a photo – they upload a web shell, a small PHP file that hands over full control of the site through an ordinary browser.

Fix it on two levels. On the plugin side, use an allowlist of extensions (jpg, png, pdf) instead of a blocklist. On the server side, block PHP execution inside /wp-content/uploads/ with a rule in .htaccess or the Nginx config. Five minutes of work that closes off an entire class of attacks.

wp-config.php, debug mode, and prying eyes

wp-config.php stores database credentials in plain text and should never be reachable from outside at all. But it happens – after a botched migration or backup, a wp-config.php.bak or wp-config.php~ file shows up, and the server serves those as plain text instead of executing them as PHP.

The second issue is WP_DEBUG left on in production “just to see the error.” It prints server paths, table names, sometimes raw code straight into any visitor’s browser. Check it once: WP_DEBUG should be false on the live site, errors logged to a file that isn’t publicly reachable, not printed to the screen.

Vulnerable plugin code – SQL injection and XSS in reviews

This part is harder, because it’s not a settings problem, it’s a code quality problem in someone else’s plugin. A review plugin that inserts a shopper’s text into a database query without escaping it is a textbook SQL injection – enough to pull the entire orders table, addresses and phone numbers included. A plugin that prints comments as-is, without stripping tags, opens the door to XSS: the attacker leaves a script instead of a review, and it runs in the next visitor’s browser, or even the admin’s while moderating comments.

You can’t eliminate this risk entirely once third-party plugins are involved, but you can cut it down a lot – favor actively maintained plugins with a large install base, check the last update date before installing anything, and run a security plugin with virtual patching (Wordfence does this), which blocks known attack patterns at the request level before the vulnerable plugin code ever processes them.

File upload form on an online store with a warning icon

Brute-force login attempts, and why rate limiting isn’t enough

Even with clean code, a site can be brought down by sheer volume – thousands of requests to wp-login.php a minute, chewing through hosting resources and, sooner or later, guessing a weak password. Limiting login attempts is a floor, not a fix. Real protection means hiding wp-login.php from direct access (WPS Hide Login lets you set a custom login URL), adding a CAPTCHA, and pushing the defense in front of the server entirely – the hosting firewall or Cloudflare.

REST API and XML-RPC – the endpoints everyone forgets

By default, the WordPress REST API exposes the site’s user list at /wp-json/wp/v2/users/ – including admin logins, even when the display name is something else. A ready-made target list for brute force, and it stays open mostly because nobody checked what the API was quietly handing out.

XML-RPC is an older protocol almost nobody uses anymore, aside from the occasional mobile posting app, but it stays enabled by default and gets used for the same brute-forcing – just routed around the usual limits on wp-login.php. If you don’t need it, disable it entirely through .htaccess or a plugin.

HTTPS, mixed content, and payment forms

Almost every store has an SSL certificate by now, so HTTPS itself rarely gets forgotten. Mixed content is a different story – a page loads over https, but an image or script still loads over http, the browser flags the connection as not secure, and shoppers close the tab right there, often on the checkout page of all places.

Payment forms are their own topic. If the form is embedded directly on the site instead of redirecting to the bank’s or processor’s own page, the store technically falls under PCI DSS, and storing or even briefly logging card numbers on your own server is a fast way to get fined or dropped by the processor. The safer setup is a hosted payment form or an iframe, so card data never touches your server at all.

Backups, staging, and a plan for if you do get hacked

Even with solid defenses, assume something eventually goes wrong – a fresh zero-day, a human mistake, a hole on the hosting side itself. What saves you then isn’t antivirus software, it’s a backup taken before the incident and actually confirmed to restore.

  • Automated daily backups of the database and files, stored off the main server – UpdraftPlus pushing to cloud storage, not just another folder on the same disk.
  • A test restore once a quarter. A backup that’s never been restored has just as good a chance of being a broken archive as a working one.
  • Plugin and theme updates go to a staging copy first (WP Staging or your host’s built-in option) and only reach production after they’ve been checked. That catches not just security fallout from the update itself but the usual plugin conflicts too.

Server rack representing a backup

If a breach has already happened, the first move isn’t to start deleting files in a panic – take the site offline (maintenance mode or a full shutdown), change every password: admin, database, FTP, hosting panel, and only then start figuring out what actually got in and how long it had been sitting there.

None of this takes very long on its own. The real issue is usually that none of it got done in the first place – the store launched, sales started coming in, and “we’ll sort out security later” never turned into an actual task. The easiest way to start is not trying to fix everything at once. Pick one item from this list and handle it this week – turning on 2FA for yourself and your team is a good place to start. The rest tends to follow.

Read also: A Yearly Update Schedule: How to Avoid Breaking Your Store Right Before Peak Season; “The Site Went Down Mid-Season”: What an SLA Actually Needs to Guarantee to Stop You Losing Money.

Share this article:
Fresh articles
All articles
How to Set Up Multi-Language Support for an Online Store
Picture a store owner who adds German with a translation plugin one evening and calls it done. Then somebody opens checkout: the…
Why Google Merchant Center Rejects Products: The Feed Errors That Keep Coming Back
A Shopping campaign goes live, impressions start rolling in, and two days later half the catalog vanishes from ads. Merchant Center shows…
API Integrations That Don’t Break: Building Reliable Sync Between CRM and Warehouse Systems
A client came to us a few weeks ago with a complaint that sounded minor at first: every so often, an order…
Can we talk about the project?
Write to us and we will contact you shortly to discuss the details of your idea.
A cool project starts with filling out this form.

    * Required to fill in