Last active
August 7, 2020 15:21
-
-
Save tannerhodges/3bc9b4c8e0fabf5e7096a0190830da8f to your computer and use it in GitHub Desktop.
HTTP Security Headers for Nginx & PHP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Add HTTP Headers to improve site security. | |
# https://owasp.org/www-project-secure-headers/#tab=Headers | |
# X-Frame-Options: Stop people from loading your site in an iframe on their own site. | |
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options | |
add_header X-Frame-Options "SAMEORIGIN"; | |
# X-XSS-Protection: Stop pages from loading when the browser detects cross-site scripting (XSS) attacks. | |
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection | |
add_header X-XSS-Protection "1; mode=block"; | |
# X-Content-Type-Options: Prevents IE & Chrome from MIME-sniffing responses away from their declared content-type. | |
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options | |
add_header X-Content-Type-Options "nosniff"; | |
# Strict-Transport-Security (aka "HSTS"): Tell browsers they should only access this site using HTTPS (not HTTP). | |
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security | |
# https://scotthelme.co.uk/hsts-the-missing-link-in-tls/ | |
add_header Strict-Transport-Security "max-age=31536000; preload"; | |
# Content Security Policy | |
# Restrict what types of requests can run on our site. Helps prevent XSS, data injection, etc. | |
# | |
# - default-src - Default rules for all content. | |
# - 'unsafe-inline' - Allow inline scripts. | |
# - 'unsafe-eval' - Allow eval scripts (e.g., in Vue development mode). | |
# - https: - Only allow assets served over HTTPS. | |
# - data: - Allow data URIs (e.g., SVG background-images). | |
# - block-all-mixed-content - Prevent insecure content from loading on the site. | |
# - upgrade-insecure-requests - Replace insecure HTTP requests with HTTPS ones instead. | |
# | |
# https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP | |
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/block-all-mixed-content | |
# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/upgrade-insecure-requests | |
# https://scotthelme.co.uk/content-security-policy-an-introduction/ | |
add_header Content-Security-Policy "default-src 'unsafe-inline' 'unsafe-eval' https: data:; block-all-mixed-content; upgrade-insecure-requests"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Add HTTP Headers to improve site security. | |
* @see https://owasp.org/www-project-secure-headers/#tab=Headers | |
* | |
* Based on the _excellent_ HTTP Headers plugin by Dimitar Ivanov. | |
* @see https://github.com/riverside/http-headers | |
* | |
* The only reason we don't use that plugin is because it doesn't | |
* have a Network-level admin to easily control headers for the | |
* entire site. Otherwise, I'd use it in a heartbeat. | |
* | |
* For now, the simplest way to maintain sitewide headers is to | |
* load them through a custom plugin. | |
* | |
* P.S. We also _have_ to do this via PHP because Pantheon locks | |
* down their server Nginx configs. | |
*/ | |
function add_security_headers() { | |
$headers = [ | |
/** | |
* X-Frame-Options | |
* ---------------- | |
* Stop people from loading your site in an iframe on their own site. | |
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options | |
*/ | |
'X-Frame-Options' => 'SAMEORIGIN', | |
/** | |
* X-XSS-Protection | |
* ---------------- | |
* Stop pages from loading when the browser detects cross-site scripting (XSS) attacks. | |
* Mostly for users of older web browsers that don't yet support `Content-Security-Policy`. | |
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection | |
*/ | |
'X-XSS-Protection' => '1; mode=block', | |
/** | |
* X-Content-Type-Options | |
* ---------------------- | |
* Prevents IE & Chrome from MIME-sniffing responses away from their declared content-type. | |
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options | |
*/ | |
'X-Content-Type-Options' => 'nosniff', | |
/** | |
* Strict-Transport-Security (aka "HSTS") | |
* -------------------------------------- | |
* Tell browsers they should only access this site using HTTPS (not HTTP). | |
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security | |
* @see https://scotthelme.co.uk/hsts-the-missing-link-in-tls/ | |
*/ | |
'Strict-Transport-Security' => 'max-age=31536000; preload', | |
/** | |
* Content Security Policy | |
* ----------------------- | |
* Restrict what types of requests can run on our site. Helps prevent XSS, data injection, etc. | |
* | |
* Here's what each piece of this header means: | |
* | |
* - default-src - Default rules for all content. | |
* - 'unsafe-inline' - Allow inline scripts. | |
* - 'unsafe-eval' - Allow eval scripts (e.g., in Vue development mode). | |
* - https: - Only allow assets served over HTTPS. | |
* - data: - Allow data URIs (e.g., SVG background-images). | |
* - block-all-mixed-content - Prevent insecure content from loading on the site. | |
* - upgrade-insecure-requests - Replace insecure HTTP requests with HTTPS ones instead. | |
* | |
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP | |
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/block-all-mixed-content | |
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/upgrade-insecure-requests | |
* @see https://scotthelme.co.uk/content-security-policy-an-introduction/ | |
*/ | |
'Content-Security-Policy' => "default-src 'unsafe-inline' 'unsafe-eval' https: data:; block-all-mixed-content; upgrade-insecure-requests", | |
]; | |
/** | |
* Add all headers to the current response. | |
* NOTE: This replaces any duplicate headers from other plugins. | |
* @see https://www.php.net/manual/en/function.header.php | |
*/ | |
foreach ( $headers as $key => $value ) { | |
header( sprintf( "%s: %s", $key, $value ) ); | |
} | |
} | |
// NOTE: For WordPress, add headers to all non-admin enqueues, actions, and filters. | |
// if ( ! is_admin() ) { | |
// add_action('send_headers', '\CCDC\SecurityHeaders\add_headers'); | |
// } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment