Website Security Checklist: 15 Steps That Keep Hackers Out (Part 13 of 20)

Closed padlock representing website security and protection from hackers

WordPress powers over 43% of the web – which makes it the world’s most targeted CMS by a wide margin. Automated bots scan the internet continuously, probing for outdated plugins, weak passwords, exposed admin panels, and known vulnerabilities. A WordPress site with no active security measures will be attacked within hours of going live. Most successful attacks are not sophisticated – they are opportunistic, targeting the same handful of entry points that remain unguarded on thousands of sites.

This checklist covers every layer of defense: firewall, security plugins, authentication hardening, file security, server configuration, and ongoing monitoring. Work through it top to bottom and your site will be significantly harder to compromise than the vast majority of WordPress installations.


Understanding WordPress Attack Vectors

Before configuring defenses, it helps to understand what attackers actually do. Most WordPress attacks fall into a handful of categories:

  • Brute force login attacks – Automated scripts trying thousands of username/password combinations against wp-login.php. The most common attack type.
  • Plugin and theme vulnerabilities – Outdated plugins with known CVEs (Common Vulnerabilities and Exposures) are the most common successful attack vector. SQL injection, cross-site scripting (XSS), and file upload vulnerabilities in plugins account for over 90% of WordPress compromises.
  • Credential stuffing – Using leaked username/password combinations from other data breaches to log in to WordPress. Works when users reuse passwords.
  • XML-RPC exploitation – WordPress’s XML-RPC endpoint enables brute force attacks that bypass standard login protection. Should be disabled on most sites.
  • Malicious file uploads – Uploading PHP files disguised as images to gain code execution on the server.
  • SQL injection – Inserting malicious SQL into database queries via forms, URL parameters, or search boxes.
  • Cross-site scripting (XSS) – Injecting JavaScript into page content that executes in visitors’ browsers.

Step 1: Web Application Firewall (WAF)

A Web Application Firewall sits between the internet and your website, filtering incoming traffic and blocking known attack patterns before they reach your server. A WAF is your first line of defense and should be the first thing you configure.

WAFTypePriceProsCons
Cloudflare Free WAFDNS-levelFreeNo server load, DDoS protection, global networkBasic rule set on free plan
Cloudflare Pro WAFDNS-level$20/moOWASP core rule set, custom rules, bot managementMonthly cost
Sucuri WAFDNS-levelFrom $199/yrMalware removal included, WordPress-specific rulesCost, adds latency if misconfigured
Wordfence (plugin)EndpointFree/$119/yrSees decrypted traffic, WordPress-specificServer-side load, real-time rules require paid
AWS WAFDNS-level$5/mo + usageAWS-native, highly customizable, scalableComplex configuration, no pre-built WP rules

Cloudflare Free WAF is the right starting point for most sites. Enable it, configure the security level (Medium is appropriate for most sites), and turn on Bot Fight Mode to block automated scanners. For sites that have been previously compromised or receive significant attack traffic, Sucuri WAF’s malware removal guarantee makes it worth the annual cost.

DNS-level WAFs (Cloudflare, Sucuri) filter traffic before it reaches your server. Endpoint WAFs (Wordfence plugin) filter traffic after it arrives but before WordPress processes it. Both work; DNS-level is preferred because malicious traffic never reaches your server at all.


Step 2: Security Plugin Selection

PluginFree VersionPaid PlanReal-time Malware ScanWAF2FALogin Protection
WordfenceYes (7-day delayed rules)$119/yrPaid only (real-time)Yes (endpoint)YesYes (limit attempts, block IPs)
Solid Security (iThemes)Yes$99/yrMalware scan (3rd party)NoYesYes
MalCareLimited$149/yrYes (cloud-based, no server load)Yes (basic)NoYes
All-In-One Security (AIOS)Yes (comprehensive)$70/yrYes (free)Yes (free)YesYes (comprehensive free)

Wordfence is the most widely used security plugin with the most comprehensive threat intelligence database. The free version is solid but has a 7-day delay on new firewall rules – attacks exploiting new vulnerabilities hit your site for a week before protection arrives. The paid version gets real-time rules.

MalCare’s cloud-based scanning is notable because it does not consume your server’s resources for scanning – the scan happens externally by analyzing file signatures. On shared hosting where server resources are constrained, this is a meaningful advantage.

