SecurityAugust 4, 20265 min read

How to Secure a Self-Hosted WordPress Site

WordPress powers a huge share of the web, which makes it a huge target. Harden your self-hosted install at the server, app, and login layers.

NBy Nxeon

WordPress runs a large slice of the web, which makes it the most attacked application on it. Most compromises aren't sophisticated โ€” they exploit weak passwords, outdated plugins, and misconfigured servers. If you self-host on a VPS, you control every layer, so you can genuinely lock it down. Here's how.

Start with a secure server

WordPress security starts below WordPress. Make sure the VPS itself is hardened: SSH keys, a firewall, and automatic updates. A compromised server means a compromised site regardless of WordPress settings.

Always use HTTPS

Serve everything over TLS so logins and cookies aren't sent in the clear. Free certificates from Let's Encrypt make this trivial โ€” see free SSL for a custom domain. Force HTTPS by redirecting all HTTP traffic and setting FORCE_SSL_ADMIN in wp-config.php:

define('FORCE_SSL_ADMIN', true);

Get file permissions right

WordPress files should be owned by your web user and not world-writable:

sudo find /var/www/wordpress -type d -exec chmod 755 {} \;
sudo find /var/www/wordpress -type f -exec chmod 644 {} \;
sudo chown -R www-data:www-data /var/www/wordpress

Lock down wp-config.php tighter since it holds your database credentials:

sudo chmod 640 /var/www/wordpress/wp-config.php

Disable the built-in file editor

The dashboard's theme/plugin editor lets anyone who gains admin access run PHP instantly. Turn it off in wp-config.php:

define('DISALLOW_FILE_EDIT', true);

{{SCREENSHOT}}

Protect the login page

wp-login.php is brute-forced constantly. Defences:

  • Strong, unique admin passwords and a non-"admin" username.
  • Limit login attempts with a plugin, or ban offenders with fail2ban using a WordPress filter.
  • Rate-limit at the web server. In Nginx:
location = /wp-login.php {
    limit_req zone=login_limit burst=3 nodelay;
    include fastcgi_params;
    fastcgi_pass unix:/run/php/php-fpm.sock;
}

For the full brute-force picture, see protect a VPS from brute-force attacks.

Keep core, themes, and plugins updated

Outdated plugins are the number one WordPress attack vector. Enable automatic updates for minor core releases in wp-config.php:

define('WP_AUTO_UPDATE_CORE', 'minor');

Remove plugins and themes you don't use โ€” every one is potential attack surface.

Harden the database and secrets

Your database should be locked to localhost with a least-privilege user. Regenerate WordPress security keys (salts) in wp-config.php from the official secret-key generator, and treat wp-config.php like any other secret โ€” see manage secrets and environment variables.

Back it up

Even a hardened site can have a bad day. Automate backups of both files and the database, and test restores โ€” see automated backups on a VPS.

Add security headers

Response headers let the browser enforce protections for you. Add these in your Nginx server block (or via a plugin) to reduce clickjacking, MIME sniffing, and mixed-content risks:

add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Strict-Transport-Security (HSTS) tells browsers to always use HTTPS for your domain, closing the window for downgrade attacks โ€” only enable it once you're confident HTTPS is working everywhere. A Content-Security-Policy is the most powerful header of all for blocking injected scripts, but it needs careful testing against your theme and plugins, so introduce it in report-only mode first.

Reduce what you expose

Attackers fingerprint WordPress to target known plugin vulnerabilities, so give them less to work with:

  • Hide the version. Remove the generator meta tag and readme files that advertise your exact WordPress version.
  • Block XML-RPC if you don't use it โ€” xmlrpc.php is a common brute-force and amplification vector. Deny it at the web server.
  • Protect wp-config and dotfiles. Ensure the web server never serves wp-config.php, .htaccess, or .git directories.
  • Disable directory listing so browsing /wp-content/uploads/ doesn't reveal your structure.

None of this is a substitute for updates and strong passwords, but it removes the easy reconnaissance that automated tools rely on. Combine it with the firewall and fail2ban layers, and your self-hosted site is a genuinely hard target โ€” often harder than the average managed install, because you control every layer.

FAQ

Do I need a security plugin?

A reputable one helps with login limiting and scanning, but it's no substitute for server hardening, HTTPS, updates, and strong passwords. Layer them.

Why disable the file editor?

If an attacker gets one admin session, the editor lets them write PHP and take over the server instantly. Disabling it removes that fast path.

How do I stop wp-login brute-force?

Combine limited login attempts, rate limiting at the web server, and fail2ban. A non-obvious admin username and strong password make guessing pointless.

Is self-hosting WordPress less secure than managed hosting?

No โ€” you control every layer, which can be *more* secure if you apply these steps. Managed hosting trades control for convenience. On a VPS you get both, with effort.

WordPress hardening checklist

Work through this and you've addressed the ways real WordPress sites actually get hacked:

  • Secure the server first: SSH keys, firewall, automatic updates.
  • Force HTTPS everywhere and set FORCE_SSL_ADMIN.
  • Fix file permissions (755 dirs, 644 files, 640 for wp-config.php) and set correct ownership.
  • Disable the dashboard file editor with DISALLOW_FILE_EDIT.
  • Protect wp-login with strong passwords, limited attempts, rate limiting, and fail2ban.
  • Keep everything updated and delete unused plugins and themes.
  • Lock down the database, regenerate salts, and add security headers.
  • Back up files and database, and test the restore.

Most of these take minutes and, together, they close the weak passwords, outdated plugins, and misconfigurations behind the vast majority of compromises. Because you self-host, you can apply every layer โ€” which is exactly why a well-maintained self-hosted install can be more secure than an average managed one, not less. The catch is the word "maintained": self-hosting trades convenience for control, and that control only helps if you actually keep updates flowing and revisit the checklist periodically. Set up automatic core and plugin updates, schedule a monthly five-minute review, and the ongoing effort stays tiny while your site stays a hard target.

A hardened WordPress site starts with a hardened server. Run yours with full root access on NVMe โ€” see WordPress VPS hosting and our security page.

#wordpress#security#php#nginx#vps#seobatch

Deploy your first server in under a minute

Creating an account is free and takes no card details. You pay when you deploy โ€” choose a billing term and pay from your wallet or by card at checkout.