# Apache Server Configs v4.0.0 | MIT License
# https://github.com/h5bp/server-configs-apache
# (!) Using `.htaccess` files slows down Apache, therefore, if you have
# access to the main server configuration file (which is usually called
# `httpd.conf`), you should add this logic there.
#
# https://httpd.apache.org/docs/current/howto/htaccess.html
# ######################################################################
# # CROSS-ORIGIN #
# ######################################################################
# ----------------------------------------------------------------------
# | Cross-origin requests |
# ----------------------------------------------------------------------
# Allow cross-origin requests.
#
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
# https://enable-cors.org/
# https://www.w3.org/TR/cors/
# (!) Do not use this without understanding the consequences.
# This will permit access from any other website.
# Instead of using this file, consider using a specific rule such as
# allowing access based on (sub)domain:
#
# Header set Access-Control-Allow-Origin "subdomain.example.com"
#
# Header set Access-Control-Allow-Origin "*"
#
# ----------------------------------------------------------------------
# | Cross-origin images |
# ----------------------------------------------------------------------
# Send the CORS header for images when browsers request it.
#
# https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image
# https://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html
SetEnvIf Origin ":" IS_CORS
Header set Access-Control-Allow-Origin "*" env=IS_CORS
# ----------------------------------------------------------------------
# | Cross-origin web fonts |
# ----------------------------------------------------------------------
# Allow cross-origin access to web fonts.
#
# https://developers.google.com/fonts/docs/troubleshooting
Header set Access-Control-Allow-Origin "*"
# ----------------------------------------------------------------------
# | Cross-origin resource timing |
# ----------------------------------------------------------------------
# Allow cross-origin access to the timing information for all resources.
#
# If a resource isn't served with a `Timing-Allow-Origin` header that would
# allow its timing information to be shared with the document, some of the
# attributes of the `PerformanceResourceTiming` object will be set to zero.
#
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Timing-Allow-Origin
# https://www.w3.org/TR/resource-timing/
# https://www.stevesouders.com/blog/2014/08/21/resource-timing-practical-tips/
#
# Header set Timing-Allow-Origin: "*"
#
# ######################################################################
# # ERRORS #
# ######################################################################
# ----------------------------------------------------------------------
# | Custom error messages/pages |
# ----------------------------------------------------------------------
# Customize what Apache returns to the client in case of an error.
#
# https://httpd.apache.org/docs/current/mod/core.html#errordocument
ErrorDocument 404 /404.html
# ----------------------------------------------------------------------
# | Error prevention |
# ----------------------------------------------------------------------
# Disable the pattern matching based on filenames.
#
# This setting prevents Apache from returning a 404 error as the result of a
# rewrite when the directory with the same name does not exist.
#
# https://httpd.apache.org/docs/current/content-negotiation.html#multiviews
Options -MultiViews
# ######################################################################
# # INTERNET EXPLORER #
# ######################################################################
# ----------------------------------------------------------------------
# | Document modes |
# ----------------------------------------------------------------------
# Force Internet Explorer 8/9/10 to render pages in the highest mode
# available in various cases when it may not.
#
# https://hsivonen.fi/doctype/#ie8
#
# (!) Starting with Internet Explorer 11, document modes are deprecated.
# If your business still relies on older web apps and services that were
# designed for older versions of Internet Explorer, you might want to
# consider enabling `Enterprise Mode` throughout your company.
#
# https://msdn.microsoft.com/en-us/library/ie/bg182625.aspx#docmode
# https://blogs.msdn.microsoft.com/ie/2014/04/02/stay-up-to-date-with-enterprise-mode-for-internet-explorer-11/
# https://msdn.microsoft.com/en-us/library/ff955275.aspx
Header always set X-UA-Compatible "IE=edge" "expr=%{CONTENT_TYPE} =~ m#text/html#i"
# ######################################################################
# # MEDIA TYPES AND CHARACTER ENCODINGS #
# ######################################################################
# ----------------------------------------------------------------------
# | Media types |
# ----------------------------------------------------------------------
# Serve resources with the proper media types (f.k.a. MIME types).
#
# https://www.iana.org/assignments/media-types/media-types.xhtml
# https://httpd.apache.org/docs/current/mod/mod_mime.html#addtype
# Data interchange
AddType application/atom+xml atom
AddType application/json json map topojson
AddType application/ld+json jsonld
AddType application/rss+xml rss
AddType application/geo+json geojson
AddType application/rdf+xml rdf
AddType application/xml xml
# JavaScript
# Servers should use text/javascript for JavaScript resources.
# https://html.spec.whatwg.org/multipage/scripting.html#scriptingLanguages
AddType text/javascript js mjs
# Manifest files
AddType application/manifest+json webmanifest
AddType application/x-web-app-manifest+json webapp
AddType text/cache-manifest appcache
# Media files
AddType audio/mp4 f4a f4b m4a
AddType audio/ogg oga ogg opus
AddType image/bmp bmp
AddType image/svg+xml svg svgz
AddType image/webp webp
AddType video/mp4 f4v f4p m4v mp4
AddType video/ogg ogv
AddType video/webm webm
AddType video/x-flv flv
# Serving `.ico` image files with a different media type prevents
# Internet Explorer from displaying them as images:
# https://github.com/h5bp/html5-boilerplate/commit/37b5fec090d00f38de64b591bcddcb205aadf8ee
AddType image/x-icon cur ico
# WebAssembly
AddType application/wasm wasm
# Web fonts
AddType font/woff woff
AddType font/woff2 woff2
AddType application/vnd.ms-fontobject eot
AddType font/ttf ttf
AddType font/collection ttc
AddType font/otf otf
# Other
AddType application/octet-stream safariextz
AddType application/x-bb-appworld bbaw
AddType application/x-chrome-extension crx
AddType application/x-opera-extension oex
AddType application/x-xpinstall xpi
AddType text/calendar ics
AddType text/markdown markdown md
AddType text/vcard vcard vcf
AddType text/vnd.rim.location.xloc xloc
AddType text/vtt vtt
AddType text/x-component htc
# ----------------------------------------------------------------------
# | Character encodings |
# ----------------------------------------------------------------------
# Serve all resources labeled as `text/html` or `text/plain` with the media type
# `charset` parameter set to `UTF-8`.
#
# https://httpd.apache.org/docs/current/mod/core.html#adddefaultcharset
AddDefaultCharset utf-8
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Serve the following file types with the media type `charset` parameter set to
# `UTF-8`.
#
# https://httpd.apache.org/docs/current/mod/mod_mime.html#addcharset
AddCharset utf-8 .appcache \
.bbaw \
.css \
.htc \
.ics \
.js \
.json \
.manifest \
.map \
.markdown \
.md \
.mjs \
.topojson \
.vtt \
.vcard \
.vcf \
.webmanifest \
.xloc
# ######################################################################
# # REWRITES #
# ######################################################################
# ----------------------------------------------------------------------
# | Rewrite engine |
# ----------------------------------------------------------------------
# (1) Turn on the rewrite engine (this is necessary in order for the
# `RewriteRule` directives to work).
#
# https://httpd.apache.org/docs/current/mod/mod_rewrite.html#RewriteEngine
#
# (2) Enable the `FollowSymLinks` option if it isn't already.
#
# https://httpd.apache.org/docs/current/mod/core.html#options
#
# (3) If your web host doesn't allow the `FollowSymlinks` option, you need to
# comment it out or remove it, and then uncomment the
# `Options +SymLinksIfOwnerMatch` line (4), but be aware of the performance
# impact.
#
# https://httpd.apache.org/docs/current/misc/perf-tuning.html#symlinks
#
# (4) Some cloud hosting services will require you set `RewriteBase`.
#
# https://www.rackspace.com/knowledge_center/frequently-asked-question/why-is-modrewrite-not-working-on-my-site
# https://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase
#
# (5) Depending on how your server is set up, you may also need to use the
# `RewriteOptions` directive to enable some options for the rewrite engine.
#
# https://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriteoptions
# (1)
RewriteEngine On
# (2)
Options +FollowSymlinks
# (3)
# Options +SymLinksIfOwnerMatch
# (4)
# RewriteBase /
# (5)
# RewriteOptions
# ----------------------------------------------------------------------
# | Forcing `https://` |
# ----------------------------------------------------------------------
# Redirect from the `http://` to the `https://` version of the URL.
#
# https://wiki.apache.org/httpd/RewriteHTTPToHTTPS
# (1) If you're using cPanel AutoSSL or the Let's Encrypt webroot method it
# will fail to validate the certificate if validation requests are
# redirected to HTTPS. Turn on the condition(s) you need.
#
# https://www.iana.org/assignments/well-known-uris/well-known-uris.xhtml
# https://tools.ietf.org/html/draft-ietf-acme-acme-12
#
# RewriteEngine On
# RewriteCond %{HTTPS} !=on
# # (1)
# # RewriteCond %{REQUEST_URI} !^/\.well-known/acme-challenge/
# # RewriteCond %{REQUEST_URI} !^/\.well-known/cpanel-dcv/[\w-]+$
# # RewriteCond %{REQUEST_URI} !^/\.well-known/pki-validation/[A-F0-9]{32}\.txt(?:\ Comodo\ DCV)?$
# RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
#
# ----------------------------------------------------------------------
# | Suppressing the `www.` at the beginning of URLs |
# ----------------------------------------------------------------------
# Rewrite www.example.com → example.com
# The same content should never be available under two different URLs,
# especially not with and without `www.` at the beginning.
# This can cause SEO problems (duplicate content), and therefore, you should
# choose one of the alternatives and redirect the other one.
#
# (!) NEVER USE BOTH WWW-RELATED RULES AT THE SAME TIME!
# (1) Set %{ENV:PROTO} variable, to allow rewrites to redirect with the
# appropriate schema automatically (http or https).
#
# (2) The rule assumes by default that both HTTP and HTTPS environments are
# available for redirection.
# If your SSL certificate could not handle one of the domains used during
# redirection, you should turn the condition on.
#
# https://github.com/h5bp/server-configs-apache/issues/52
RewriteEngine On
# (1)
RewriteCond %{HTTPS} =on
RewriteRule ^ - [E=PROTO:https]
RewriteCond %{HTTPS} !=on
RewriteRule ^ - [E=PROTO:http]
# (2)
# RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ %{ENV:PROTO}://%1%{REQUEST_URI} [R=301,L]
# ----------------------------------------------------------------------
# | Forcing the `www.` at the beginning of URLs |
# ----------------------------------------------------------------------
# Rewrite example.com → www.example.com
# The same content should never be available under two different URLs,
# especially not with and without `www.` at the beginning.
# This can cause SEO problems (duplicate content), and therefore, you should
# choose one of the alternatives and redirect the other one.
#
# (!) NEVER USE BOTH WWW-RELATED RULES AT THE SAME TIME!
# (1) Set %{ENV:PROTO} variable, to allow rewrites to redirect with the
# appropriate schema automatically (http or https).
#
# (2) The rule assumes by default that both HTTP and HTTPS environments are
# available for redirection.
# If your SSL certificate could not handle one of the domains used during
# redirection, you should turn the condition on.
#
# https://github.com/h5bp/server-configs-apache/issues/52
# Be aware that the following might not be a good idea if you use "real"
# subdomains for certain parts of your website.
#
# RewriteEngine On
# # (1)
# RewriteCond %{HTTPS} =on
# RewriteRule ^ - [E=PROTO:https]
# RewriteCond %{HTTPS} !=on
# RewriteRule ^ - [E=PROTO:http]
# # (2)
# # RewriteCond %{HTTPS} !=on
# RewriteCond %{HTTP_HOST} !^www\. [NC]
# RewriteCond %{SERVER_ADDR} !=127.0.0.1
# RewriteCond %{SERVER_ADDR} !=::1
# RewriteRule ^ %{ENV:PROTO}://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
#
# ######################################################################
# # SECURITY #
# ######################################################################
# ----------------------------------------------------------------------
# | Frame Options |
# ----------------------------------------------------------------------
# Protect website against clickjacking.
#
# The example below sends the `X-Frame-Options` response header with the value
# `DENY`, informing browsers not to display the content of the web page in any
# frame.
#
# This might not be the best setting for everyone. You should read about the
# other two possible values the `X-Frame-Options` header field can have:
# `SAMEORIGIN` and `ALLOW-FROM`.
# https://tools.ietf.org/html/rfc7034#section-2.1.
#
# Keep in mind that while you could send the `X-Frame-Options` header for all
# of your website's pages, this has the potential downside that it forbids even
# non-malicious framing of your content (e.g.: when users visit your website
# using a Google Image Search results page).
#
# Nonetheless, you should ensure that you send the `X-Frame-Options` header for
# all pages that allow a user to make a state-changing operation (e.g: pages
# that contain one-click purchase links, checkout or bank-transfer confirmation
# pages, pages that make permanent configuration changes, etc.).
#
# Sending the `X-Frame-Options` header can also protect your website against
# more than just clickjacking attacks.
# https://cure53.de/xfo-clickjacking.pdf.
#
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
# https://tools.ietf.org/html/rfc7034
# https://blogs.msdn.microsoft.com/ieinternals/2010/03/30/combating-clickjacking-with-x-frame-options/
# https://www.owasp.org/index.php/Clickjacking
#
# Header always set X-Frame-Options "DENY" "expr=%{CONTENT_TYPE} =~ m#text/html#i"
#
# ----------------------------------------------------------------------
# | Content Security Policy (CSP) |
# ----------------------------------------------------------------------
# Mitigate the risk of cross-site scripting and other content-injection
# attacks.
#
# This can be done by setting a `Content Security Policy` which whitelists
# trusted sources of content for your website.
#
# There is no policy that fits all websites, you will have to modify the
# `Content-Security-Policy` directives in the example depending on your needs.
#
# The example policy below aims to:
#
# (1) Restrict all fetches by default to the origin of the current website by
# setting the `default-src` directive to `'self'` - which acts as a
# fallback to all "Fetch directives" (https://developer.mozilla.org/en-US/docs/Glossary/Fetch_directive).
#
# This is convenient as you do not have to specify all Fetch directives
# that apply to your site, for example:
# `connect-src 'self'; font-src 'self'; script-src 'self'; style-src 'self'`, etc.
#
# This restriction also means that you must explicitly define from which
# site(s) your website is allowed to load resources from.
#
# (2) The `` element is not allowed on the website. This is to prevent
# attackers from changing the locations of resources loaded from relative
# URLs.
#
# If you want to use the `` element, then `base-uri 'self'` can be
# used instead.
#
# (3) Form submissions are only allowed from the current website by setting:
# `form-action 'self'`.
#
# (4) Prevents all websites (including your own) from embedding your webpages
# within e.g. the `