Secure Your WordPress Site with a Robust .htaccess Configuration

September 3, 2024


Securing your WordPress site is more important than ever in today’s digital landscape. A well-crafted .htaccess file can significantly enhance your site’s security by enforcing HTTPS, protecting against various attacks, and controlling access to sensitive areas of your site. Below, I’m sharing a comprehensive .htaccess configuration that works for me on some of my WordPress sites – Your configuration may need to change to your server’s requirements, but this will at least give you an idea of what can be done.


The goal was to get above B+ on securityheaders.com

Edit .htaccess File:

X-Frame-Options (Clickjacking Protection)

Purpose: Protects against clickjacking by ensuring the site can only be embedded in an iframe by the same origin. Standard: Use the SAMEORIGIN directive for all sites unless you specifically want to allow embedding on other domains.

<IfModule mod_headers.c>
    Header always append X-Frame-Options SAMEORIGIN
</IfModule>

HTTP Strict Transport Security (HSTS)

Purpose: Forces browsers to always connect to your site over HTTPS. Standard: This is a strong security header that can be applied universally. Make sure your site is fully HTTPS-compliant before applying this.

<IfModule mod_headers.c>
    Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</IfModule>

Permissions Policy

Purpose: Restricts which browser features (geolocation, microphone, camera, etc.) are allowed on your site. Standard: This setup denies unnecessary permissions, which is good for security. Adjust if your site requires access to any of these features.

<IfModule mod_headers.c>
    Header always set Permissions-Policy "geolocation=(), microphone=(), camera=(), fullscreen=(self), payment=()"
</IfModule>

XSS Protection and Content-Type Options

Purpose:

  • XSS Protection helps block cross-site scripting attacks.
  • Content-Type Options prevents MIME type sniffing.
  • Referrer Policy controls how much information about the referrer is shared.

Standard: These headers are beneficial for all sites and provide additional protection.

<IfModule mod_headers.c>
    Header set X-XSS-Protection "1; mode=block"
    Header set X-Content-Type-Options "nosniff"
    Header set Referrer-Policy "strict-origin-when-cross-origin"
</IfModule>

Protect Sensitive Files

Purpose: Blocks access to sensitive files like configuration files, logs, and database backups. Standard: Apply this on any WordPress or similar site to protect sensitive files.

<files wp-config.php>
    order allow,deny
    deny from all
</files>

<files .htaccess>
    order allow,deny
    deny from all
</files>

<FilesMatch "\.(htaccess|htpasswd|ini|log|sh|zip|sql|bak)$">
    Order Allow,Deny
    Deny from all
</FilesMatch>

Prevent PHP Execution in Uploads Directory

Purpose: Prevents PHP code from being executed in the uploads directory, which is a common attack vector. Standard: Apply this on any WordPress site to improve security. Adjust the path to fit the site’s directory structure.

<Directory /path/to/wordpress/wp-content/uploads/>
    <FilesMatch "\.php$">
        Order Deny,Allow
        Deny from all
    </FilesMatch>
</Directory>

Site-Specific Sections

(Customisation Needed)

These sections require customisation based on the domain, external resources, and specific site requirements.

Content Security Policy (CSP)

External Domains: You need to customize script-src, style-src, img-src, and form-action for each site based on the domains it uses. For example, if the site integrates third-party services, add those domains. Example Changes: For a new site, replace https://www.zoik.com.au with that site’s domain. Similarly, ensure other external resources like Google Fonts, jQuery, or CDNs are listed.

<IfModule mod_headers.c>
    Header set Content-Security-Policy "
        default-src 'self';
        script-src 'self' 'unsafe-inline' 'unsafe-eval' https://s.w.org https://ajax.googleapis.com https://cdnjs.cloudflare.com https://www.googletagmanager.com;
        style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://cdnjs.cloudflare.com;
        img-src 'self' data: https://secure.gravatar.com;
        font-src 'self' https://fonts.gstatic.com https://cdnjs.cloudflare.com;
connect-src 'self' https://www.zoik.com.au;
        frame-ancestors 'self';
        base-uri 'self';
        form-action 'self' https://www.zoik.com.au;
    "
</IfModule>

Form-Action Directive

Customisation Required: If the site allows form submissions, form-action needs to be adjusted to permit submission to the specific site’s domain and any third-party services (if used) I have added it to the above code.

form-action 'self' https://www.example.com;

Path to Uploads Directory

Customization Required: Adjust the /path/to/wordpress/wp-content/uploads/ directory to the actual uploads directory of each specific WordPress site.

<Directory /path/to/wordpress/wp-content/uploads/>
    <FilesMatch "\.php$">
        Order Deny,Allow
        Deny from all
    </FilesMatch>
</Directory>

General Structure for Other Sites

When adapting this .htaccess for other sites, follow this structure:

  1. Standard Security Headers (Can Be Copied for All Sites):
    • X-Frame-Options
    • HTTP Strict Transport Security (HSTS)
    • Permissions Policy
    • XSS Protection and Content-Type Options
    • Protect Sensitive Files
    • Prevent PHP Execution in Uploads
  2. Customizable Sections:
    • Content Security Policy (adjust external domains, inline script/styles needs)
    • Form-Action (adjust for site’s domain and external services)
    • Directory Paths (adjust for site structure, particularly uploads folder)

Additional Considerations:

  • Testing: After applying the .htaccess changes, always test the site with tools like securityheaders.com and in-browser developer tools to ensure that nothing is inadvertently blocked.
  • Third-Party Resources: Ensure that any third-party scripts, styles, or connections (such as payment gateways or analytics) are properly whitelisted in the CSP.

By following this approach, you can adapt this .htaccess for different sites while maintaining strong security and achieving a high score on tools like securityheaders.com.

I managed to be A+ and A on the security websites securityheaders.com and observatory.mozilla.org

Yah.