WordPress runs roughly 40% of the web, which makes it both the most battle-tested CMS in existence and the most frequently attacked. The question “is WordPress secure” has two honest answers. The core itself – the code maintained by the WordPress project – is reasonably secure. It has a dedicated security team, regular patches, and automatic background updates for point releases. The much larger answer is that most WordPress sites run dozens of third-party plugins and themes of wildly varying quality on servers the site owner never hardened, and that is where breaches actually come from.
This article is the overview. It covers why WordPress gets targeted, the attack vectors in the order you are likely to meet them, the three layers of the security stack (server, application, ongoing), the mistakes that do most of the damage, and where managed hosting changes the picture. The individual topics – brute force attacks, malware, fail2ban, ModSecurity, the login page – have dedicated posts. This one ties them together.
Why WordPress is targeted#
The short version: market share, not inherent weakness.
If you are a person writing an attack script, you want it to work against the largest possible population of sites so a single tool returns the widest possible yield. WordPress is that population. A scanner that hits
/wp-login.php
or
/xmlrpc.php
on every IP address in a netblock will find thousands of hits. The same scanner targeting a less common CMS finds a handful. Attackers do what scales.
Related: WordPress is extensible by design. A core install is a small codebase written by a focused team, but the typical production site runs 15-40 plugins written by 15-40 different authors with 15-40 different ideas about security. Every plugin is another attack surface. A vulnerability in one installed-everywhere plugin (think Contact Form 7, Elementor, WooCommerce) instantly becomes a million-site problem.
This framing matters for how you defend the site. You are not trying to be secure against a human attacker who picked your site specifically. You are trying to be secure against automated scanners that do not care who you are and will move on to the next target the moment you cost more to breach than the next victim on their list.
Attack vectors in the order you will meet them#
Defense starts with understanding what actually gets used against WordPress sites. In rough order of frequency:
1. Brute force on the login page
Scanners hit
/wp-login.php
and
/xmlrpc.php
with credential lists – common usernames (admin, administrator, your domain name without the TLD, the author slug they pulled from
/wp-json/wp/v2/users
) combined with common or leaked passwords. XML-RPC makes this worse by amplifying: one XML-RPC request can test hundreds of username-password pairs in a single HTTP call, which is why it is the preferred vector for heavy brute forcing.
The full mechanics are in brute force attacks on WordPress. The mitigations: strong passwords, rename or restrict the login URL, rate-limit at the web server, enable two-factor authentication, disable or restrict XML-RPC, and (at the server level) run fail2ban against the login URL.
2. Vulnerable plugins and themes
Most successful WordPress breaches you read about are not core vulnerabilities. They are plugin vulnerabilities – usually in a plugin that has not been updated in years, or that was updated but the site owner did not apply the update. A single SQL injection or authenticated privilege escalation in a plugin installed on a million sites produces a market of easy targets for weeks after the advisory lands.
The defence is boring and it works: keep plugins updated, remove plugins you do not actively use (deactivated plugins that still exist in
wp-content/plugins/
are still on disk and still exploitable if the attacker gets file access), and prefer well-maintained plugins with active author responses in their support forums. Subscribe to a vulnerability feed like Patchstack or WPScan so you know when something in your stack is patched.
3. Outdated core
Core is less often the vector than plugins, but it happens. The largest incidents usually involve a site running a version that is years behind current. WordPress ships automatic background updates for minor releases (security and maintenance), which catches most of what matters. Major releases are opt-in and you should take them within a reasonable window – see WordPress automatic updates for the full picture on what updates automatically and what you still have to trigger.
4. Weak or reused passwords
Credential stuffing works because people reuse passwords across sites. A breach on a retailer hands attackers a list of email-password pairs, and they try those pairs on WordPress logins everywhere. If one of your editors used the same password on their breached forum account and your admin panel, you are now compromised through no fault of WordPress itself.
The counter is a password manager, enforcement of long unique passwords on WordPress accounts, and two-factor authentication for anything with the
edit_pages
capability or higher. The “admin” username is the other half of this – attackers default to it because it used to be the WordPress installer default. Reset the admin password and either rename that account or disable it entirely in favour of a uniquely-named administrator.
5. File permissions and file uploads
Two subcategories. The first is permissions – files and directories that are world-writable when they should not be, usually the result of someone running
chmod -R 777
to “fix” a permissions problem. That turns every file into something any user on the server can edit, which matters on shared hosting. The second is arbitrary file upload vulnerabilities – a plugin lets users upload files, but fails to validate the extension, and an attacker uploads a PHP file that gives them remote code execution.
The right permissions for a typical WordPress install:
755
for directories,
644
for files,
600
or
640
for
wp-config.php
. Do not run
chmod 777
on anything. On the upload side, the webserver should not execute PHP in
wp-content/uploads/
. Nginx and Apache configurations for WordPress should include a rule that disables PHP execution in the uploads directory – this is standard on any platform that knows WordPress, and it catches a whole class of upload-based attacks.
6. Exposed configuration and backup files
Site owners leak credentials surprisingly often: a
.env
file in the web root, a
wp-config.php.bak
from an editor save, a database dump left at
/backup.sql
, a
.git/
directory exposing the whole repository. Scanners probe for all of these. If they find one, they read it and move on to whatever the file enables (direct database access, S3 keys, admin credentials).
The fix is twofold. Never leave these files in the web root, and configure the webserver to deny access to them even if they do appear. A minimal nginx block to block hidden files and common backup extensions:
location ~ /\. { deny all; }
location ~ \.(sql|bak|old|orig|swp|tmp)$ { deny all; }
The security stack: three layers#
WordPress security is not one thing. It is three independent layers that back each other up. If you do only one layer, you have gaps. If you do all three, each failure is caught by the next one.
Layer 1: Server-level
This is what happens before a request ever reaches PHP. It is also the layer site owners think about least because hosting providers usually handle it, but it is where the highest-volume attacks get filtered out.
- Web application firewall. ModSecurity with the OWASP Core Rule Set blocks known attack patterns (SQL injection, XSS, common exploit signatures) at the nginx or Apache layer, before any PHP code runs.
- Fail2ban. fail2ban reads server logs and temporarily bans IPs that fail login attempts too many times, hit 404s too aggressively, or match abuse patterns.
- Rate limiting. The webserver should rate-limit requests per IP, with a lower rate on sensitive endpoints like
/wp-login.phpand/xmlrpc.php. This stops brute force attempts before they hit PHP at all. - Container or account isolation. On shared hosting, each account should be isolated from every other so that a breach of one site cannot spread. On managed WordPress hosting this is usually containerisation (Podman, Docker, or namespaces); on traditional shared hosting it may be just file system permissions, which is weaker.
- SELinux or AppArmor. A mandatory access control system that confines processes to only the files and network they need. Even if PHP is compromised, the attacker cannot pivot to system binaries or other users’ files.
- TLS everywhere. All traffic over HTTPS, HSTS header set so browsers refuse HTTP even if the user types it, modern cipher suites only.
Layer 2: Application-level
This is what you configure inside WordPress itself.
- Login protection. Rename
/wp-login.phpto something non-guessable using a plugin like WPS Hide Login, or restrict access to specific IPs at the webserver layer. The WordPress login URL article covers the mechanics. - Two-factor authentication. Use Wordfence, Two Factor, or the built-in 2FA in any decent security plugin for every account with publishing or admin capability.
- XML-RPC disabled or restricted. If you do not use Jetpack or the WordPress mobile app, disable XML-RPC entirely – either in
.htaccess, in nginx, or via a plugin. If you do need it, restrict it to specific IPs at the webserver. The full mechanics are in WordPress XML-RPC: what it is and how to disable or secure it. - Disable file editing in the admin. Add
define('DISALLOW_FILE_EDIT', true);to wp-config.php to remove the theme and plugin code editors from the dashboard. If an attacker phishes an admin account, they cannot drop a shell through the UI. - Disable file mods entirely in production. Stronger:
define('DISALLOW_FILE_MODS', true);removes plugin installs, theme installs, and updates from the admin – all changes have to happen through your deployment pipeline. Only appropriate for managed environments where you control deployment separately. - Principle of least privilege for user roles. Every account gets the smallest role that lets them do their job. Writers get Author, not Administrator. Clients who want to manage their own pages get Editor, not Administrator. Nobody gets Administrator unless they actually need to install plugins.
- Author slug obfuscation. Prevent
/wp-json/wp/v2/usersand/?author=1from enumerating real usernames. Most security plugins include an option for this, or you can add it manually.
Layer 3: Ongoing operations
Security is a process, not a state. The ongoing layer is where most sites slip.
- Updates, applied within a reasonable window. Core security releases within days. Plugins within a week for critical vulns, within a month for everything else. WordPress automatic updates explains what you can safely automate and what you still need to check.
- Backups that actually work. Daily backups, stored off-server, retention window that covers “we noticed the compromise two weeks late” (minimum 30 days is the realistic floor). Test restores quarterly so you know the backup is actually readable. A backup you have never restored is a hope, not a backup.
- Test updates on a staging site. Before pushing a plugin or core update to production, apply it on a WordPress staging site first. Catches the “this update breaks the checkout” class of incident before it hits customers.
- Monitoring. Something should tell you the site is still up, still serving 200s, still logged in-able. When something breaks, you should know within minutes, not when a customer emails support.
- Malware scanning. Periodic or real-time file scanning against known malware signatures and against file hashes of your own theme and plugin files. Wordfence does this at the application layer. Server-side filewatchers do it at the filesystem layer, which catches things Wordfence cannot (malware dropped by compromised credentials into a directory the plugin does not scan). If you are checking by hand, how to check a website for malware covers the basics, and WordPress malware covers cleanup.
- Incident response plan. Know in advance what you do if the site is hacked: isolate, restore from clean backup, rotate all credentials, audit logs. My WordPress site was hacked: what to do right now is the playbook.
Common mistakes that do most of the damage#
Most WordPress breaches are not novel. They are one of the same five mistakes:
- Username “admin” with a weak password. Still the single most common cause of brute force compromise. Rename the account, enable 2FA, and rate-limit the login.
- Plugins installed, deactivated, and forgotten. A deactivated plugin is still on disk. If it has a vulnerability and an attacker gets in through some other route, they can re-enable or directly exploit it. Delete plugins you do not use.
- No backups or backups only on the same server. When the server gets encrypted by ransomware or you discover malware you cannot remove cleanly, a backup on the same server is worthless. Off-site, verified, with restore tested.
- Nulled plugins and themes. Free downloads of paid plugins, usually bundled with a backdoor that gives the distributor admin access to your site. Never install a plugin or theme from anywhere except WordPress.org, a commercial vendor’s own site, or your own developer. The “savings” are an illusion – you are paying with the entire site.
- Running end-of-life PHP. Old PHP versions stop receiving security patches. A site on PHP 7.2 in 2026 is running unpatched code at the foundation of everything else. End-of-life PHP: the risks of running an unsupported version goes into specifics.
Managed WordPress hosting vs unmanaged VPS#
“Managed WordPress hosting” covers a wide range, but from a security standpoint the thing you are actually buying is the server-level layer (Layer 1 above). On a good managed WordPress host:
- ModSecurity with a curated ruleset is already running and tuned for WordPress.
- Fail2ban is watching login and admin paths.
- Rate limits are configured per-site.
- Accounts are isolated in containers or their equivalent.
- SSL is automatic and renewing itself.
- PHP versions are maintained and upgradeable from the control panel.
- Backups run automatically.
- Malware scanning runs at the filesystem layer continuously.
On an unmanaged VPS, you do all of that yourself. That is not impossible and it is not even particularly hard if you know what you are doing – but it is work, and a lot of sites get breached because the site owner meant to configure it and never got around to it. What is managed WordPress hosting has the broader feature comparison; the relationship between Wordfence and server-level security explains why even a strong application-layer plugin benefits from server-layer backing.
Hostney’s WordPress stack runs all of these server-level protections by default. Every account runs in an isolated Podman container so a compromise cannot spread. SELinux is in enforcing mode, ModSecurity with OWASP rules is on every nginx vhost, fail2ban watches authentication endpoints, a filewatcher daemon flags filesystem changes in real time, and the edge layer runs a behavioural bot-protection system that scores incoming traffic and challenges suspicious requests with proof-of-work before they reach PHP. DDoS hardening and per-IP rate limiting are configured at the webserver level, and automatic SSL from Let’s Encrypt handles TLS without manual renewal. This is what “managed WordPress security” should mean: you write content, the platform handles the surface area.
Summary#
WordPress is as secure as you configure it. Core is fine. The attack surface is plugins, credentials, and configuration, and every one of those is under your control. The defence is three layers – server, application, ongoing operations – and each layer has a short list of things to do. Do them once, maintain them, and the automated scanners that make up 99% of real-world WordPress attacks move on to easier targets. The remaining 1% requires more work, but you get that work for free on a managed host that treats security as default rather than something you have to configure yourself.