Skip to content

Instantly share code, notes, and snippets.

@JamborJan
Last active July 22, 2019 07:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JamborJan/35171e8a7474e35e2550a78d80bef285 to your computer and use it in GitHub Desktop.
Save JamborJan/35171e8a7474e35e2550a78d80bef285 to your computer and use it in GitHub Desktop.
Template .htaccess file with security fixes & enhancements for hosted WordPress pages
# # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Content: .htaccess file with security settings
# Author: Jan Jambor, XWare GmbH
# Author URI: https://xwr.ch
# Date: 20.07.2019
#
# # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # #
# Wordpress rewrites
# # # # # # # # # # # # # # # # # # # # # # # # # #
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# # # # # # # # # # # # # # # # # # # # # # # # # #
# Gzip compression
# # # # # # # # # # # # # # # # # # # # # # # # # #
SetOutputFilter DEFLATE
AddOutputFilterByType DEFLATE text/html text/css text/plain text/xml application/x-javascript application/x-httpd-php
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip
# # # # # # # # # # # # # # # # # # # # # # # # # #
# do not show the server version and X-Powered-By
# # # # # # # # # # # # # # # # # # # # # # # # # #
#ServerTokens Prod
ServerSignature Off
Header always unset "X-Powered-By"
Header unset "X-Powered-By"
# # # # # # # # # # # # # # # # # # # # # # # # # #
# security stuff
# # # # # # # # # # # # # # # # # # # # # # # # # #
<IfModule mod_headers.c>
# HSTS prevents attackers from tricking you into connecting via HTTP in the
# future, but if you actually intend to access the server via non-SSL in the
# future then you should probably delete this line.
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" env=HTTPS
# you can tell the browser that it can only download content from the domains you explicitly allow
# for examples see e.g. https://scotthelme.co.uk/content-security-policy-an-introduction/
Header set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; img-src 'self' data: https:; style-src 'self' 'unsafe-inline' https:; font-src 'self' data: https:; frame-src 'self' https:; connect-src 'self' https: wss:; object-src 'self' "
# X-Frame-Options tells the browser whether you want to allow your site to be framed or not.
# By preventing a browser from framing your site you can defend against attacks like clickjacking.
# Recommended value: add_header X-Frame-Options "SAMEORIGIN";.
Header always set X-Frame-Options "SAMEORIGIN"
# X-XSS-Protection sets the configuration for the cross-site scripting filter built into most browsers.
# Recommended value "X-XSS-Protection: 1; mode=block".
Header always set X-Xss-Protection "1; mode=block"
# X-Content-Type-Options stops a browser from trying to MIME-sniff the content type and forces it
# to stick with the declared content-type. This helps to reduce the danger of drive-by downloads.
# Recommended value "X-Content-Type-Options: nosniff".
Header always set X-Content-Type-Options "nosniff"
# Referrer-Policy
# Details see https://scotthelme.co.uk/a-new-security-header-referrer-policy/
Header always set Referrer-Policy "no-referrer"
# Feature Policy
# is a new header that allows a site to control which features and APIs can be used in the browser.
# Details see https://scotthelme.co.uk/a-new-security-header-feature-policy/
Header always set Feature-Policy "microphone 'none'; payment 'none'; sync-xhr 'self';"
</IfModule>
# # # # # # # # # # # # # # # # # # # # # # # # # #
# caching static content
# # # # # # # # # # # # # # # # # # # # # # # # # #
FileETag MTime Size
<IfModule mod_expires.c>
# Enable expirations.
ExpiresActive On
# Cache all files for 2 weeks after access (A).
ExpiresDefault A1209600
<FilesMatch \.php$>
# Do not allow PHP scripts to be cached unless they explicitly send cache
# headers themselves. Otherwise all scripts would have to overwrite the
# headers set by mod_expires if they want another caching behavior.
ExpiresActive Off
</FilesMatch>
</IfModule>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment