Forked from wpmudev-sls/wpmudev-defender-headers-login.php
Created
February 10, 2022 20:37
-
-
Save sumonst21/6b19cffc5ee7eb18e181ebb1e779fa9e to your computer and use it in GitHub Desktop.
[Defender] - Add security headers on login page, useful for situation where home page getting redirected to login page
This file contains hidden or 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 | |
/** | |
* Plugin Name: [Defender] - Security header on login page | |
* Plugin URI: https://premium.wpmudev.org/ | |
* Description: Add security headers on login page, useful for redirections on login page | |
* Author: Prashant Singh @ WPMUDEV | |
* Author URI: https://premium.wpmudev.org/ | |
* License: GPLv2 or later | |
* Task: SLS-2748 | |
*/ | |
if ( ! defined( 'ABSPATH' ) ) { | |
exit; | |
} | |
if ( defined( 'WP_CLI' ) && WP_CLI ) { | |
return; | |
} | |
if ( ! class_exists( 'WPMUDEV_Defender_Admin_Headers' ) ) { | |
class WPMUDEV_Defender_Admin_Headers { | |
private static $_instance = null; | |
public static function get_instance() { | |
if ( is_null( self::$_instance ) ) { | |
self::$_instance = new WPMUDEV_Defender_Admin_Headers(); | |
} | |
return self::$_instance; | |
} | |
private function __construct() { | |
add_action( 'login_head', array( $this, 'wpmudev_admin_headers' ) ); | |
} | |
public function wpmudev_admin_headers(){ | |
if ( headers_sent() ) { | |
return; | |
} | |
$header_settings = get_site_option('wd_security_headers_settings'); | |
if( !empty( $header_settings ) ){ | |
$header_settings = json_decode( $header_settings ); | |
if ( true === $header_settings->sh_xframe && in_array( $header_settings->sh_xframe_mode, array( 'sameorigin', 'allow-from', 'deny' ), true ) ) { | |
$mode = 'allow-from' === $header_settings->sh_xframe_mode ? 'sameorigin' : $header_settings->sh_xframe_mode; | |
header( trim( 'X-Frame-Options: ' . $mode ) ); | |
} | |
if ( true === $header_settings->sh_referrer_policy | |
&& isset( $header_settings->sh_referrer_policy_mode ) | |
&& in_array( | |
$header_settings->sh_referrer_policy_mode, | |
array( | |
'no-referrer', | |
'no-referrer-when-downgrade', | |
'origin', | |
'origin-when-cross-origin', | |
'same-origin', | |
'strict-origin', | |
'strict-origin-when-cross-origin', | |
'unsafe-url', | |
), | |
true | |
) | |
) { | |
$headers = 'Referrer-Policy: ' . $header_settings->sh_referrer_policy_mode; | |
header( $headers ); | |
} | |
if ( true === $header_settings->sh_feature_policy | |
&& isset( $header_settings->sh_feature_policy_mode ) | |
&& in_array( $header_settings->sh_feature_policy_mode, array( 'self', 'allow', 'origins', 'none' ), true ) | |
) { | |
$headers = ''; | |
$features = array( | |
'accelerometer', | |
'autoplay', | |
'camera', | |
'encrypted-media', | |
'fullscreen', | |
'geolocation', | |
'gyroscope', | |
'magnetometer', | |
'microphone', | |
'midi', | |
'payment', | |
'usb', | |
); | |
switch ( $header_settings->sh_feature_policy_mode ) { | |
case 'self': | |
array_walk( | |
$features, | |
function ( &$value, $key ) { | |
$value .= " 'self'"; | |
} | |
); | |
$headers = 'Feature-Policy: ' . implode( '; ', $features ); | |
break; | |
case 'allow': | |
array_walk( | |
$features, | |
function ( &$value, $key ) { | |
$value .= ' *'; | |
} | |
); | |
$headers = 'Feature-Policy: ' . implode( '; ', $features ); | |
break; | |
case 'origins': | |
if ( isset( $header_settings->sh_feature_policy_urls ) && ! empty( $header_settings->sh_feature_policy_urls ) ) { | |
$urls = explode( PHP_EOL, $header_settings->sh_feature_policy_urls ); | |
$urls = array_map( 'trim', $urls ); | |
$urls = implode( ' ', $urls ); | |
array_walk( | |
$features, | |
function ( &$value, $key ) use ( $urls ) { | |
$value .= ' ' . $urls; | |
} | |
); | |
$headers = 'Feature-Policy: ' . implode( '; ', $features ); | |
} | |
break; | |
case 'none': | |
array_walk( | |
$features, | |
function ( &$value, $key ) { | |
$value .= " 'none'"; | |
} | |
); | |
$headers = 'Feature-Policy: ' . implode( '; ', $features ); | |
break; | |
default: | |
break; | |
} | |
if ( strlen( $headers ) > 0 ) { | |
header( trim( $headers ) ); | |
} | |
} | |
if ( true === $header_settings->sh_content_type_options && 'nosniff' === $header_settings->sh_content_type_options_mode ) { | |
header( 'X-Content-Type-Options: nosniff' ); | |
} | |
if ( true === $header_settings->sh_xss_protection && in_array( $header_settings->sh_xss_protection_mode, array( 'sanitize', 'block', 'none' ), true ) ) { | |
$headers = ''; | |
switch ( $header_settings->sh_xss_protection_mode ) { | |
case 'sanitize': | |
$headers = 'X-XSS-Protection: 1'; | |
break; | |
case 'block': | |
$headers = 'X-XSS-Protection: 1; mode=block'; | |
break; | |
default: | |
break; | |
} | |
if ( strlen( $headers ) > 0 ) { | |
header( trim( $headers ) ); | |
} | |
} | |
if ( true === $header_settings->sh_strict_transport ) { | |
$headers = 'Strict-Transport-Security:'; | |
$default_max_age = 604800; | |
if ( isset( $header_settings->hsts_cache_duration ) && ! empty( $header_settings->hsts_cache_duration ) ) { | |
$arr = $this->wpmudev_time_in_seconds(); | |
//set default for a week, so RIPs wont waring weak header | |
$seconds = isset( $arr[ $header_settings->hsts_cache_duration ] ) | |
? $arr[ $header_settings->hsts_cache_duration ] | |
: $default_max_age; | |
if ( ! is_null( $seconds ) ) { | |
$headers .= ' max-age=' . $seconds; | |
} | |
} else { | |
//set default for a week | |
$headers .= ' max-age=' . $default_max_age; | |
} | |
if ( '1' === (string) $header_settings->include_subdomain ) { | |
$headers .= ' ; includeSubDomains'; | |
} | |
if ( '1' === (string) $header_settings->hsts_preload ) { | |
$headers .= ' ; preload'; | |
} | |
header( $headers ); | |
} | |
} | |
} | |
private function wpmudev_time_in_seconds(){ | |
return array( | |
'1 hour' => 1 * 3600, | |
'24 hours' => 86400, | |
'7 days' => 7 * 86400, | |
'30 days' => 30 * 86400, | |
'3 months' => ( 3 * 30 + 1 ) * 86400, | |
'6 months' => ( 6 * 30 + 3 ) * 86400, | |
'1 year' => 365 * 86400, | |
'2 years' => 365 * 2 * 86400, | |
); | |
} | |
} | |
if ( ! function_exists( 'wpmudev_defender_admin_header' ) ) { | |
function wpmudev_defender_admin_header() { | |
return WPMUDEV_Defender_Admin_Headers::get_instance(); | |
}; | |
add_action( 'plugins_loaded', 'wpmudev_defender_admin_header', 10 ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment