WordPress Hardening Rules Generator

.htaccess or Nginx hardening rules, plus a Content-Security-Policy header pre-filled for Stripe, PayPal and Google Pay.

Describe the result you need. AI will set up the tool and ask for any missing details.

Configure with AI

Enter to submit · Shift + Enter for a new line

Sent to AI. Leave out passwords and private customer data.

Your details

Turn this off if you use Jetpack, the WordPress mobile app, or another tool that relies on XML-RPC; otherwise it's a common, low-risk block against pingback-based brute force.

Hardening rules

htaccess-hardening.txt
# Add near the top of .htaccess, above the "# BEGIN WordPress" block.

Options -Indexes

<Files wp-config.php>
    Require all denied
</Files>

<Files .htaccess>
    Require all denied
</Files>

<Directory "wp-content/uploads">
    <FilesMatch "\.php$">
        Require all denied
    </FilesMatch>
</Directory>

<IfModule mod_headers.c>
    Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://js.stripe.com https://*.js.stripe.com https://www.paypal.com https://www.paypalobjects.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; frame-src 'self' https://js.stripe.com https://*.js.stripe.com https://hooks.stripe.com https://www.paypal.com; connect-src 'self' https://api.stripe.com https://www.paypal.com;"
</IfModule>

Turn this on, then click through your whole checkout with the browser console open. A missing domain shows up immediately as a blocked-by-CSP error, which is far safer than guessing every script your theme and apps load.

What each rule does

  • Directory browsing off: stops anyone from seeing a raw file listing of a folder with no index file.
  • wp-config.php and .htaccess denied: blocks direct requests to the two files most worth protecting outright.
  • No PHP execution in /wp-content/uploads/: a classic malware-upload technique relies on getting a PHP file into uploads and requesting it directly; this closes that off even if a vulnerable plugin lets a file through.
  • Content-Security-Policy: tells the browser exactly which domains are allowed to run scripts or open frames on your pages, checked against Stripe's own documented CSP directives (script-src and frame-src need js.stripe.com and *.js.stripe.com, frame-src also needs hooks.stripe.com, connect-src needs api.stripe.com). PayPal's and Google Pay's domains are this tool's own defaults: confirm them against your provider's current integration docs before relying on them.

Adding the rules

  1. 01

    Apache: paste above "# BEGIN WordPress"

    In .htaccess, so WordPress's own rewrite rules don't intercept the request first.

  2. 02

    Nginx: paste inside your server block, then test

    sudo nginx -t, then sudo systemctl reload nginx.

  3. 03

    Turn on the CSP last, and test checkout

    With your browser's console open. A blocked script or frame shows up immediately as a CSP violation, which is a far safer way to find a missing domain than guessing.

Pitfalls

  • "Allow inline scripts/styles" is on by default because most WordPress themes and page builders rely on inline <script> and <style> tags; turning it off without nonce-ing every inline block will likely break your theme's own styling and any small inline script it adds.
  • Test every payment method on checkout after turning on the CSP: a payment provider not in the list will silently fail to load rather than showing an obvious error.
  • Blocking xmlrpc.php breaks Jetpack, the WordPress mobile app, and any tool that pings or posts to it; leave that toggle off if you use any of those.

Questions people ask

Will this break my page builder or theme?

Directory browsing, wp-config protection and the uploads PHP block are all safe for any theme. The Content-Security-Policy is the one to test carefully, since it can block a script or embed your theme relies on if a domain is missing.

Do I need this if I already use a security plugin?

Security plugins like Wordfence add their own protections, but server-level rules like these run before WordPress even loads, which is faster and can't be bypassed by a compromised plugin.

Why isn't blocking XML-RPC on by default?

Because it breaks Jetpack, the WordPress mobile app, and pingbacks/trackbacks for any store that uses them. It's a safe block only if you don't rely on any of those.

What if my payment provider isn't Stripe, PayPal or Google Pay?

Add its documented CSP domains to script-src, frame-src and connect-src by hand in the generated rule; check your provider's own integration docs for the exact list.

Want this builtinto your store?

I'm Emmanuel, a Shopify and WooCommerce developer. If this tool pointed at something you'd rather have fixed for you (a faster store, cleaner product data, a migration, a custom feature), send me a note.

Emmanuel Asika

Emmanuel Asika

Shopify & WooCommerce developer, Dublin

I build and fix online stores: new builds, migrations, speed, SEO and the custom bits apps can't do.

hello@emmanuelasika.com