All-In-One Security (AIOS) offers the most complete free tier. If you are running multiple sites on a tight budget, AIOS covers the critical bases without cost.


Step 3: Two-Factor Authentication Setup

Two-factor authentication (2FA) adds a second verification step to login: something you know (password) plus something you have (a code from your phone). Even if an attacker has your correct username and password (from a data breach or guessing), they cannot log in without the second factor.

Setting Up 2FA with Google Authenticator or Authy

  1. Install a 2FA plugin: WP 2FA (free), Wordfence (included), or Two Factor Authentication by miniOrange.
  2. In the plugin settings, enable TOTP (Time-based One-Time Password) as the 2FA method.
  3. On your phone, install Google Authenticator, Authy, or Microsoft Authenticator.
  4. Scan the QR code shown in the WordPress plugin setup with your authenticator app.
  5. Enter the 6-digit code from your app to confirm setup.
  6. Save your backup codes in a secure location (password manager).
  7. Force 2FA for all administrator and editor roles in the plugin settings.

Authy has advantages over Google Authenticator: it backs up your codes to the cloud (so you do not lose access if you lose your phone) and syncs across multiple devices. Google Authenticator is more privacy-conscious but offers no backup. Either works well for WordPress 2FA.


Step 4: Login Page Protection

Limit Login Attempts

By default, WordPress allows unlimited login attempts. A brute force script can try 10,000 password combinations per minute. Limit Login Attempts Reloaded (free plugin) blocks an IP after a configurable number of failed attempts (3-5 is standard) and prevents further attempts for a lockout period (typically 20 minutes). After multiple lockouts from the same IP, extend the ban to 24 hours or permanently block.

Rename wp-login.php

WPS Hide Login (free plugin) changes the login URL from the standard /wp-login.php to any custom path you choose. Automated attacks target /wp-login.php – if the file is not at that path, bot attacks return 404 errors without ever reaching your login form. This is security through obscurity (not a strong defense alone) but eliminates the vast majority of automated brute force traffic against your server.

reCAPTCHA v3

Google’s reCAPTCHA v3 runs silently in the background, analyzing visitor behavior and assigning a risk score. Unlike v2 (the “I am not a robot” checkbox), v3 requires no user interaction. Suspicious requests (automated bots) get low scores and are blocked. Add reCAPTCHA v3 to your login page, registration form, and contact forms. WP Rocket, Gravity Forms, and most security plugins support direct reCAPTCHA v3 integration.


Step 5: File Integrity Monitoring

File integrity monitoring (FIM) takes a snapshot of all your WordPress files (core, plugins, themes) and alerts you when files are added, modified, or deleted unexpectedly. If a hacker modifies a plugin file to add a backdoor, FIM detects the change. If malicious code is injected into your theme’s functions.php, FIM alerts you immediately.

Wordfence includes file integrity monitoring in both free and paid versions. It compares your WordPress core files against the official checksums from WordPress.org. Any modification to core files triggers an alert. For plugin and theme files, Wordfence also maintains checksums for plugins from the WordPress.org directory.

WP Cerber Security offers more granular FIM with scheduled scans and email/SMS alerts. iThemes Security Pro (Solid Security) includes FIM with weekly scans in the paid version.


Step 6: Malware Scanning Automation

Schedule automated malware scans to run daily. If malware is injected into your site, you want to know within hours, not weeks. Wordfence scans run daily on the free version (with 7-day delayed definitions) and more frequently on paid plans. MalCare’s cloud scanning does not impact site performance and can be scheduled hourly on paid plans.

What malware scans look for: PHP code injection in plugin/theme files, base64-encoded payloads (commonly used to obfuscate malicious code), known malware signatures, suspicious file timestamps, backdoor functions (eval, base64_decode, system, exec in unexpected places), spam link injection in post content.


Step 7: Security Headers

HTTP security headers are instructions sent from your server to the browser that control how the browser handles your site’s content. They protect against XSS attacks, clickjacking, and data injection. Most are simple one-line additions to your server configuration or .htaccess file.

HeaderPurposeRecommended Value
Content-Security-Policy (CSP)Controls which sources the browser loads resources from. Prevents XSS.Start with report-only mode, then enforce
X-Frame-OptionsPrevents your site from being embedded in iframes on other sites (clickjacking)SAMEORIGIN
X-Content-Type-OptionsPrevents browsers from MIME-sniffing files (serving .jpg as executable)nosniff
Permissions-PolicyControls which browser features (camera, microphone, geolocation) your pages can usegeolocation=(), microphone=(), camera=()
Referrer-PolicyControls how much referrer information is sent when visitors click outbound linksstrict-origin-when-cross-origin
Strict-Transport-Security (HSTS)Forces HTTPS for all future connections once setmax-age=31536000; includeSubDomains

