| @@ -1,32 +1,57 @@ | ||
| 1 | -<?php | |
| 2 | -// Exit if accessed directly. | |
| 3 | -if ( ! defined( 'ABSPATH' ) ) { | |
| 4 | - exit; | |
| 5 | -} | |
| 6 | - | |
| 7 | -/** | |
| 8 | - * Apply security headers. | |
| 9 | - * | |
| 10 | - * This function applies several HTTP security headers to enhance site protection if the | |
| 11 | - * 'ns_shield_security_headers' option is enabled. The following headers are applied: | |
| 12 | - * - Strict-Transport-Security: Applied only if the connection is secure (HTTPS). | |
| 13 | - * - X-Frame-Options: SAMEORIGIN | |
| 14 | - * - X-Content-Type-Options: nosniff | |
| 15 | - * - Referrer-Policy: no-referrer-when-downgrade | |
| 16 | - * - Permissions-Policy: geolocation=(self), microphone=() | |
| 17 | - * | |
| 18 | - * @return void | |
| 19 | - */ | |
| 20 | -function ns_shield_apply_security_headers() { | |
| 21 | - if ( get_option( 'ns_shield_security_headers' ) ) { | |
| 22 | - // Apply HSTS header only if connection is secure. | |
| 23 | - if ( is_ssl() ) { | |
| 24 | - header( "Strict-Transport-Security: max-age=31536000; includeSubDomains; preload" ); | |
| 25 | - } | |
| 26 | - header( "X-Frame-Options: SAMEORIGIN" ); | |
| 27 | - header( "X-Content-Type-Options: nosniff" ); | |
| 28 | - header( "Referrer-Policy: no-referrer-when-downgrade" ); | |
| 29 | - header( "Permissions-Policy: geolocation=(self), microphone=()" ); | |
| 30 | - } | |
| 31 | -} | |
| 32 | -add_action( 'send_headers', 'ns_shield_apply_security_headers' ); | |
| 1 | +<?php | |
| 2 | +// Exit if accessed directly. | |
| 3 | +if ( ! defined( 'ABSPATH' ) ) { | |
| 4 | + exit; | |
| 5 | +} | |
| 6 | + | |
| 7 | +/** | |
| 8 | + * Apply security headers. | |
| 9 | + * | |
| 10 | + * This function applies several HTTP security headers to enhance site protection if the | |
| 11 | + * 'ns_shield_security_headers' option is enabled. The following headers are applied: | |
| 12 | + * - X-Frame-Options: SAMEORIGIN | |
| 13 | + * - X-Content-Type-Options: nosniff | |
| 14 | + * - Referrer-Policy: strict-origin-when-cross-origin | |
| 15 | + * - Permissions-Policy: geolocation=(self), microphone=() | |
| 16 | + * - Strict-Transport-Security: max-age=31536000 (HTTPS only) | |
| 17 | + * | |
| 18 | + * @return void | |
| 19 | + */ | |
| 20 | +function ns_shield_security_headers_are_enabled() { | |
| 21 | + $security_headers_value = get_option( 'ns_shield_security_headers' ); | |
| 22 | + | |
| 23 | + return true === $security_headers_value || 1 === $security_headers_value || '1' === $security_headers_value; | |
| 24 | +} | |
| 25 | + | |
| 26 | +/** | |
| 27 | + * Apply the Referrer-Policy header once per request. | |
| 28 | + * | |
| 29 | + * @return void | |
| 30 | + */ | |
| 31 | +function ns_shield_apply_referrer_policy() { | |
| 32 | + static $referrer_policy_sent = false; | |
| 33 | + | |
| 34 | + if ( $referrer_policy_sent || ! ns_shield_security_headers_are_enabled() ) { | |
| 35 | + return; | |
| 36 | + } | |
| 37 | + | |
| 38 | + header( 'Referrer-Policy: strict-origin-when-cross-origin' ); | |
| 39 | + $referrer_policy_sent = true; | |
| 40 | +} | |
| 41 | + | |
| 42 | +function ns_shield_apply_security_headers() { | |
| 43 | + if ( ns_shield_security_headers_are_enabled() ) { | |
| 44 | + header( "X-Frame-Options: SAMEORIGIN" ); | |
| 45 | + header( "X-Content-Type-Options: nosniff" ); | |
| 46 | + ns_shield_apply_referrer_policy(); | |
| 47 | + header( "Permissions-Policy: geolocation=(self), microphone=()" ); | |
| 48 | + | |
| 49 | + // Legacy HSTS is more restrictive and must remain the only HSTS header when active. | |
| 50 | + if ( is_ssl() && ! ns_shield_legacy_hsts_is_enabled() ) { | |
| 51 | + header( 'Strict-Transport-Security: max-age=31536000' ); | |
| 52 | + } | |
| 53 | + } | |
| 54 | +} | |
| 55 | +add_action( 'send_headers', 'ns_shield_apply_security_headers' ); | |
| 56 | +add_action( 'rest_pre_serve_request', 'ns_shield_apply_referrer_policy', 0 ); | |
| 57 | +?> | |