Boost WordPress Security by Adding Essential Headers through functions.php and .htaccess

Since WordPress is a widely used platform, it is also a target for hackers.

Enhancing the security of your WordPress website is of utmost importance. One effective measure is to add security headers, which can significantly increase your site’s protection against potential security threats, including cross-site scripting (XSS) attacks, cross-site request forgery (CSRF) attacks, and more.

In this tutorial, we’ll guide you through the process of adding security headers to your WordPress site. We provide both PHP snippets to add to your functions.php and .htaccess snippets for each header, giving you the flexibility to choose the method that best suits your needs. However, it’s essential to note that PHP-based security headers might not work seamlessly with caching plugins, such as WP Rocket, which can cache pages without executing PHP code.

Before proceeding with any customizations in WordPress, it’s essential to set up a child theme. A child theme acts as a safe and efficient way to make modifications without affecting the parent theme. If you haven’t set up a child theme yet, follow this tutorial on How to Create a Child Theme for Customization. It will guide you through the process and ensure that your customizations remain intact even after theme updates.

Before you start, you can check the security of your website via: securityheaders.com.

ClickJacking

X-Frame-Options tells the browser whether you want to allow your site to be (i)framed or not. By preventing a browser from framing your site you can defend against attacks like clickjacking. Learn more.

PHP Snippet:

function add_security_header_clickjacking() {
	header( 'X-Frame-Options: SAMEORIGIN' );
}
add_action( 'send_headers', 'add_security_header_clickjacking' );
Code language: PHP (php)

.htaccess Snippet:

Header always append X-Frame-Options SAMEORIGIN
Code language: Apache (apache)

MIME Sniffing

It prevents Google Chrome and Internet Explorer from trying to mime-sniff the content-type of a response away from the one being declared by the server. It reduces exposure to drive-by downloads and the risks of user uploaded content that, with clever naming, could be treated as a different content-type, like an executable. Learn more.

PHP Snippet:

function add_security_header_mimesniff() {
    header( 'X-Content-Type-Options: nosniff' );
}
add_action( 'send_headers', 'add_security_header_mimesniff' );
Code language: PHP (php)

.htaccess Snippet:

Header always append X-Content-Type-Options nosnif
Code language: Apache (apache)

X-Xss-Protection

This header is used to configure the built in reflective XSS protection found in Internet Explorer, Chrome and Safari (Webkit). It tells the browser to block the response if it detects an attack rather than sanitising the script. Learn more.

PHP Snippet:

function add_security_header_xxssprotect() {
    header( 'X-XSS-Protection: 1;mode=block' );
}
add_action( 'send_headers', 'add_security_header_xxssprotect' );
Code language: PHP (php)

.htaccess Snippet:

Header always append X-XSS-Protection "1; mode=block"
Code language: Apache (apache)

Referrer Policy

The browser will not send the referrer header when navigating from HTTPS to HTTP, but will always send the full URL in the referrer header when navigating from HTTP to any origin. It doesn’t matter whether the source and destination are the same site or not, only the scheme. Learn more.

PHP Snippet:

function add_security_header_referrerpolicy() {
	header( 'Referrer-Policy: no-referrer-when-downgrade' );
}
add_action( 'send_headers', 'add_security_header_referrerpolicy' );
Code language: PHP (php)

.htaccess Snippet:

Header always append Referrer-Policy no-referrer-when-downgrade
Code language: Apache (apache)

Content Security Policy (CSP)

This is an added layer of security that helps to detect and mitigate certain types of attacks, including Cross-Site Scripting (XSS) and data injection attacks. These attacks are used for everything from data theft, to site defacement, to malware distribution. Learn more.

PHP Snippet:

function add_security_header_contentpolicy() {
    header( 'Content-Security-Policy: upgrade-insecure-requests;' );
}
add_action( 'send_headers', 'add_security_header_contentpolicy' );
Code language: PHP (php)

.htaccess Snippet:

Header always append Content-Security-Policy "upgrade-insecure-requests"
Code language: Apache (apache)

HTTP Strict Transport Security (HSTS)

This is a policy mechanism that helps to protect the website against man-in-the-middle attacks such as protocol downgrade attacks and cookie hijacking. Learn more.

PHP Snippet:

function add_security_header_hsts() {
	header( 'Strict-Transport-Security: "max-age=31536000" env=HTTPS' );
}
add_action( 'send_headers', 'add_security_header_hsts' );
Code language: PHP (php)

.htaccess Snippet:

Header always set Strict-Transport-Security "max-age=31536000" env=HTTPS
Code language: Apache (apache)

Disable Themes & Plugins Editor