The Solid Security plugin and AIOS can add these headers via their settings panels without touching server configuration files. Alternatively, add them to your .htaccess or Nginx config. Verify your headers at securityheaders.com after implementation.


Step 8: wp-config.php Hardening

The wp-config.php file contains your database credentials and controls key WordPress security settings. These constants should be set:

  • DISALLOW_FILE_EDIT – Set to true. Disables the built-in WordPress theme and plugin file editor. An attacker who gains admin access cannot use this editor to inject code. define(‘DISALLOW_FILE_EDIT’, true);
  • DISALLOW_FILE_MODS – Set to true to also prevent plugin/theme installation and updates via the dashboard. Use this if you deploy code via Git and never want WordPress touching files. Note: this prevents applying security updates via the dashboard too.
  • Security Keys and Salts – These are used to encrypt session tokens. Generate fresh ones at the WordPress Secret Key Generator and update them every 6-12 months. Updating them logs out all currently logged-in users (a useful response to suspected session hijacking).
  • FORCE_SSL_ADMIN – Set to true to force HTTPS for all admin area requests. define(‘FORCE_SSL_ADMIN’, true);

Move wp-config.php one directory above your WordPress root if your server configuration allows it. WordPress looks for it one level up automatically. This keeps it out of the web-accessible public directory.


Step 9: File Permissions

Correct file permissions prevent web-accessible scripts from writing to files they should not touch. The WordPress recommended permissions:

  • wp-config.php – 600 (owner read/write only, no group/world access)
  • Directories – 755 (owner read/write/execute, group and world read/execute)
  • Files – 644 (owner read/write, group and world read only)
  • wp-content/uploads/ – 755 (must be writable by web server for media uploads)

Do not set any PHP files to 777 (world-writable). This allows any user on the shared server to write to those files. On shared hosting, other users’ compromised sites can leverage 777 files on your site. If an installer requires 777 permissions, change them back to 644 or 755 immediately after installation completes.


Step 10: Database Prefix and XML-RPC

Change the Database Prefix

WordPress uses wp_ as the default database table prefix. SQL injection attacks often target specific table names – knowing your prefix makes injection attacks easier to craft. Change the prefix to something random like wp_a7k3x_. On new installations, set this in wp-config.php before running the installer. On existing sites, use a plugin like iThemes Security or Solid Security to change it (which handles updating all references). This is a defensive measure that reduces the effectiveness of automated SQL injection attacks.

Disable XML-RPC

XML-RPC is a legacy API that allowed remote publishing tools (like the old desktop WordPress apps) to communicate with your site. Most modern sites do not use it, but it remains enabled by default. Attackers use it to execute brute force attacks with amplification – a single XML-RPC request can bundle hundreds of login attempts, bypassing rate limiting. Disable it by adding this to your .htaccess:

Block requests to xmlrpc.php in your web server configuration or via the Wordfence/AIOS plugin settings. Note: Jetpack requires XML-RPC. If you use Jetpack, you cannot fully disable it, but you can limit it to specific IP addresses or use Jetpack’s own security features instead.


Step 11: REST API Security

WordPress’s REST API exposes site data (posts, users, comments) at /wp-json/. By default, the users endpoint lists all WordPress usernames at /wp-json/wp/v2/users – giving attackers valid usernames for brute force attacks. Restrict the users endpoint to authenticated requests only by filtering rest_endpoints or adding a security plugin rule.

You do not need to disable the REST API entirely – many plugins (Gutenberg, WooCommerce, WPForms) depend on it. The goal is limiting what unauthenticated requests can access. Disable endpoints you do not use and restrict user enumeration via the REST API.


Step 12: User Role Audit

Review all WordPress users quarterly. Ask: Does each user still work with the organization? Does each user have the minimum role needed for their tasks? Are there any administrator accounts that should not have that level of access?

WordPress roles from most to least privileged: Administrator, Editor, Author, Contributor, Subscriber. Assign the minimum role required. A content creator who only writes posts does not need Editor access (which includes the ability to publish others’ posts). Reduce the attack surface by minimizing the number of accounts with high-privilege roles.

