How to Secure WordPress Without Security Plugins
Quick answer: Yes, you can secure WordPress without any security plugins. Most real protection comes from two layers you control directly: application hardening (wp-config.php rules, correct file permissions, disabled file editing) and server-level controls (a web-server firewall, blocked PHP execution, least-privilege database access). Plugins add convenience and monitoring, not the foundation.
After manually cleaning more than 4,500 hacked WordPress sites, one pattern repeats: the site that gets reinfected almost always had a security plugin installed, and was breached anyway. The plugin was never the problem. It just was not the foundation.
The numbers explain why. Patchstack’s 2026 report counted 11,334 new WordPress vulnerabilities in 2025, a 42% jump year over year. Plugins accounted for 91% of them; WordPress core had just two. The weighted median time from public disclosure to first exploitation was five hours. You cannot patch fast enough to win that race. The most reliable thing you can do is shrink what an attacker can reach in the first place, and almost all of that work needs zero plugins.
This guide is the no-plugin path: the server-level and application-level hardening I apply after every cleanup. If you would rather compare dedicated tools, see my breakdown of the best WordPress security plugins, but read this first, because no plugin replaces the basics below.
Server-level vs. application-level security: the model that matters
Every control on a WordPress site lives at one of two layers, and knowing which is which tells you what you can do without a plugin.
Application-level security runs inside WordPress: PHP, wp-config.php, the database WordPress reads, and the admin dashboard. Every security plugin lives here. So do wp-config rules and file-editing controls.
Server-level security runs below WordPress: the web server (Apache, Nginx, or LiteSpeed), the PHP runtime, the file system, the MySQL or MariaDB server, and the operating system. A request reaches this layer before WordPress ever loads.
The difference is when each layer acts. A server-level firewall can drop a malicious request before a single line of PHP runs, which is cheap and resilient. An application-level plugin only sees a request after WordPress has loaded, which is exactly why malware that gains file access can often switch the plugin off and hide its tracks.
| Layer | Where it runs | Good at | Blind to | No-plugin tools |
|---|---|---|---|---|
| Application | Inside WordPress (PHP) | Login rules, 2FA, WordPress-specific hardening, change logging | Anything outside WordPress; can be disabled once files are compromised | wp-config.php constants, functions.php filters, WP-CLI |
| Server | Below WordPress (OS, web server, DB) | Dropping bad requests early, blocking PHP execution, file integrity, brute-force throttling | WordPress user authentication; intent of a “valid” request abusing a plugin | .htaccess / Nginx rules, php.ini, ModSecurity, fail2ban, file permissions |
But neither layer wins alone. Patchstack tested standard hosting defenses in 2025 and found that 87.8% of real-world WordPress attacks bypassed them, because those attacks abuse WordPress against itself: a vulnerable plugin doing exactly what its own code permits. So the goal is not “server good, plugin bad.” It is: reduce the attack surface first, then harden both layers.
Why fewer plugins is itself a security control
Every plugin is third-party code running on your server with broad access to your files and database. With 91% of WordPress vulnerabilities living in plugins, and many of them in abandoned plugins that will never be patched, the math is simple: the less third-party code you run, the less an attacker can target and the less you have to patch inside that five-hour window.
In nearly every cleanup I do, the entry point is a vulnerable or nulled plugin or theme, not WordPress core. So treat plugin reduction as a control in its own right. If a feature can be achieved with a few lines in functions.php or a single server rule, prefer that over installing a plugin. Audit quarterly, and delete rather than just deactivate anything unused, because a deactivated plugin still sits on disk and remains reachable. For the broader maintenance routine, see my full guide on how to secure a WordPress site.
Application-level hardening (no plugins required)
These controls live in wp-config.php, your server config, and core WordPress settings. None of them need a plugin.
Lock down wp-config.php
This file holds your database credentials and secret keys, so it deserves the tightest permission on the site. Set it to 600 (or 640 if your host requires group read), and if your host allows it, move it one level above the web root.
# Restrict wp-config.php to the owner only
chmod 600 wp-config.php
Disable the built-in file editor
This is the single most useful one-line change I recommend after a cleanup. When an attacker gets one admin session, the first thing they often do is open Appearance › Theme File Editor and paste a backdoor straight into the theme, no FTP needed. I have traced more than one reinfection back to exactly this path, including a hidden backdoor in a client’s site. Turning the editor off removes that one-click route.
// In wp-config.php, above the "stop editing" line
define( 'DISALLOW_FILE_EDIT', true );
Disable file modifications (advanced)
DISALLOW_FILE_MODS goes further: it blocks plugin and theme installs, deletions, and updates from the dashboard. That is powerful, but it has a real trade-off, you also lose automatic updates. Only use it if you patch another way, such as WP-CLI or a deployment pipeline. On a site that is managed by hand and rarely changes, it is one of the strongest anti-tamper controls available.
// Blocks ALL file changes from the dashboard, including updates
define( 'DISALLOW_FILE_MODS', true );
Refresh secret keys and force HTTPS in the admin
Your authentication salts sign the cookies that keep you logged in. Regenerating them invalidates every existing session, which is exactly what you want after any suspected breach, it logs out an attacker who may be riding a stolen cookie. Grab a fresh set from the official generator and replace the matching block in wp-config.php.
# Generate a fresh set of keys and salts
https://api.wordpress.org/secret-key/1.1/salt/
// Then force the admin and login over HTTPS
define( 'FORCE_SSL_ADMIN', true );
Block PHP execution where it does not belong
Most webshells get dropped into wp-content/uploads, because that folder is writable. Blocking PHP from running there neutralizes the payload even if the file lands on disk, which is one of the highest-value server rules you can add. It is the same principle behind a lot of the .htaccess malware cleanups I handle.
# Apache: place in wp-content/uploads/.htaccess
<Files *.php>
Require all denied
</Files>
# Nginx: add to your server block
location ~* /wp-content/uploads/.*\.php$ {
deny all;
}
Shut down XML-RPC if you do not use it
xmlrpc.php is a common target for brute-force amplification and pingback abuse. If you do not use the WordPress mobile app, Jetpack, or an external publishing tool, block the endpoint at the server. Confirm those integrations are not in use first, since this will break them.
# Apache: in the root .htaccess
<Files xmlrpc.php>
Require all denied
</Files>
Strip version giveaways and manage application passwords
Remove the WordPress generator tag, delete the default readme.html, and uninstall unused themes so attackers cannot fingerprint exact versions. Application passwords are another quiet risk: they grant API access and, if leaked, behave like a backdoor. If you do not connect external apps over the REST API, disable them with a one-line filter, no plugin and no Wordfence required.
// In functions.php or a small must-use plugin
add_filter( 'wp_is_application_passwords_available', '__return_false' );
For login-specific measures beyond this, such as 2FA and protecting the login URL, see my dedicated guide on how to secure WordPress login.
Server-level hardening (no plugins required)
What you can do here depends on your hosting. On shared hosting you usually have file and .htaccess access but no SSH or php.ini control, so ask your host what is already enabled. On managed WordPress hosting, much of this is configured for you. On a VPS, you control all of it. Apply what your environment allows.
Set correct file and folder permissions
The standard is 755 for directories, 644 for files, and 600 for wp-config.php. Never use 777 on anything; it lets any process write to that file, which is how a lot of cross-account infections spread on shared servers. If you do not have SSH, you can correct permissions with my no-SSH PHP permissions script.
# Run from your WordPress root over SSH
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
chmod 600 wp-config.php
Disable directory browsing
If directory listing is on, anyone can browse your folder structure and read what plugins and backups you have. Turn it off at the server.
# Apache: in the root .htaccess
Options -Indexes
Restrict dangerous PHP functions
Most webshells rely on PHP’s command-execution functions. Disabling the ones a normal WordPress site never needs removes a huge amount of a shell’s capability even if one is uploaded. Test after applying, since a few hosts or plugins may need one of these.
# In php.ini (VPS / managed with access)
disable_functions = exec,shell_exec,system,passthru,popen,proc_open
Add a server firewall and brute-force blocking
This is the server-level equivalent of what a plugin firewall does, except it acts before PHP loads. On a VPS or capable managed host, run ModSecurity with the OWASP Core Rule Set to filter malicious requests, and fail2ban to ban IPs that hammer wp-login.php. On shared hosting, ask whether ModSecurity is already active; it often is.
Lock down the database
Give WordPress a dedicated MySQL user scoped to a single database, with a long random password. Do not use the root account, and never reuse the same database user across multiple sites, that is how one compromised site becomes several. Changing the wp_ table prefix is sometimes suggested too, but it is a low-impact, defense-in-depth measure that can break a site if done carelessly, so I treat it as optional rather than essential.
Enforce HTTPS and security headers at the server
Security headers are pure server config, no plugin needed. They harden the browser side against clickjacking, MIME sniffing, and protocol downgrade.
# Apache: in the root .htaccess
Header always set X-Content-Type-Options "nosniff"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
The one thing hardening cannot replace: knowing when something changed
Hardening shrinks the attack surface. What it does not do is tell you the day a brand-new vulnerability in a plugin you actually use gets weaponized within five hours. That detection-and-virtual-patching gap is the honest, legitimate argument for security plugins. Pretending hardening is invincible is how sites get reinfected after a cleanup.
You can cover the monitoring half without a plugin. WP-CLI verifies your core and plugin files against the official checksums, so any modified or injected file shows up immediately.
# Verify core and all plugin files against wordpress.org checksums
wp core verify-checksums
wp plugin verify-checksums --all
Schedule those commands with a cron job and you have genuine file-integrity monitoring with zero plugins. The one piece that hardening and checksums still cannot cover is virtual patching of an unpatched vulnerability inside that five-hour window. For that you genuinely need either a server WAF rule, a managed host that does it for you, or a focused security plugin. Be honest about that single trade-off instead of treating “no plugins” as a complete defense.
No-plugin WordPress hardening checklist
-
- Delete unused plugins and themes; keep everything else updated.
-
- Set permissions: 755 directories, 644 files, 600 for wp-config.php.
-
- In wp-config: add
DISALLOW_FILE_EDIT, refresh salts, force SSL in admin.
- In wp-config: add
-
- Block PHP execution inside wp-content/uploads.
-
- Disable directory browsing.
-
- Restrict dangerous PHP functions in php.ini.
-
- Scope the database user to one database with a strong password.
-
- Block xmlrpc.php if you do not use it.
-
- Add HTTPS and security headers at the server.
-
- Schedule WP-CLI checksum verification as integrity monitoring.
When to bring in a specialist
One critical caveat: if your site is already infected, do not harden on top of the infection. Locking down a compromised site just locks the attacker’s backdoor in with it. Clean first, then harden. In 4,500-plus cleanups I have seen well-meaning owners apply every step above while a webshell sat untouched in an uploads folder, which is how, for example, this Bluehost site recovery started.
If your site is currently hacked, redirecting to spam, or blacklisted, my WordPress malware removal service handles the cleanup manually, with no data loss, and applies the hardening in this guide afterward. Prefer to hand the whole thing off? You can hire me directly.
Frequently asked questions
Can you really secure WordPress without any plugins?
Yes. The core of WordPress security is reducing your attack surface and hardening configuration, and almost all of that happens in wp-config.php, your server settings, and file permissions, none of which need a plugin. The only gap is real-time virtual patching, where a server WAF or focused plugin still helps.
Should I remove my security plugin if my host already has server-level security?
Often yes, if your managed host runs a server WAF, malware scanning, and brute-force protection, a heavy all-in-one plugin is largely redundant and only adds load. But server-level tools cannot show WordPress login activity or enforce 2FA, so keep an application-level option for those specific needs.
What is the difference between server-level and application-level security?
Server-level security runs below WordPress (web server, PHP, database, OS) and acts on a request before WordPress loads. Application-level security runs inside WordPress as PHP and only sees a request after it loads. Server-level is harder to disable; application-level is better at WordPress-specific rules. Strong sites use both.
Does disabling file editing in wp-config actually stop hackers?
It closes one specific, very common path. Attackers who steal an admin session frequently use the built-in theme and plugin editor to paste a backdoor instantly. Setting DISALLOW_FILE_EDIT removes that one-click option, so they must find another route. It is not a complete defense, but it is a high-value one-line change.
Is changing the WordPress database prefix worth it for security?
Only marginally. Renaming the wp_ prefix can frustrate some automated attacks that assume default table names, but it does not stop a determined attacker and can break your site if done incorrectly. Treat it as optional defense-in-depth, well after permissions, file-edit lockdown, and PHP-execution blocking.
Last updated: June 3, 2026 by MD Pabel, WordPress Security Specialist, 4,500+ sites cleaned.