WordPress Security Checklist: 25 Things to Do Before You Launch

by | Updated on May 8, 2026

Table of Contents

    Top Website Design Company near me
    ✨ Get AI Summary
    Quick takeaways, insights, and action points

    You’ve built the site. The design looks great, the content is ready, and your client is excited to go live. But before you hit publish — have you actually secured it?

    WordPress powers 43% of all websites globally, making it the most lucrative target for cybercriminals. In 2025 alone, 7,966 new vulnerabilities were discovered in the WordPress ecosystem — a 34% increase from the previous year. Most of those vulnerabilities could have been closed in under an hour with the right checklist.

    This is that checklist.

    We’ve helped hundreds of businesses — law firms, eCommerce stores, real estate agencies — launch and maintain WordPress sites that don’t get hacked. Here are the exact 25 steps we run through every single time, in the order we do them.

    Before We Start: Two Things to Understand

    Security is not a plugin. Installing Wordfence doesn’t mean your site is secure. Security is a configuration discipline. A plugin is a monitoring tool, not a substitute for proper setup.

    Most hacks are automated. Most people think hackers personally target their site. They don’t. Automated bots crawl the web 24/7, scanning for known vulnerabilities. If your site has one, they’ll find it. This means even a brand new site with no traffic is at risk the moment it goes live.

    With that said, here’s the complete checklist.

    Critical — Do These First

    These five items account for the majority of successful WordPress hacks. No other steps matter if these aren’t done first.

    1. Force HTTPS Site-Wide

    If your site is still loading over HTTP — even partially — visitor data is exposed to interception on every page. SSL is also a Google ranking factor sites without it are actively penalised.

    How to do it:

    • Issue a free SSL certificate from your hosting control panel (cPanel → Let’s Encrypt, or Cloudflare’s free plan)
    • In WordPress Admin → Settings → General, change both URL fields from  http://  to  https://
    • Add this redirect to your  .htaccess  file:
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
    • Run a search-replace in your database. With WP-CLI:  wp search-replace ‘http://yourdomain.com’ ‘https://yourdomain.com’ –skip-columns=guid

    Check: Your browser padlock should show “Connection is secure.” No mixed-content warnings.

    2. Change the Default Admin Username

    A 2025 study by Sucuri found that 12% of compromised WordPress sites used the username “admin” with passwords shorter than 8 characters. The “admin” username is the first thing every brute-force tool tries. Remove it.

    How to do it:

    • Create a new Administrator account with a unique, non-obvious username (not your name, not your domain)
    • Log out, log in as the new account
    • Delete the original “admin” account, reassigning its content to your new account
    • Update your display name: Users → Edit → Display Name Publicly As → choose something generic like “NinjaSofts Team”

    3. Use Strong, Unique Passwords + Password Manager

    Every administrator and editor account needs a password that is at least 20 characters, randomly generated, and unique to this site. Reused passwords mean a breach on any other site can unlock your WordPress admin.

    Tools to use: 1Password, Bitwarden (free), or LastPass. Use their password generator — never create passwords manually.

    For extra protection: Install WP 2FA (free plugin) and enable two-factor authentication on all admin accounts. 2FA blocks 99.9% of automated attacks — even with compromised passwords.

    4. Keep WordPress Core, Plugins, and Themes Updated

    According to Patchstack’s 2025 annual report, 97% of WordPress vulnerabilities originated in plugins and themes, not WordPress core. Every outdated plugin is a known, documented attack vector.

    Before launch:

    • Update WordPress core to the latest version
    • Update all installed plugins
    • Update your active theme and any parent theme
    • Delete any plugins or themes you are not using — deactivated plugins still represent attack surface

    Enable auto-updates for minor releases: In  wp-config.php , add:

    define( 'WP_AUTO_UPDATE_CORE', true );

    5. Run Automated Daily Backups to Off-Site Storage

    A backup stored on the same server as your WordPress installation is not a real backup. If the server is compromised, the backup goes with it.

    The correct setup:

    • Plugin: UpdraftPlus (free) or BlogVault
    • Storage: Google Drive, Dropbox, or Amazon S3 — never “same server”
    • Frequency: Daily for active sites, weekly minimum for low-traffic sites
    • Retention: Keep at least 30 days of backup history

    Test a restore before launch. A backup you’ve never restored is a backup you’ve never verified.

    High Priority — Complete Before Going Live

    6. Add All Critical HTTP Security Headers

    Security headers are instructions your server sends to the browser that activate protective policies. Without them, your visitors’ browsers have no guidance on how to handle cross-origin requests, clickjacking attempts, or MIME-type sniffing attacks.

    Add these to your  .htaccess  file inside  <IfModule mod_headers.c> :

    <IfModule mod_headers.c>
      Header always set X-Frame-Options "SAMEORIGIN"
      Header always set X-Content-Type-Options "nosnif
      Header always set Referrer-Policy "strict-origin-when-cross-origin"
      Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
      Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
      Header always set X-XSS-Protection "1; mode=block"
    </IfModule>

    Verify with securityheaders.com — aim for an A or A+ rating.

    7. Disable Directory Listing

    By default, if a directory on your server doesn’t have an index.php file, the web server displays a browsable list of all files in that folder. This means anyone can visit  /wp-content/uploads/  and see every file you’ve ever uploaded.

    Fix — add one line to  .htaccess :

    Options -Indexes

    Also create a blank  index.php  file in  /wp-content/uploads/  and  /wp-content/plugins/  as a secondary measure.

    Test: Visit  https://yourdomain.com/wp-content/uploads/  — it should return a 403 Forbidden error, not a file list.

    8. Protect wp-config.php

    wp-config.php  contains your database credentials, authentication secret keys, and table prefix. If an attacker can read this file directly, they have full control of your database.

    Add to  .htaccess :

    <Files wp-config.php>
      Order Allow,Deny
      Deny from all
    </Files>

    Also move  wp-config.php  one directory above your WordPress root — WordPress natively supports this and the web server won’t serve files above the root.

    9. Remove the WordPress Version Number from Page Source

    Outdated software accounts for 96% of WordPress vulnerabilities. Exposing your version number tells automated scanners exactly which CVEs to try. Remove it.
    Add to  functions.php :

    // Remove version from head and feeds
    remove_action( 'wp_head', 'wp_generator' );
    add_filter( 'the_generator', '__return_empty_string' );
    // Remove version from scripts and stylesheets
    add_filter( 'style_loader_src', function( $src ) {
        return remove_query_arg( 'ver', $src );
    });
    add_filter( 'script_loader_src', function( $src ) {
        return remove_query_arg( 'ver', $src );
    });

    Verify: View source on your homepage and search for “generator” — the tag should be gone.

    10. Disable XML-RPC (Unless You Need It)

    XML-RPC is a legacy WordPress API. Unless you specifically use Jetpack or post from a mobile app, it should be disabled. It allows attackers to attempt hundreds of password combinations per single HTTP request via the multicall method.

    Add to  .htaccess :

    <Files xmlrpc.php>
      Order Allow,Deny
      Deny from all
    </Files>

    If you use Jetpack, disable only multicall by adding to  functions.php :

    add_filter( 'xmlrpc_methods', function( $methods ) {
        unset( $methods['system.multicall'] );
        return $methods;
    });

    11. Restrict Access to wp-login.php

    The WordPress login page is the most attacked URL in any WordPress installation. Bots start hammering it within hours of a site going live.

    Option A — IP restriction:

    <Files wp-login.php>
      Order Deny,Allow
      Deny from all
      Allow from YOUR.STATIC.IP.HERE
    </Files>

    Option B: Install WPS Hide Login (free plugin) and move the login URL to something non-standard like  /team-access/ . Bots will never find it.

    Option C: Add Google reCAPTCHA v3 to the login form using WPForms or Fluent Forms.

    Combine at least two of these approaches.

    12. Block User Enumeration

    Visiting  /?author=1  on an unprotected WordPress site redirects to  /author/USERNAME/ , revealing your admin’s login name. This cuts an attacker’s work in half.

    Add to  functions.php :

    add_action( 'template_redirect', function() {
        if ( is_author() ) {
            wp_redirect( home_url(), 301 );
            exit;
        }
    });

    13. Restrict the REST API User Endpoint

    The WordPress REST API exposes your admin username at  /wp-json/wp/v2/users/1  by default. Restrict it.

    add_filter( 'rest_endpoints', function( $endpoints ) {
        if ( isset( $endpoints['/wp/v2/users'] ) ) {
            unset( $endpoints['/wp/v2/users'] );
        }
        if ( isset( $endpoints['/wp/v2/users/(?P<id>[\\d]+)'] ) ) {
            unset( $endpoints['/wp/v2/users/(?P<id>[\\d]+)'] );
        }
        return $endpoints;
    });

    14. Set Correct File Permissions

    Incorrect file permissions are one of the most common misconfigurations on WordPress sites, especially on shared hosting.

    Correct permissions:

    • Files: 644 (owner can read/write, everyone else can read)
    • Directories: 755 (owner can read/write/execute, everyone else can read/execute)
    • wp-config.php : 400 or 440 (read-only for owner only)

    Set via SSH/Terminal:

    find /path/to/wordpress -type f -exec chmod 644 {} \;
    find /path/to/wordpress -type d -exec chmod 755 {} \;
    chmod 400 /path/to/wordpress/wp-config.php

    Never set files or directories to 777. If a plugin tells you to set 777 permissions, find a different plugin.

    15. Protect the debug.log File

    If you’ve ever had  WP_DEBUG_LOG  enabled, there may be a  debug.log  file in  /wp-content/  that is publicly readable. This file often contains database table names, file paths, and plugin errors.

    Check: Visit  https://yourdomain.com/wp-content/debug.log  — if you see content instead of a 404, this is exposed.

    Fix — add to  .htaccess  in  /wp-content/ :

    <Files "debug.log">
      Order Allow,Deny
      Deny from all
    </Files>

    Then disable debug logging in  wp-config.php :

    define( 'WP_DEBUG', false );
    define( 'WP_DEBUG_LOG', false );

    Medium Priority — Important, Do Within First Week

    16. Change the WordPress Database Table Prefix

    The default WordPress table prefix is  wp_ . Every automated SQL injection script knows this. Changing it removes the lowest-hanging fruit.

    This is easiest to configure during a fresh install. On an existing site, use a plugin like Better WP Security — always take a full database backup first.

    17. Disable PHP Execution in Upload Directories

    Even if an attacker uploads a malicious PHP file to your uploads directory, PHP execution should be blocked so the file can never run.

    Create a  .htaccess  file in  /wp-content/uploads/  containing:

    <Files *.php>
      Deny from all
    </Files>

    18. Set Cookie Security Flags

    WordPress session and authentication cookies should be transmitted securely and protected from JavaScript access. Without these flags, XSS attacks can steal session cookies.

    Add to  wp-config.php :

    @ini_set( 'session.cookie_httponly', 1 );
    @ini_set( 'session.cookie_secure', 1 );
    @ini_set( 'session.cookie_samesite', 'Strict' );

    For Apache, enforce globally via  .htaccess :

    <IfModule mod_headers.c>
      Header always edit Set-Cookie "^(.*)" "$1; HttpOnly; Secure; SameSite=Strict"
    </IfModule>

    19. Limit Login Attempts

    Without login rate limiting, bots can attempt thousands of passwords per hour against your login page. Implement a limit after which an IP is temporarily blocked.

    Without a plugin — add to  functions.php :

    add_filter( 'authenticate', function( $user, $username, $password ) {
        $ip = $_SERVER['REMOTE_ADDR'];
        $key = 'login_attempts_' . md5( $ip );
        $attempts = (int) get_transient( $key );
        if ( $attempts >= 5 ) {
            return new WP_Error( 'too_many_attempts', 'Too many login attempts. Try again in 15 minutes.' );
        }
        if ( is_wp_error( $user ) ) {
            set_transient( $key, $attempts + 1, 15 * MINUTE_IN_SECONDS );
        }
        return $user;
    }, 30, 3 );

    With a plugin: Limit Login Attempts Reloaded (free, 2M+ installs).

    20. Replace Exposed Email Addresses with a Contact Form

    Plain  mailto:  links in your page’s HTML source are harvested by spam bots. Replace them with a contact form.

    Free plugins: WPForms Lite, Contact Form 7, Fluent Forms.

    21. Implement a Web Application Firewall (WAF)

    A WAF sits between your visitors and your server, analysing incoming traffic and blocking malicious requests before they reach WordPress.

    • Cloudflare (free tier): DNS-level WAF. Stops attacks before they reach your server. Easiest to implement.
    • Wordfence (free): Endpoint WAF installed on your server. Excellent for shared hosting.
    • Sucuri (paid): Cloud-based WAF with a strong malware removal guarantee.

    22. Regenerate WordPress Security Keys and Salts

    Security keys and salts encrypt WordPress authentication cookies. Regenerating them invalidates all active sessions — including any attacker sessions that may exist.

    Generate new keys at: api.wordpress.org/secret-key/1.1/salt/

    Replace the corresponding lines in  wp-config.php . Do this before launch and after any suspected compromise.

    Low Risk But Worth Doing

    23. Update Your PHP Version

    If you’re running anything older than PHP 8.2, you’re operating on an expired engine. PHP 7.4 reached its end-of-life on November 28, 2022.

    Check: WordPress Admin → Tools → Site Health → Info → Server.

    Update via your hosting control panel. Most managed hosts (Cloudways, Kinsta, WP Engine) allow PHP version changes with one click.

    24. Remove the Server Version Header

    The HTTP  Server  header often reveals the web server software and version — e.g.,  Apache/2.4.51 . This tells automated scanners which known exploits to try.

    For Apache — add to  .htaccess :

    ServerTokens Prod
    ServerSignature Off

    For Nginx — add to  nginx.conf :

    server_tokens off;

    25. Set Up Security Monitoring and Alerts

    A hardened site still needs to be watched. Enable monitoring so you know immediately if something changes.

    What to monitor:

    • File integrity monitoring (Wordfence or iThemes Security)
    • Failed login attempts
    • New admin user creation
    • Plugin or theme file changes
    • Blacklist/malware status (Sucuri’s free external scanner runs weekly) — visit sitecheck.sucuri.net

    Google Search Console will email you if Google detects malware or deceptive content on your site — make sure it’s set up and your email is current.

    Pre-Launch Security Checklist — Quick Reference

    CRITICAL

    1. SSL forced site-wide, HTTPS confirmed, no mixed content
    2. Admin username changed from “admin” to unique username
    3. Strong passwords + 2FA on all admin accounts
    4. Core, plugins, and themes all updated — unused ones deleted
    5. Daily automated backups to off-site storage, test restore confirmed

    HIGH PRIORITY

    1. HTTP security headers added (X-Frame-Options, HSTS, CSP, etc.)
    2. Directory listing disabled (Options -Indexes)
    3. wp-config.php protected and file permissions set correctly
    4. WordPress version removed from page source
    5. XML-RPC disabled or multicall method blocked
    6. wp-login.php protected (IP restriction, renamed URL, or CAPTCHA)
    7. User enumeration via /?author=1 blocked
    8. REST API user endpoint restricted
    9. debug.log file blocked and debug mode disabled

    MEDIUM PRIORITY

    1. Database table prefix changed from wp_
    2. PHP execution disabled in /wp-content/uploads/
    3. Cookie security flags set (HttpOnly, Secure, SameSite)
    4. Login attempt limiting enabled
    5. Mailto: links replaced with contact forms
    6. Web Application Firewall (WAF) configured
    7. WordPress security keys and salts regenerated

    LOW RISK

    1. PHP version is 8.2 or newer
    2. Server version header suppressed
    3. Security monitoring and alerts configured

    After Launch: Keep It Secure

    Security isn’t a one-time task. It’s a system you maintain. Set a monthly reminder to:

    1. Update all plugins, themes, and WordPress core
    2. Review user accounts and remove any you don’t recognise
    3. Confirm your backup restore works
    4. Review your security plugin’s log for unusual activity

    Check Your Score Before You Launch

    Our free WordPress Security Scanner runs 14 of these checks automatically — SSL, security headers, login page exposure, directory listing, user enumeration, debug log access, REST API exposure, XML-RPC status, cookie security flags, and more — and returns a scored report with step-by-step remediation for every issue it finds.

    Run the free scanner on your site before you go live →

    What to read next