Disable the option to edit themes and plugins code directly from the WordPress admin to prevent potential coding errors or unauthorized access via the WordPress editor.

define( 'DISALLOW_FILE_EDIT', true );
Code language: PHP (php)

Hide WordPress version

Many attackers scan sites for vulnerable WordPress versions. By hiding the version from your site’s HTML, you avoid being marked by hackers for mass attacks. Use the following code snippet in your theme’s functions.php file:

add_filter( 'the_generator', '__return_empty_string' );
Code language: PHP (php)

Pro Tip: Consolidate Security Headers

For a highly efficient and organized approach to adding security headers to your WordPress website, you can consolidate all the security headers into one unified method. This ensures consistency and simplifies your configuration. You have the flexibility to choose between two methods: using a single .htaccess block or a single PHP function.

PHP Snippet:

function hoolite_add_security_headers() {

	header("X-Frame-Options: SAMEORIGIN");

	header("X-Content-Type-Options: nosniff");

	header("X-XSS-Protection: 1;mode=block");

	header("Referrer-Policy: no-referrer-when-downgrade");

	header("Content-Security-Policy: upgrade-insecure-requests;");

	header('Strict-Transport-Security: "max-age=31536000" env=HTTPS');
}

add_action("send_headers", "hoolite_add_security_headers");
Code language: PHP (php)

.htaccess Snippet:

<IfModule mod_headers.c>
    Header always append X-Frame-Options SAMEORIGIN
    Header always append X-Content-Type-Options nosniff
    Header always append X-XSS-Protection "1; mode=block"
    Header always append Referrer-Policy no-referrer-when-downgrade
    Header always append Content-Security-Policy "upgrade-insecure-requests"
    Header always set Strict-Transport-Security "max-age=31536000" env=HTTPS
</IfModule>
Code language: Apache (apache)

After adding your security headers, test your website again via: securityheaders.com.

That’s it! Adding security headers to your WordPress website via both PHP and .htaccess is a quick and effective way to increase its protection against potential security threats. However, always make a backup of the .htaccess file and the functions.php file before making any changes. This ensures that you can revert to the previous configuration if needed.

Leave your feedback and help us improve ๐Ÿถ

We hope you found this article helpful! If you have any questions, feedback, or spot any errors, please let us know in the comments. Your input is valuable and helps us improve. If you liked this article, please consider sharing it with others. And if you really enjoyed it, you can show your support by buying us a cup of coffee โ˜•๏ธ or donating via PayPal ๐Ÿ’ฐ.

More free knowledge, because why not?

3 Comments

  • Hi, thanks for the tips. You could add an important information : It wont work with caching plugins as WpRocket as the php isn’t loaded on cached pages. You’ll have to edit the .htaccess for those.

    Reply
    • Hi Nad, thank you for your valuable input! It’s great to have your insights on this topic. It’s true that when working with caching plugins like WP Rocket, there can be some considerations to keep in mind. However, the good news is that there are ways to address these challenges and ensure both performance and security.

      As mentioned, caching plugins aim to optimize website performance by serving cached content. While PHP-based security headers might not be applied directly to cached pages, there are solutions available. Some caching plugins, including WP Rocket, offer settings designed to handle security headers. For instance, the “Add HTTP Strict Transport Security (HSTS)” option in WP Rocket allows you to add an HSTS header even with caching enabled.

      Additionally, manual configuration and testing play pivotal roles. You can configure your caching plugin to work seamlessly with added security headers by excluding specific pages or URLs from caching. And after implementing these headers, thorough testing ensures they work as intended, even when caching is active. Tools like securityheaders.com or browser developer tools can help verify that your security headers are present and effective.

      In conclusion, while challenges can arise when using security headers with caching plugins, there are solutions available, and it’s all about finding the right balance between performance and security. Thanks again for your contribution to the discussion โ€“ it’s much appreciated!

      Reply
    • Hi Nad,

      I wanted to let you know that we’ve updated the tutorial. In response to your feedback, we’ve added .htaccess snippets for each of the security headers. Additionally, we’ve consolidated the PHP and .htaccess configurations into a single “Pro Tip” section, making it even easier to implement these crucial security measures.

      Now, you have the flexibility to choose between PHP or .htaccess, or even use both methods for maximum security. Thanks for your valuable input, and we hope you find these updates helpful in enhancing your WordPress website’s security.

      Feel free to check out the tutorial again to explore the changes. If you have any more questions or suggestions, please don’t hesitate to reach out!

      Reply

Your thoughts matter, leave a reply ๐Ÿ’ฌ

Your email address will not be published. Required fields are marked *