Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save sumonst21/6b19cffc5ee7eb18e181ebb1e779fa9e to your computer and use it in GitHub Desktop.
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
<?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