Hi there! How can we help you today?
-
Home
-
Website Security
-
WordPress Security Vulnerabilities: 7 Types & 2026 Hardening Checklist
WordPress Security Vulnerabilities: 7 Types & 2026 Hardening Checklist
Common WordPress security vulnerabilities (XSS, SQLi, CSRF, broken access control), Patchstack 2025 data and a hardening checklist: wp-config, permissions.
Contents
Most hacked WordPress sites are not breached by a "brilliant" attacker. They fall to a known WordPress security vulnerability that already had a patch the owner never installed, or to a default setting nobody tightened. According to Patchstack's State of WordPress Security in 2026 report, 11,334 new vulnerabilities were disclosed in the WordPress ecosystem in 2025 alone, up 42% from 2024.
In this guide, TeamDevDesign explains the most common vulnerability types (XSS, SQL injection, CSRF, broken access control, file uploads, information disclosure, misconfiguration), where they come from, and, most importantly, a detailed WordPress hardening checklist with configuration snippets you can apply today. Everything here is defensive: concepts plus safe vs. unsafe code, no attack instructions.
Table of contents
- What is a WordPress security vulnerability?
- Where vulnerabilities come from: 2024–2025 data
- 7 common vulnerability types and how to prevent them
- How to secure a WordPress site: hardening checklist
- Login security and recovering from a hack
- Summary checklist by frequency
- Frequently asked questions
- Conclusion
What is a WordPress security vulnerability?
A WordPress security vulnerability is a weakness in code, configuration or day-to-day operation that lets someone without permission do things that should be blocked: read data, inject malicious code, create an admin account, or run commands on the server.
A real WordPress site is made of several layers:
- WordPress core – maintained by the WordPress.org community.
- Plugins and themes – written by thousands of different authors, with uneven quality.
- Runtime environment – PHP, the web server (Apache, Nginx, LiteSpeed), the database and the hosting/VPS operating system.
- People – passwords, roles, plugin habits, how backups are stored.
A vulnerability can live in any of these layers, so WordPress security means reducing risk at every layer, not installing one plugin and forgetting about it.
Where WordPress security vulnerabilities come from: 2024–2025 data
Annual reports from two organisations that specialise in WordPress vulnerability research paint a consistent picture:
| Metric | 2024 | 2025 |
|---|---|---|
| New vulnerabilities (Patchstack) | 7,966 | 11,334 |
| Share found in plugins | 96% | 91% |
| Share found in themes | 4% | 9% |
| Vulnerabilities in WordPress core | 7 | 6 (all low priority) |
| No patch available at disclosure | 33% | 46% |
Sources: Patchstack – State of WordPress Security in 2025 (2024 data) and Patchstack – State of WordPress Security in 2026 (2025 data). An independent source, the Wordfence 2024 Annual WordPress Security Report, recorded 8,223 vulnerabilities published in its database in 2024, with the same plugin-heavy trend.
Five practical takeaways:
- Plugins and themes are the main risk. Core has only a handful of vulnerabilities per year and is usually patched through automatic updates. Every extra plugin is one more door to watch. For choosing and managing plugins safely, see our guide to WordPress plugin vulnerabilities.
- The reaction window is tiny. Patchstack reports that about half of high-impact vulnerabilities in 2025 were exploited within 24 hours, and the median time to mass exploitation was roughly 5 hours.
- Not every vulnerability has a fix. 46% had no patch at disclosure in 2025, so you need a WAF, or to remove/replace the plugin.
- Hosting is a layer too. End-of-life PHP, overly broad file permissions and many sites sharing one hosting account let damage spread when one site is breached. PHP-level issues are covered in our article on PHP security vulnerabilities.
- People are the last layer. Reused passwords, Administrator rights handed out freely and "nulled" (pirated) themes are common causes that vulnerability reports cannot measure.
7 common WordPress vulnerability types and how to prevent them
The groups below follow the OWASP Top 10:2025, where Broken Access Control ranks first and Security Misconfiguration second. Code examples use standard WordPress functions.
1. Cross-Site Scripting (XSS)
XSS happens when user input (search boxes, comments, URL parameters) is printed without escaping, so the visitor's browser runs an injected script that can hijack an administrator's session. Patchstack found XSS made up almost half of all new vulnerabilities in 2024.
Unsafe:
<?php echo $_GET['keyword']; ?>
Safer: sanitize on input, escape on output, for the right context.
<?php
$keyword = sanitize_text_field( wp_unslash( $_GET['keyword'] ?? '' ) );
echo esc_html( $keyword ); // inside HTML content
echo '<input value="' . esc_attr( $keyword ) . '">'; // inside an attribute
echo '<img src="' . esc_url( $img_url ) . '">'; // inside a URL
?>
2. SQL Injection
SQL injection happens when user input is concatenated straight into a query, allowing unauthorised reading or modification of data. In WordPress the standard defence is $wpdb->prepare().
Unsafe:
$wpdb->get_results( "SELECT * FROM {$wpdb->prefix}orders WHERE id = " . $_GET['id'] );
Safer:
$id = absint( $_GET['id'] ?? 0 );
$rows = $wpdb->get_results(
$wpdb->prepare( "SELECT * FROM {$wpdb->prefix}orders WHERE id = %d", $id )
);
3. Cross-Site Request Forgery (CSRF)
CSRF tricks a logged-in administrator's browser into sending a request they never intended, such as changing the account email or enabling a dangerous option. WordPress provides nonces to verify that a request came from the site's own form.
// In the form
wp_nonce_field( 'tdd_save_settings', 'tdd_nonce' );
// When processing
if ( ! isset( $_POST['tdd_nonce'] )
|| ! wp_verify_nonce( sanitize_key( $_POST['tdd_nonce'] ), 'tdd_save_settings' ) ) {
wp_die( 'Invalid request.' );
}
4. Broken Access Control
Patchstack names this the most exploited vulnerability class of 2025. A typical bug: an AJAX or REST handler performs a sensitive action but only checks "is logged in" (or nothing at all), so a Subscriber, or even an anonymous visitor, can call admin-only functionality. Note that a CSRF nonce does not replace a capability check.
add_action( 'wp_ajax_tdd_delete_log', function () {
check_ajax_referer( 'tdd_delete_log' );
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( 'Insufficient permissions', 403 );
}
// ... process
} );
register_rest_route( 'tdd/v1', '/export', [
'methods' => 'GET',
'callback' => 'tdd_export',
'permission_callback' => fn() => current_user_can( 'manage_options' ),
] );
A real example: CVE-2024-10924 in the Really Simple Security plugin (versions 9.0.0 to 9.1.1.1) allowed an authentication bypass when the plugin's two-factor feature was enabled. Version 9.1.2 fixed it and was pushed as a forced update. The lesson: even security plugins need regular updates.
5. Unrestricted file upload
An upload form (CVs, avatars, documents) that only checks the extension in the browser can be abused to put a PHP file on the server. If the uploads folder also allows PHP execution, that is a complete backdoor. Defend in two layers: validate on the server, and block PHP execution in uploads (see the checklist below).
$check = wp_check_filetype_and_ext( $tmp_path, $filename, [
'jpg|jpeg' => 'image/jpeg',
'png' => 'image/png',
'pdf' => 'application/pdf',
] );
if ( ! $check['ext'] || ! $check['type'] ) {
wp_die( 'File type not allowed.' );
}
6. Information disclosure and user enumeration
Attackers usually do reconnaissance first: finding usernames through author pages or the /wp-json/wp/v2/users REST endpoint, reading plugin versions from readme.txt, or seeing PHP errors that reveal server paths. Leaked usernames are not critical on their own, but they make password guessing easier. To reduce exposure:
- Set a public display name that differs from the login name.
- Hide errors in production: set
WP_DEBUGandWP_DEBUG_DISPLAYtofalse. - Never leave backup files (
.zip,.sql,wp-config.php.bak) in the web root. - If you do not need a public user list via the REST API, restrict that endpoint to logged-in users.
7. Security misconfiguration
OWASP ranks this second in 2025. On WordPress it usually means 777 permissions, code editing enabled in the dashboard, directory listing turned on, end-of-life PHP, an all-powerful database user, or deactivated plugins that were never deleted. Most of the checklist below targets this group.
How to secure a WordPress site: detailed hardening checklist
WordPress hardening means tightening configuration to shrink the attack surface and limit damage if something goes wrong. This section builds on the official Hardening WordPress documentation plus operational experience. Always back up before changing configuration and test on staging where possible.
1. Update core, plugins, themes and PHP
- WordPress has applied core security releases automatically since version 3.7, and lets you enable auto-updates per plugin/theme since version 5.5. Turn it on for plugins with low conflict risk.
- For critical plugins (WooCommerce, page builders), update manually but on a fixed schedule, at least weekly.
- Delete (not just deactivate) unused plugins and themes. Files of a deactivated plugin still sit on the server and can still be requested directly.
- Run a PHP version that still receives security support; check the php.net Supported Versions page.
- Follow vulnerability alerts for your plugins via WPScan, Wordfence or Patchstack.
2. Lock down wp-config.php
Add these lines to wp-config.php, above /* That's all, stop editing! */:
// Disable the theme/plugin code editor in the dashboard
define( 'DISALLOW_FILE_EDIT', true );
// (Optional) Also block installing/updating plugins and themes from the dashboard
// Only enable if you update via WP-CLI/Git/deployments
// define( 'DISALLOW_FILE_MODS', true );
// Force HTTPS for the admin area
define( 'FORCE_SSL_ADMIN', true );
// Never print PHP errors to the browser in production
define( 'WP_DEBUG', false );
define( 'WP_DEBUG_DISPLAY', false );
Per the WordPress docs, DISALLOW_FILE_EDIT removes the edit_themes, edit_plugins and edit_files capabilities from every user. It does not stop malicious uploads, but it stops a compromised admin account from planting code in a few clicks. Note that DISALLOW_FILE_MODS also disables dashboard updates, so only use it if you have another update workflow.
Protect wp-config.php itself: use 400 or 440 permissions where your host supports it (or 600/640 depending on the PHP user), and on Apache add this to the top of .htaccess:
<Files "wp-config.php">
Require all denied
</Files>
3. Security keys and salts
The eight constants AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY and the four *_SALT values sign login cookies. Make sure they are random and unique per site, generated with the WordPress.org key generator, never the placeholder "put your unique phrase here".
Note: Changing the keys logs every user out, which is exactly what you want after a suspected breach. Do not rotate them mechanically on a schedule, though: some plugins use these keys to encrypt stored data, and new keys can make that data unreadable. Check your plugins before rotating.
4. File permissions: 644 for files, 755 for folders
WordPress recommends 644 for files and 755 for directories, never 777. Run from the site root (adjust the path):
find /path/to/wordpress -type d -exec chmod 755 {} \;
find /path/to/wordpress -type f -exec chmod 644 {} \;
chmod 440 /path/to/wordpress/wp-config.php
Ownership matters as much as permissions: core and plugins should belong to your account user, and only wp-content/uploads needs to be writable by the web server. If you manage your own VPS, see our 16-step Linux VPS security guide.
5. Block PHP execution in the uploads folder
wp-content/uploads should only hold images and documents. Blocking PHP here neutralises most backdoors dropped through upload bugs.
Apache/LiteSpeed – create wp-content/uploads/.htaccess:
<FilesMatch "\.(?i:php[0-9]?|phtml|phar)$">
Require all denied
</FilesMatch>
Nginx – add inside the server block, before the generic \.php$ location:
location ~* ^/wp-content/uploads/.*\.(php[0-9]?|phtml|phar)$ {
deny all;
}
To verify: place a harmless PHP file in uploads and request it; the correct result is a 403 error.
6. Disable XML-RPC if you do not use it
xmlrpc.php serves older mobile apps, pingbacks and some remote publishing tools. If you do not use them, it is just one more target for password-guessing campaigns. Important: according to developer.wordpress.org, the xmlrpc_enabled filter only disables methods that require authentication; it does not disable pingbacks. The thorough way is to block it at the web server:
# Apache (.htaccess in the site root)
<Files "xmlrpc.php">
Require all denied
</Files>
# Nginx
location = /xmlrpc.php { deny all; }
Before blocking, check whether you use the WordPress mobile app, Jetpack or remote publishing tools.
7. HTTPS everywhere
- Install SSL (Let's Encrypt is free on most hosts and on aaPanel) and switch the site address to
https://. - 301-redirect all HTTP traffic to HTTPS at the web server.
- Once stable, consider adding
Strict-Transport-Security(HSTS), plusX-Content-Type-Options: nosniffandX-Frame-Options: SAMEORIGIN.
8. Web application firewall (WAF)
With almost half of 2025's vulnerabilities unpatched at disclosure, a WAF buys you time in that gap. The WordPress docs describe three kinds:
| WAF type | Examples | Pros | Cons |
|---|---|---|---|
| Server level | ModSecurity | Blocks before PHP runs | Needs server access; false positives if rules are not tuned |
| WordPress plugin | Wordfence, Shield, plugins with virtual patching | Understands WordPress context, easy to install | Runs on the same server, uses resources |
| Reverse proxy/DNS | Cloudflare, Sucuri | Filters before traffic reaches the server, doubles as a CDN | Direct access to the origin IP must be blocked |
You do not need all three; one correctly configured WAF is enough for most small sites.
9. Backups with the 3-2-1 rule
- Back up both files and database, automatically and daily for sites with frequent content or orders.
- Keep at least 3 copies, on 2 types of storage, with 1 copy off the server (Google Drive, S3, another machine).
- Keep several restore points (7 days, 4 weeks), because malware can sit dormant for weeks.
- Test a restore at least once a quarter.
10. Least-privilege user roles
- Only 1–2 Administrator accounts. Writers use Author/Editor; report viewers get a dedicated role.
- Do not use the username "admin"; one personal account per person, no shared logins.
- Review users monthly and remove accounts of people who have left or finished their work.
- Database: one database and one user per site. Per the WordPress docs, normal operation only needs SELECT, INSERT, UPDATE and DELETE, but major updates may need ALTER.
11. Monitor logs and file integrity
- Enable an activity log to see who logged in, who installed plugins and who changed settings.
- Review access logs: floods of POST requests to
wp-login.php,xmlrpc.phpor unknown files inuploadsdeserve attention. - Verify core integrity: the WP-CLI command
wp core verify-checksumscompares core files with the originals;wp plugin verify-checksums --alldoes the same for WordPress.org plugins.
Login security and recovering from a hack (summary)
The login page is the most frequently probed target. The minimum: strong, unique passwords, two-factor authentication (2FA) for every account with editing rights or higher, limits on failed login attempts, and optionally restricting wp-admin by IP. Step-by-step instructions are in our guide to WordPress login security.
If your site shows warning signs (strange redirects, Google warnings, unknown admins, spam pages), do not start deleting files at random. The safe sequence: isolate, snapshot the current state, change passwords and keys, clean up or restore a clean backup, then patch the exact vulnerability that was exploited. The full process is in what to do when your WordPress site is hacked.
WordPress hardening checklist by frequency
| Frequency | Tasks |
|---|---|
| Once (at setup) | DISALLOW_FILE_EDIT, FORCE_SSL_ADMIN, debug off; random salts; 644/755 permissions; block PHP in uploads; block xmlrpc.php if unused; HTTPS + 301 redirect; install a WAF; separate database and user |
| Daily | Automatic off-server backups; review alerts from your WAF/security plugin |
| Weekly | Update plugins, themes and core; read vulnerability news for your plugins; skim the activity log |
| Monthly | Review users and roles; delete unused plugins/themes; run verify-checksums; check the PHP version |
| Quarterly | Test a restore from backup; review server configuration and security headers |
If your site runs on a VPS, also read how to optimise a VPS for WordPress to get PHP-FPM, caching and user permissions right from the start.
Frequently asked questions about WordPress security
Is WordPress secure?
WordPress core has a good patching record: Patchstack recorded only 6 core vulnerabilities in 2025, all low priority. Most risk comes from plugins, themes, configuration and admin habits. A WordPress site that is kept updated and properly hardened carries far less risk than a neglected one, even though no system can eliminate risk entirely.
Is a security plugin enough?
No. Security plugins help with WAF rules, malware scanning and login limits, but they do not replace updates, least-privilege roles, backups and server configuration. Security plugins can have vulnerabilities too, as CVE-2024-10924 showed.
How do I know if my WordPress site has vulnerabilities?
Compare your list of plugins, themes and versions against the WPScan, Wordfence or Patchstack databases; many security plugins do this automatically. Only scan sites you own or are authorised to test.
How often should I update plugins?
For security fixes, as soon as possible: Patchstack data shows many vulnerabilities are mass-exploited within hours of disclosure. For regular feature updates, a weekly schedule with a backup beforehand is reasonable.
Conclusion
Most WordPress security vulnerabilities live in plugins and themes, and the time between disclosure and exploitation keeps shrinking. Effective WordPress security therefore combines several layers: regular updates, hardened configuration, a WAF to cover unpatched gaps, least-privilege roles, off-server backups and log monitoring. No measure removes risk completely, but these steps make your site harder to attack and faster to recover.
If you do not have time to keep watch yourself, TeamDevDesign offers ongoing WordPress maintenance and management, including updates, backups and configuration reviews. To discuss your specific site, contact TeamDevDesign.
Share this post:
Contents
Related Posts
Common PHP security vulnerabilities in 2026: SQL injection, XSS, CSRF, file uploads, deserialization...
Plugins caused 91% of new WordPress vulnerabilities in 2025. See 5 real CVEs, the risks of nulled pl...
WordPress site hacked? Spot the signs, isolate the site, scan for malware, verify checksums with WP-...