Skip to main content
Website Speed & Security

How Do I Improve My WebPageTest Security Score?

This article and the links inside will help you improve your WordPress website security by modifying the .htaccess file on your website.

Note: The suggestions and advice in this article should only be used by developers or blog owners who are comfortable making updates to their .htaccess file. Always make a copy of your .htaccess file before attempting any changes. That way you can quickly roll back to a working version if you notice any issues with your website.

We suggest that you look at more than just this article before you begin making adjustments to your .htaccess file. Of course we’re available to help if you don’t want to go it alone in addressing your basic WordPress security issues. Although we’re not deep security experts we can solve basic issues like updating your .htaccess file with security directives.

I began improving the security headers for this website when a client of mine had to pass PCI testing for their website. I worked with their contractor to improve the security of their WordPress website by making updates to their .htaccess file. Although the updates were a bit different than what I implemented on this website, it got me started on improving more than just the basics of website security.

The security score from WebPageTest is rather new. They started using it in early May 2020. Here’s a recent test score from that shows our A+ score. Prior to implementing the changes to our .htaccess file we received a score of “F”. The rest of this article shows what we did to obtain it.

graphic of security score from web page test

Here are the .htaccess directives we’re using to get an A+ rating on the security scan:

Header always set Strict-Transport-Security “max-age=31536000; includeSubDomains; preload” env=HTTPS
Header always append X-Frame-Options SAMEORIGIN ( or use DENY for total block. DENY will cause issues with adjustment of entry details in Gravity Forms as it presents an iframe to adjust )
Header always set X-XSS-Protection: 0
Header set X-Content-Type-Options nosniff
Header set Content-Security-Policy “script-src ‘unsafe-inline’ ‘unsafe-eval’ http: https:”

What the .htaccess security directives mean

Here’s a rundown of what each .htaccess rule is doing, and how it affects WordPress website security.

Header always set Strict-Transport-Security “max-age=31536000; includeSubDomains; preload” env=HTTPS

Specifying HTTP Strict Transport Security (HSTS) in website response headers lets web browser clients know that your website only accepts HTTPS requests. It can help prevent “man in the middle” attacks. For instance if a visitor to your website bookmarks or manually types they could be subject to a man in the middle attack, without this directive in place.

The max-age=31536000 part of the directive tells the directive to last for 1 year, which is 31536000 seconds. It has “includeSubdomains” because all present and future subdomains will be HTTPS.

Header always append X-Frame-Options SAMEORIGIN or DENY

The SAMEORIGIN value allows Gravity Forms, and perhaps other WP Administration interfaces, to add the date to form entry listings – without SAMEORIGIN this functionality won’t work. It also allows you to frame your own web pages on parts of your site, which would be pretty uncommon.

The DENY value for the X-Frame-Options header prevents any domain from framing your website content. This is useful so someone doesn’t hijack your website content or try to impersonate your website.

Header always set X-XSS-Protection: 0

According to MDN Web Docs, the X-XSS-Protection header has been deprecated and its use can introduce additional security issues on the client side. It is recommended to set the header as X-XSS-Protection: 0 in order to disable the XSS Auditor, and not allow it to take the default behavior of the browser handling the response.”

Prior to understanding this, I had our website set to: Header always set X-XSS-Protection “1; mode=block”. Note that the WebPageTest tool still recommends the setting: X-XSS-Protection: 1. This is in spite of up security experts suggesting it be set to 0. It goes to show that these testing tools shouldn’t always be trusted without further diving into the metrics. At some point they’ll most likely update their testing to reflect the most current standards.

Header set X-Content-Type-Options nosniff

This .htaccess directive specifies that the MIME types in the Content-Type headers should not be changed, and must be followed. MIME sniffing can create security issues for website owners as well as website visitors. An attacker can leverage MIME sniffing to send an XSS (Cross Site Scripting) attack. XSS attacks are when malicious scripts are injected into trusted websites for the purpose of running the malicious script on your the website visitors device. In other workds, the script uses your website to send malicious code to your website visitors mobile phone, laptop, or desktop computer.

Header set Content-Security-Policy “script-src ‘unsafe-inline’ ‘unsafe-eval’ http: https:”

This directive specifies valid sources for JavaScript. The ‘unsafe-inline’ means that the website allows the use of inline resources, such as inline script elements, javascript: URLs, and inline event handlers. The ‘unsafe-eval’ means that the website allows the use of eval() and similar methods for creating code from strings.

Direct links to MDN Web Docs for each directive

A big thanks to the OWASP Cheat Sheet Series and Templarbit for information about the .htaccess directives mentioned above.