For community sites with member registration (BuddyPress, WooCommerce), monitor for suspicious registrations – accounts with names that look automated, email addresses from disposable email services, or accounts that immediately try to post links. The BuddyPress Moderation Pro plugin adds automated content moderation and spam detection for community platforms, reducing the manual overhead of user management.


Step 13: Vulnerability Monitoring

Plugin vulnerabilities are the most common successful attack vector. A plugin you installed two years ago may have a critical CVE that was published last month. Staying informed about vulnerabilities in your installed plugins is essential.

  • Patchstack – Free tier provides vulnerability alerts for plugins in your WordPress site. Paid plans add a virtual patching feature that blocks exploit attempts for known vulnerabilities before you have updated the plugin.
  • WPScan – Command-line vulnerability scanner that checks your plugins, themes, and WordPress version against a database of known vulnerabilities. The API offers 25 free requests per day. Integrate into your deployment pipeline or run monthly.
  • WP Vanguard – Security scanner for WordPress with a 38,000+ CVE database. Identifies vulnerable plugins and themes, generates a security report with severity scores, and provides remediation guidance. Useful for auditing sites before and after major updates.
  • Wordfence paid – Real-time vulnerability alerts for installed plugins, direct from Wordfence’s threat intelligence team.

Step 14: Incident Response Basics

If your site is compromised, having a response plan reduces the time you spend in panic mode. The basic steps:

  1. Take the site offline – Activate maintenance mode or block public access to prevent the attack from spreading or harming visitors.
  2. Change all passwords immediately – WordPress admin, FTP, hosting control panel, database. Force logout all users by updating security keys in wp-config.php.
  3. Restore from a clean backup – If you have a recent clean backup (from before the compromise), restore it. This is faster than manual cleanup and more reliable.
  4. If no clean backup: scan and clean – Run Wordfence or MalCare scan, remove all flagged files, reinstall WordPress core and all plugins fresh from WordPress.org.
  5. Identify entry point – Check server logs for the original attack request. What plugin was exploited? What IP did it come from? Update or remove the vulnerable component.
  6. Harden before going back online – Apply the steps in this checklist before restoring public access.

Step 15: The Penetration Testing Schedule

Monthly automated scans (WPScan, Wordfence), quarterly manual audits (user role review, plugin audit, security header check), and annual penetration tests for sites handling payment or sensitive data. A penetration test goes beyond automated scanning – a human tester tries to actively exploit your site’s defenses using the same techniques real attackers use.

For most small to medium business sites, monthly automated scans plus the hardening steps in this checklist is sufficient. For e-commerce sites, member platforms handling personal data, or sites storing any sensitive user information, an annual professional penetration test is worth the investment (typically $500-5,000 depending on scope).


Community Site Security with BuddyPress

Community sites face additional security concerns beyond standard WordPress hardening. Open registration, user-generated content, private messages, and group activity all create attack surfaces that do not exist on simple blogs.

BuddyPress Moderation Pro adds automated moderation tools specifically designed for BuddyPress communities: spam detection for activity posts and messages, keyword filtering, automated suspension of accounts that trigger spam signals, and tools for moderators to review and act on reported content efficiently. For any community site where the volume of user activity exceeds what you can manually review, automated moderation is essential security infrastructure.


Quick Reference Security Checklist

  • WAF configured (Cloudflare free minimum)
  • Security plugin installed and active (Wordfence, MalCare, or AIOS)
  • 2FA enabled for all admin accounts
  • Login URL changed from default wp-login.php
  • Login attempts limited (3-5 attempts before lockout)
  • Malware scanning scheduled (daily)
  • Security headers configured (check at securityheaders.com)
  • DISALLOW_FILE_EDIT set to true in wp-config.php
  • Security keys and salts rotated in the last 12 months
  • File permissions correct (644 files, 755 dirs, 600 wp-config.php)
  • XML-RPC disabled (unless required by Jetpack)
  • User enumeration blocked via REST API and XML-RPC
  • User roles reviewed in the last 90 days
  • All plugins updated within the last 7 days
  • Vulnerability monitoring active (Patchstack or WPScan)

Series Navigation

This post is part of the Website Owner’s Toolkit – a 21-part series covering everything you need to run a successful website.

Facebook
Twitter
LinkedIn
Pinterest