| 1 |
<?php |
| 2 |
// Exit if accessed directly. |
| 3 |
if ( ! defined( 'ABSPATH' ) ) { |
| 4 |
exit; |
| 5 |
} |
| 6 |
|
| 7 |
/** |
| 8 |
* Apply HSTS Header. |
| 9 |
* |
| 10 |
* Preserve the one-time legacy HSTS migration decision. |
| 11 |
* |
| 12 |
* @return void |
| 13 |
*/ |
| 14 |
function ns_shield_legacy_hsts_value_is_enabled( $value ) { |
| 15 |
return true === $value || 1 === $value || '1' === $value; |
| 16 |
} |
| 17 |
|
| 18 |
/** |
| 19 |
* Check whether the one-time legacy HSTS migration has completed. |
| 20 |
* |
| 21 |
* @return bool |
| 22 |
*/ |
| 23 |
function ns_shield_legacy_hsts_migration_is_completed() { |
| 24 |
return ns_shield_legacy_hsts_value_is_enabled( get_option( 'ns_shield_legacy_hsts_migration_completed', false ) ); |
| 25 |
} |
| 26 |
|
| 27 |
/** |
| 28 |
* Check whether the saved legacy HSTS decision is active. |
| 29 |
* |
| 30 |
* @return bool |
| 31 |
*/ |
| 32 |
function ns_shield_legacy_hsts_is_enabled() { |
| 33 |
$legacy_value = get_option( 'ns_shield_legacy_hsts_active', false ); |
| 34 |
|
| 35 |
return ns_shield_legacy_hsts_value_is_enabled( $legacy_value ); |
| 36 |
} |
| 37 |
|
| 38 |
/** |
| 39 |
* Migrate former HSTS settings exactly once without re-enabling HSTS later. |
| 40 |
* |
| 41 |
* @return bool Whether this call performed the migration. |
| 42 |
*/ |
| 43 |
function ns_shield_migrate_legacy_hsts() { |
| 44 |
if ( ns_shield_legacy_hsts_migration_is_completed() ) { |
| 45 |
return false; |
| 46 |
} |
| 47 |
|
| 48 |
$was_hsts_enabled = ns_shield_legacy_hsts_value_is_enabled( get_option( 'ns_shield_hsts', false ) ); |
| 49 |
$were_security_headers_enabled = ns_shield_legacy_hsts_value_is_enabled( get_option( 'ns_shield_security_headers', false ) ); |
| 50 |
|
| 51 |
update_option( 'ns_shield_legacy_hsts_active', $was_hsts_enabled || $were_security_headers_enabled, false ); |
| 52 |
update_option( 'ns_shield_legacy_hsts_migration_completed', true, false ); |
| 53 |
update_option( 'ns_shield_installed_version', NS_SHIELD_VERSION, false ); |
| 54 |
|
| 55 |
return true; |
| 56 |
} |
| 57 |
add_action( 'plugins_loaded', 'ns_shield_migrate_legacy_hsts', 1 ); |
| 58 |
|
| 59 |
/** |
| 60 |
* Preserve HSTS only for legacy configurations during the Free-version migration. |
| 61 |
* |
| 62 |
* @return void |
| 63 |
*/ |
| 64 |
function ns_shield_apply_hsts_header() { |
| 65 |
if ( is_ssl() && ns_shield_legacy_hsts_is_enabled() ) { |
| 66 |
header( 'Strict-Transport-Security: max-age=31536000; includeSubDomains; preload' ); |
| 67 |
} |
| 68 |
} |
| 69 |
add_action( 'send_headers', 'ns_shield_apply_hsts_header' ); |
| 70 |
|
| 71 |
/** |
| 72 |
* Warn administrators that their legacy HSTS configuration remains active. |
| 73 |
* |
| 74 |
* @return void |
| 75 |
*/ |
| 76 |
function ns_shield_legacy_hsts_admin_notice() { |
| 77 |
if ( ! current_user_can( 'manage_options' ) || ! ns_shield_legacy_hsts_is_enabled() ) { |
| 78 |
return; |
| 79 |
} |
| 80 |
|
| 81 |
if ( ! function_exists( 'get_current_screen' ) ) { |
| 82 |
return; |
| 83 |
} |
| 84 |
|
| 85 |
$screen = get_current_screen(); |
| 86 |
|
| 87 |
if ( ! $screen || 'settings_page_secure-options' !== $screen->id ) { |
| 88 |
return; |
| 89 |
} |
| 90 |
|
| 91 |
echo '<div class="notice notice-warning"><p>' . esc_html__( 'A legacy HSTS configuration with includeSubDomains and preload is still active. The header is temporarily preserved to avoid disrupting the website. Move this advanced HSTS configuration to the web server, Cloudflare, or a managed solution before disabling it.', 'netsensai-shield' ) . '</p></div>'; |
| 92 |
} |
| 93 |
add_action( 'admin_notices', 'ns_shield_legacy_hsts_admin_notice' ); |
| 94 |
|