Server : nginx/1.24.0 System : Linux ip-172-31-33-48 6.14.0-1011-aws #11~24.04.1-Ubuntu SMP Fri Aug 1 02:07:25 UTC 2025 x86_64 User : www-data ( 33) PHP Version : 8.3.6 Disable Function : NONE Directory : /var/www/html/wp-content/plugins.off/ninjafirewall/lib/ |
Upload File : |
<?php // +---------------------------------------------------------------------+ // | NinjaFirewall (WP Edition) | // | | // | (c) NinTechNet - https://nintechnet.com/ | // +---------------------------------------------------------------------+ // | This program is free software: you can redistribute it and/or | // | modify it under the terms of the GNU General Public License as | // | published by the Free Software Foundation, either version 3 of | // | the License, or (at your option) any later version. | // | | // | This program is distributed in the hope that it will be useful, | // | but WITHOUT ANY WARRANTY; without even the implied warranty of | // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | // | GNU General Public License for more details. | // +---------------------------------------------------------------------+ sa if ( strpos($_SERVER['SCRIPT_NAME'], '/nfwlog/') !== FALSE || strpos($_SERVER['SCRIPT_NAME'], '/ninjafirewall/') !== FALSE ) { die('Forbidden'); } if ( defined('NFW_STATUS') ) { return; } if ( defined('WP_CLI') && WP_CLI && PHP_SAPI === 'cli' ) { if (! defined('NFW_UWL') ) { define('NFW_UWL', true); } return; } $nfw_ = []; $nfw_['fw_starttime'] = nfw_fc_metrics('start'); // Optional NinjaFirewall configuration file // ( see https://blog.nintechnet.com/ninjafirewall-wp-edition-the-htninja-configuration-file/ ) : if ( @file_exists($nfw_['file'] = dirname($_SERVER['DOCUMENT_ROOT']) .'/.htninja') || @file_exists($nfw_['file'] = $_SERVER['DOCUMENT_ROOT'] .'/.htninja') ) { $nfw_['res'] = @include_once $nfw_['file']; if ( $nfw_['res'] == 'ALLOW' ) { if (! defined( 'NFW_UWL' ) ) { define('NFW_UWL', true); } nfw_quit( 20 ); return; } if ( $nfw_['res'] == 'BLOCK' ) { header('HTTP/1.1 403 Forbidden'); header('Status: 403 Forbidden'); header('Pragma: no-cache'); header('Cache-Control: no-cache, no-store, must-revalidate'); header('Expires: 0'); die('403 Forbidden'); } } // Clear warning if there's an open_basedir restriction if ( function_exists('error_clear_last') ) { // PHP 7.0+ error_clear_last(); } $nfw_['wp_content'] = dirname(dirname(dirname( __DIR__ ))); // Check if we have a user-defined log directory // (see "Path to NinjaFirewall's log and cache directory" // at https://blog.nintechnet.com/ninjafirewall-wp-edition-the-htninja-configuration-file/ ) : if ( defined('NFW_LOG_DIR') ) { $nfw_['log_dir'] = NFW_LOG_DIR . '/nfwlog'; } else { $nfw_['log_dir'] = $nfw_['wp_content'] . '/nfwlog'; } if (! is_dir($nfw_['log_dir']) ) { if (! mkdir( $nfw_['log_dir'] . '/cache', 0755, true) ) { define( 'NFW_STATUS', 13 ); return; } } // Get/set PID if ( file_exists( "{$nfw_['log_dir']}/cache/.pid" ) ) { define( 'NFW_PID', file_get_contents( "{$nfw_['log_dir']}/cache/.pid" ) ); } // Check if we are connecting over HTTPS nfw_is_https(); if ( strpos($_SERVER['SCRIPT_NAME'], 'wp-login.php' ) !== FALSE ) { nfw_bfd(1); } elseif ( strpos($_SERVER['SCRIPT_NAME'], 'xmlrpc.php' ) !== FALSE ) { nfw_bfd(2); } if (empty ($wp_config)) { $wp_config = dirname($nfw_['wp_content']) . '/wp-config.php'; } // Connection $ret = nfw_connect(); if ( $ret !== true ) { nfw_quit( $ret ); return; } // Fetch options $ret = nfw_get_data( 'nfw_options' ); if ( $ret !== true ) { nfw_quit( $ret ); return; } if (! empty($nfw_['nfw_options']['clogs_pubkey']) && isset($_POST['clogs_req']) ) { include_once 'fw_centlog.php'; fw_centlog(); exit; } if ( empty($nfw_['nfw_options']['enabled']) ) { nfw_quit( 20 ); return; } include_once 'custom_firewall.php'; // HTTP response headers if ( (! empty( $nfw_['nfw_options']['response_headers'] ) || ! empty($nfw_['nfw_options']['custom_headers']) ) && function_exists('header_register_callback') ) { if (! empty( $nfw_['nfw_options']['response_headers'] ) ) { define('NFW_RESHEADERS', $nfw_['nfw_options']['response_headers']); if (! empty( $nfw_['nfw_options']['response_headers'][6] ) && ! empty( $nfw_['nfw_options']['csp_frontend_data'] ) ) { define( 'CSP_FRONTEND_DATA', $nfw_['nfw_options']['csp_frontend_data']); } if (! empty( $nfw_['nfw_options']['response_headers'][7] ) && ! empty( $nfw_['nfw_options']['csp_backend_data'] ) ) { define( 'CSP_BACKEND_DATA', $nfw_['nfw_options']['csp_backend_data'] ); } } if (! empty( $nfw_['nfw_options']['custom_headers'] ) ) { define('NFW_CUSTHEADERS', $nfw_['nfw_options']['custom_headers']); } header_register_callback('nfw_response_headers'); } if (! empty($nfw_['nfw_options']['force_ssl']) ) { define('FORCE_SSL_ADMIN', true); } if (! empty($nfw_['nfw_options']['disallow_edit']) ) { define('DISALLOW_FILE_EDIT', true); } if (! empty($nfw_['nfw_options']['disallow_mods']) ) { define('DISALLOW_FILE_MODS', true); } if (! empty($nfw_['nfw_options']['disable_error_handler']) ) { define('WP_DISABLE_FATAL_ERROR_HANDLER', true); } nfw_check_ip(); // Superglobals override if (! empty($nfw_['nfw_options']['php_superglobals']) ) { $sgs = [ '_GET', '_POST', '_SESSION', '_COOKIE', '_SERVER', '_FILES', '_ENV', '_REQUEST', 'GLOBALS' ]; foreach( $sgs as $sg ) { if ( isset( $_GET[$sg] ) ) { nfw_log('Superglobals override attempt', "\$_GET[$sg]: ". serialize( $_GET[$sg] ), 6, 0); unset( $_GET[$sg] ); } if ( isset( $_POST[$sg] ) ) { nfw_log('Superglobals override attempt', "\$_POST[$sg]: ". serialize( $_POST[$sg] ), 6, 0); unset( $_POST[$sg] ); } if ( isset( $_COOKIE[$sg] ) ) { nfw_log('Superglobals override attempt', "\$_COOKIE[$sg]: ". serialize( $_COOKIE[$sg] ), 6, 0); unset( $_COOKIE[$sg] ); } } } // We only start a session if users already have a PHP session // cookie because we don't need write access yet: $nfw_['session_name'] = ini_get('session.name'); if ( isset( $_COOKIE[ $nfw_['session_name'] ] ) ) { nfw_check_session(); } if (! empty($_SESSION['nfw_goodguy']) ) { // Look for Live Log AJAX request: if (! empty($_SESSION['nfw_livelog']) && isset($_POST['livecls']) && isset($_POST['lines'])) { include_once 'fw_livelog.php'; fw_livelog_show(); } // Fetch admin rules $ret = nfw_get_data( 'nfw_rules' ); if ( $ret !== true ) { nfw_quit( $ret ); return; } nfw_check_admin_request(); nfw_quit( 20 ); return; } define('NFW_SWL', 1); if ( file_exists($nfw_['log_dir'] .'/cache/livelogrun.php')) { include_once 'fw_livelog.php'; fw_livelog_record(); } if (! empty($nfw_['nfw_options']['php_errors']) ) { @error_reporting(0); @ini_set('display_errors', 0); } if ( empty($nfw_['nfw_options']['allow_local_ip']) && NFW_REMOTE_ADDR_PRIVATE == true ) { nfw_quit(20); return; } if ( NFW_REMOTE_ADDR_PRIVATE == true && strpos( $_SERVER['SCRIPT_NAME'], '/wp-cron.php' ) !== FALSE ) { nfw_quit(20); return; } if ( @$nfw_['nfw_options']['scan_protocol'] == 1 && NFW_IS_HTTPS == true ) { nfw_quit(20); return; } if ( @$nfw_['nfw_options']['scan_protocol'] == 2 && NFW_IS_HTTPS == false ) { nfw_quit(20); return; } if (! empty($nfw_['nfw_options']['fg_enable']) && ! defined('NFW_WPWAF') ) { include_once 'fw_fileguard.php'; fw_fileguard(); } if (! empty($nfw_['nfw_options']['no_host_ip']) && @filter_var(parse_url('http://'.$_SERVER['HTTP_HOST'], PHP_URL_HOST), FILTER_VALIDATE_IP) ) { nfw_log('HTTP_HOST is an IP', $_SERVER['HTTP_HOST'], 1, 0); nfw_block(); } if (! empty($nfw_['nfw_options']['referer_post']) && $_SERVER['REQUEST_METHOD'] == 'POST' && ! isset($_SERVER['HTTP_REFERER']) ) { nfw_log('POST method without Referer header', $_SERVER['REQUEST_METHOD'], 1, 0); nfw_block(); } if (! empty($nfw_['nfw_options']['admin_ajax']) && strpos( $_SERVER['SCRIPT_NAME'], 'wp-admin/admin-ajax.php' ) !== FALSE ) { nfw_is_bot( 'admin-ajax.php' ); } if ( strpos($_SERVER['SCRIPT_NAME'], '/xmlrpc.php' ) !== FALSE ) { if (! empty($nfw_['nfw_options']['no_xmlrpc']) ) { nfw_log('Access to WordPress XML-RPC API', $_SERVER['SCRIPT_NAME'], 2, 0); nfw_block(); } if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) { if (! isset( $HTTP_RAW_POST_DATA ) ) { @$HTTP_RAW_POST_DATA = file_get_contents( 'php://input' ); } if (! empty($nfw_['nfw_options']['no_xmlrpc_multi']) ) { if ( @strpos( $HTTP_RAW_POST_DATA, '<methodName>system.multicall</methodName>') !== FALSE ) { nfw_log('Access to WordPress XML-RPC API (system.multicall method)', $_SERVER['SCRIPT_NAME'], 2, 0); nfw_block(); } } if (! empty($nfw_['nfw_options']['no_xmlrpc_pingback']) ) { if ( @strpos( $HTTP_RAW_POST_DATA, '<methodName>pingback.ping</methodName>') !== FALSE ) { nfw_log('Access to WordPress XML-RPC API (pingback.ping)', $_SERVER['SCRIPT_NAME'], 2, 0); nfw_block(); } } } } if (! empty($nfw_['nfw_options']['no_xmlrpc_pingback']) && strpos($_SERVER['HTTP_USER_AGENT'], '; verifying pingback from ') !== FALSE) { nfw_log('Blocked pingback verification', $_SERVER['HTTP_USER_AGENT'], 2, 0); nfw_block(); } // WordPress Aplication Passwords if (! empty($nfw_['nfw_options']['no_appswd']) && strpos( $_SERVER['SCRIPT_NAME'], '/wp-admin/authorize-application.php' ) !== FALSE ) { nfw_log('Access to WordPress Application Passwords', $_SERVER['SCRIPT_NAME'], 2, 0); nfw_block(); } if (! empty($nfw_['nfw_options']['no_post_themes']) && $_SERVER['REQUEST_METHOD'] == 'POST' && strpos($_SERVER['SCRIPT_NAME'], $nfw_['nfw_options']['no_post_themes']) !== FALSE ) { nfw_log('POST request in the themes folder', $_SERVER['SCRIPT_NAME'], 2, 0); nfw_block(); } if (! empty($nfw_['nfw_options']['wp_dir']) && preg_match( '`' . $nfw_['nfw_options']['wp_dir'] . '`', $_SERVER['SCRIPT_NAME']) ) { nfw_log('Forbidden direct access to PHP script', $_SERVER['SCRIPT_NAME'], 2, 0); nfw_block(); } nfw_check_upload(); // Fetch rules $ret = nfw_get_data( 'nfw_rules' ); if ( $ret !== true ) { nfw_quit( $ret ); return; } nfw_check_request( $nfw_['nfw_rules'], $nfw_['nfw_options'] ); if (! empty($nfw_['nfw_options']['get_sanitise']) && ! empty($_GET) ){ $_GET = nfw_sanitise( $_GET, 1, 'GET'); } if (! empty($nfw_['nfw_options']['post_sanitise']) && ! empty($_POST) ){ $_POST = nfw_sanitise( $_POST, 1, 'POST'); } if (! empty($nfw_['nfw_options']['request_sanitise']) && ! empty($_REQUEST) ){ $_REQUEST = nfw_sanitise( $_REQUEST, 1, 'REQUEST'); } if (! empty($nfw_['nfw_options']['cookies_sanitise']) && ! empty($_COOKIE) ) { $_COOKIE = nfw_sanitise( $_COOKIE, 3, 'COOKIE'); } if (! empty($nfw_['nfw_options']['ua_sanitise']) && ! empty($_SERVER['HTTP_USER_AGENT']) ) { $_SERVER['HTTP_USER_AGENT'] = nfw_sanitise( $_SERVER['HTTP_USER_AGENT'], 1, 'HTTP_USER_AGENT'); } if (! empty($nfw_['nfw_options']['referer_sanitise']) && ! empty($_SERVER['HTTP_REFERER']) ) { $_SERVER['HTTP_REFERER'] = nfw_sanitise( $_SERVER['HTTP_REFERER'], 1, 'HTTP_REFERER'); } if (! empty($nfw_['nfw_options']['php_path_i']) && ! empty($_SERVER['PATH_INFO']) ) { $_SERVER['PATH_INFO'] = nfw_sanitise( $_SERVER['PATH_INFO'], 2, 'PATH_INFO'); } if (! empty($nfw_['nfw_options']['php_path_t']) && ! empty($_SERVER['PATH_TRANSLATED']) ) { $_SERVER['PATH_TRANSLATED'] = nfw_sanitise( $_SERVER['PATH_TRANSLATED'], 2, 'PATH_TRANSLATED'); } if (! empty($nfw_['nfw_options']['php_self']) && ! empty($_SERVER['PHP_SELF']) ) { $_SERVER['PHP_SELF'] = nfw_sanitise( $_SERVER['PHP_SELF'], 2, 'PHP_SELF'); } nfw_quit(20); return; // ===================================================================== // Close the SQL link, set the firewall status, clear the $nfw_ array // and close the session before leaving. function nfw_quit( $status ) { global $nfw_; define( 'NFW_STATUS', $status ); if ( isset( $nfw_['mysqli'] ) ) { $nfw_['mysqli']->close(); } $nfw_ = []; } // ===================================================================== // Connect to the DB. function nfw_connect() { global $nfw_, $wp_config; // WPWAF mode? if ( defined('NFW_WPWAF') && NFW_WPWAF == 2 ) { $nfw_['wp_waf'] = 2; return true; } // Check if we have a SQL link that was defined in the .htninja. // See "Giving NinjaFirewall a MySQLi link identifier" // at https://blog.nintechnet.com/ninjafirewall-wp-edition-the-htninja-configuration-file/ if (! empty( $GLOBALS['nfw_mysqli'] ) && ! empty( $GLOBALS['nfw_table_prefix'] ) ) { $nfw_['mysqli'] = $GLOBALS['nfw_mysqli']; $nfw_['table_prefix'] = $GLOBALS['nfw_table_prefix']; return true; } // DB if (! file_exists( $wp_config ) ) { if (! @file_exists( $wp_config = dirname( dirname($nfw_['wp_content']) ) . '/wp-config.php') ) { return 1; } } if (! $nfw_['fh'] = fopen($wp_config, 'r') ) { return 2; } // Potential SQL flags $nfw_['MYSQL_CLIENT_FLAGS'] = 0; while (! feof($nfw_['fh'])) { $nfw_['line'] = fgets($nfw_['fh']); if ( preg_match('/^\s*define\s*\(\s*[\'"]DB_NAME[\'"]\s*,\s*[\'"](.+?)[\'"]/', $nfw_['line'], $nfw_['match']) ) { $nfw_['DB_NAME'] = $nfw_['match'][1]; } elseif ( preg_match('/^\s*define\s*\(\s*[\'"]DB_USER[\'"]\s*,\s*[\'"](.+?)[\'"]/', $nfw_['line'], $nfw_['match']) ) { $nfw_['DB_USER'] = $nfw_['match'][1]; } elseif ( preg_match('/^\s*define\s*\(\s*[\'"]DB_PASSWORD[\'"]\s*,\s*([\'"])(.+?)\1\s*\);/', $nfw_['line'], $nfw_['match']) ) { $nfw_['DB_PASSWORD'] = str_replace( '\\'.$nfw_['match'][1], $nfw_['match'][1], $nfw_['match'][2] ); if ( $nfw_['match'][1] == '"' ) { $nfw_['DB_PASSWORD'] = str_replace( '\$', '$', $nfw_['DB_PASSWORD'] ); } } elseif ( preg_match('/^\s*define\s*\(\s*[\'"]DB_HOST[\'"]\s*,\s*[\'"](.+?)[\'"]/', $nfw_['line'], $nfw_['match']) ) { $nfw_['DB_HOST'] = $nfw_['match'][1]; } elseif ( preg_match('/^\s*\$table_prefix\s*=\s*[\'"](.*?)[\'"]/', $nfw_['line'], $nfw_['match']) ) { $nfw_['table_prefix'] = $nfw_['match'][1]; } elseif ( preg_match('/^\s*define\s*\(\s*[\'"]MYSQL_CLIENT_FLAGS[\'"]\s*,\s*(.+?)\s*\)/', $nfw_['line'], $nfw_['match']) ) { if ( empty( $nfw_['MYSQL_CLIENT_FLAGS'] ) ) { $available_flags = [ 'MYSQLI_CLIENT_COMPRESS' => MYSQLI_CLIENT_COMPRESS, 'MYSQLI_CLIENT_FOUND_ROWS' => MYSQLI_CLIENT_FOUND_ROWS, 'MYSQLI_CLIENT_IGNORE_SPACE' => MYSQLI_CLIENT_IGNORE_SPACE, 'MYSQLI_CLIENT_INTERACTIVE' => MYSQLI_CLIENT_INTERACTIVE, 'MYSQLI_CLIENT_SSL' => MYSQLI_CLIENT_SSL, 'MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT' => MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT ]; // There could be one or more flags, e.g., 'MYSQLI_CLIENT_SSL | MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT' $tmp_flags = explode( '|', $nfw_['match'][1] ); foreach( $tmp_flags as $tmp_flag ) { $tmp_flag = trim( $tmp_flag ); if ( isset( $available_flags[$tmp_flag] ) ) { $nfw_['MYSQL_CLIENT_FLAGS'] += $available_flags[$tmp_flag]; } } } } } fclose($nfw_['fh']); unset($wp_config); if (! isset($nfw_['DB_NAME']) || ! isset($nfw_['DB_USER']) || ! isset($nfw_['DB_PASSWORD']) || ! isset($nfw_['DB_HOST']) || ! isset($nfw_['table_prefix']) ) { return 3; } nfw_check_dbhost(); // Make sure mysqli extension is loaded if (! function_exists( 'mysqli_real_connect' ) ) { return 14; } @$nfw_['mysqli'] = mysqli_init(); @mysqli_real_connect( $nfw_['mysqli'], $nfw_['DB_HOST'], $nfw_['DB_USER'], $nfw_['DB_PASSWORD'], $nfw_['DB_NAME'], $nfw_['port'], $nfw_['socket'], $nfw_['MYSQL_CLIENT_FLAGS'] ); if ($nfw_['mysqli']->connect_error) { return 4; } return true; } // ===================================================================== // Fetch rules and options. function nfw_get_data( $what ) { global $nfw_; if ( $what != 'nfw_rules' ) { $what = 'nfw_options'; } // WP API if ( isset( $nfw_['wp_waf'] ) && $nfw_['wp_waf'] == 2 ) { if ( is_multisite() ) { $nfw_[ $what ] = get_site_option( $what ); } else { $nfw_[ $what ] = get_option( $what ); } return true; // DB } else { // Rules if ( $what == 'nfw_rules' ) { if (! $nfw_['result'] = @$nfw_['mysqli']->query('SELECT * FROM `' . $nfw_['mysqli']->real_escape_string($nfw_['table_prefix']) . "options` WHERE `option_name` = 'nfw_rules'") ) { return 7; } if (! $nfw_['rules'] = @$nfw_['result']->fetch_object() ) { return 8; } if (! $nfw_['nfw_rules'] = @unserialize( $nfw_['rules']->option_value ) ) { return 12; } // Options } else { if (! $nfw_['result'] = @$nfw_['mysqli']->query('SELECT * FROM `' . $nfw_['mysqli']->real_escape_string($nfw_['table_prefix']) . "options` WHERE `option_name` = 'nfw_options'") ) { // Maybe this is an old multisite install where the main site // options table is named 'wp_1_options' instead of 'wp_options' if (! $nfw_['result'] = @$nfw_['mysqli']->query('SELECT * FROM `' . $nfw_['mysqli']->real_escape_string($nfw_['table_prefix']) . "1_options` WHERE `option_name` = 'nfw_options'") ) { return 5; } // Change the table prefix to match 'wp_1_options' $nfw_['table_prefix'] = "{$nfw_['table_prefix']}1_"; } if (! $nfw_['options'] = @$nfw_['result']->fetch_object() ) { return 6; } if (! $nfw_['nfw_options'] = @unserialize( $nfw_['options']->option_value ) ) { return 11; } } // Make sure we have something or return an error if ( $what == 'nfw_rules' && ! isset( $nfw_['nfw_rules']['1'] ) ) { return 16; } elseif ( $what == 'nfw_options' && ! isset( $nfw_['nfw_options']['enabled'] ) ) { return 15; } // All good return true; } } // ===================================================================== // Check for HTTPS. function nfw_is_https() { // Can be defined in the .htninja: if ( defined('NFW_IS_HTTPS') ) { return; } if ( ( isset( $_SERVER['SERVER_PORT'] ) && $_SERVER['SERVER_PORT'] == 443 ) || ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') || ( isset( $_SERVER['HTTPS'] ) && $_SERVER['HTTPS'] !== 'off' ) ) { define('NFW_IS_HTTPS', true); } else { define('NFW_IS_HTTPS', false); } } // ===================================================================== function nfw_check_session() { global $nfw_; if (! function_exists('session_status') ) { if (session_id() ) return; } else { if (session_status() === PHP_SESSION_ACTIVE) return; } // Prepare session: @ini_set('session.cookie_httponly', 1); @ini_set('session.use_only_cookies', 1); if ( defined('NFW_IS_HTTPS') && NFW_IS_HTTPS == true ) { @ini_set('session.cookie_secure', 1); } if (! headers_sent() ) { session_start(); $nfw_['session_id'] = 1; } } // ===================================================================== function nfw_check_ip() { if ( defined('NFW_REMOTE_ADDR') ) { return; } global $nfw_; if (! isset( $_SERVER['REMOTE_ADDR'] ) ) { $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; } if (strpos($_SERVER['REMOTE_ADDR'], ',') !== false) { // Ensure we have a proper and single IP (a user may use the .htninja file // to redirect HTTP_X_FORWARDED_FOR, which may contain more than one IP, // to REMOTE_ADDR): $nfw_['match'] = array_map('trim', @explode(',', $_SERVER['REMOTE_ADDR'])); foreach($nfw_['match'] as $nfw_['m']) { if ( filter_var($nfw_['m'], FILTER_VALIDATE_IP) ) { define( 'NFW_REMOTE_ADDR', $nfw_['m']); break; } } } if (! defined('NFW_REMOTE_ADDR') ) { define('NFW_REMOTE_ADDR', htmlspecialchars($_SERVER['REMOTE_ADDR']) ); } if ( filter_var( NFW_REMOTE_ADDR, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) { define( 'NFW_REMOTE_ADDR_IPV6', true ); } else { define( 'NFW_REMOTE_ADDR_IPV6', false ); } if (filter_var( NFW_REMOTE_ADDR, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) ) { define( 'NFW_REMOTE_ADDR_PRIVATE', false ); } else { define( 'NFW_REMOTE_ADDR_PRIVATE', true ); } } // ===================================================================== function nfw_check_upload() { if ( defined('NFW_STATUS') ) { return; } global $nfw_; $f_uploaded = []; $f_uploaded = nfw_fetch_uploads(); $tmp = ''; if ( empty($nfw_['nfw_options']['uploads']) ) { $tmp = ''; foreach ($f_uploaded as $key => $value) { if (! $f_uploaded[$key]['name']) { continue; } if ( empty( $f_uploaded[$key]['size'] ) ) { $f_uploaded[$key]['size'] = 0; } $tmp .= $f_uploaded[$key]['name'] . ' (' . number_format($f_uploaded[$key]['size']) . ' bytes) '; } if ( $tmp ) { nfw_log('Blocked file upload attempt', rtrim($tmp, ' '), 3, 0); nfw_block(); } } else { foreach ($f_uploaded as $key => $value) { if (! $f_uploaded[$key]['name']) { continue; } if ( empty( $f_uploaded[$key]['size'] ) ) { $f_uploaded[$key]['size'] = 0; } if ( $f_uploaded[$key]['size'] > 67 && $f_uploaded[$key]['size'] < 129 ) { $data = file_get_contents( $f_uploaded[$key]['tmp_name'] ); if ( preg_match('`^X5O!P%@AP' . '\[4\\\PZX54\(P\^\)7CC\)7}\$EIC' . 'AR-STANDARD-ANTIVI' . 'RUS-TEST-FILE!\$H' . '\+H\*' . '[\x09\x10\x13\x20\x1A]*`', $data) ) { nfw_log('EICAR Standard Anti-Virus Test File blocked', $f_uploaded[$key]['name'] . ' (' . number_format($f_uploaded[$key]['size']) . ' bytes)', 3, 0); nfw_block(); } } if (! defined('NFW_NO_MIMECHECK') && isset( $f_uploaded[$key]['type'] ) && ! preg_match('/\/.*\bphp\d?\b/i', $f_uploaded[$key]['type']) && preg_match('/\.ph(?:p([34x7]|5\d?)?|t(ml)?)(?:\.|$)/', $f_uploaded[$key]['name']) ) { nfw_log('Blocked file upload attempt (MIME-type mismatch)', $f_uploaded[$key]['name'] .' != '. $f_uploaded[$key]['type'], 3, 0); nfw_block(); } if (! empty($nfw_['nfw_options']['sanitise_fn']) ) { if ( empty( $nfw_['nfw_options']['substitute'] ) ) { $nfw_['nfw_options']['substitute'] = 'X'; } $tmp = ''; $f_uploaded_name = $f_uploaded[$key]['name']; $f_uploaded[$key]['name'] = preg_replace('/[^\w\.\-]/i', $nfw_['nfw_options']['substitute'], $f_uploaded[$key]['name'], -1, $count); // Sanitize double (or more) extensions (e.g., foo.php.gif => foo.php_.gif) $ret = []; $ret = nfw_sanitize_extensions( $f_uploaded[$key]['name'], $nfw_['nfw_options']['substitute'] ); if (! empty( $ret['count'] ) ) { $count += $ret['count']; $f_uploaded[$key]['name'] = $ret['name']; } if ($count) { $tmp = ' (sanitising '. $count . ' char. from filename)'; $_FILES = nfw_sanitize_filename( $_FILES, $f_uploaded_name, $f_uploaded[$key]['name'] ); } } if (! isset( $f_uploaded[$key]['size'] ) ) { $size = 'n/a'; } else { $size = number_format( $f_uploaded[$key]['size'] ); } nfw_log('File upload detected, no action taken' . $tmp , "{$f_uploaded[$key]['name']} ($size bytes)", 5, 0); } } } // ===================================================================== function nfw_fetch_uploads() { global $file_buffer, $upload_array, $prop_key; $upload_array = []; foreach( $_FILES as $f_key => $f_value ) { foreach( $f_value as $prop_key => $prop_value ) { // Fetch all but 'error': if (! in_array( $prop_key, ['name', 'type', 'tmp_name', 'size'] ) ) { continue; } $file_buffer = $f_key; if ( is_array( $_FILES[$f_key][$prop_key] ) ) { nfw_recursive_upload( $_FILES[$f_key][$prop_key] ); } else { if (! empty( $_FILES[$f_key][$prop_key] ) ) { $upload_array[$f_key][$prop_key] = $_FILES[$f_key][$prop_key]; } } } } return $upload_array; } // ===================================================================== function nfw_recursive_upload( $data ) { global $file_buffer, $upload_array, $prop_key; foreach( $data as $data_key => $data_value ) { if ( is_array( $data_value ) ) { $file_buffer .= "_{$data_key}"; nfw_recursive_upload( $data_value ); } else { if ( empty( $data_value ) ) { continue; } $upload_array["{$file_buffer}_{$data_key}"][$prop_key] = $data_value; } } } // ===================================================================== function nfw_sanitize_filename( $array, $key, $value ) { array_walk_recursive( $array, function( &$v, $k ) use ( $key, $value ) { if (! empty( $v ) && $v == $key ) { $v = $value; } } ); return $array; } function nfw_sanitize_extensions( $filename, $subs ) { $ret = []; $ret['count'] = 0; $parts = explode( '.', $filename ); $ret['name'] = array_shift( $parts ); $extension = array_pop( $parts ); foreach ( $parts as $part ) { if (! empty( $part ) ) { $ret['name'] .= ".{$part}{$subs}"; ++$ret['count']; } } if ( $extension ) { $ret['name'] .= ".{$extension}"; } return $ret; } // ===================================================================== function nfw_check_admin_request() { global $nfw_; if ( isset( $nfw_['nfw_rules']['999'] ) ) { $nfw_['adm_rules'] = []; foreach ( $nfw_['nfw_rules']['999'] as $key => $value ) { if ( empty( $nfw_['nfw_rules'][$key]['ena'] ) ) { continue; } $nfw_['adm_rules'][$key] = $nfw_['nfw_rules'][$key]; } if (! empty( $nfw_['adm_rules'] ) ) { nfw_check_request( $nfw_['adm_rules'], $nfw_['nfw_options'] ); } } } // ===================================================================== function nfw_check_request( $nfw_rules, $nfw_options ) { if ( defined('NFW_STATUS') ) { return; } global $nfw_, $HTTP_RAW_POST_DATA; foreach ( $nfw_rules as $id => $rules ) { if ( empty( $rules['ena']) ) { continue; } $wherelist = explode('|', $rules['cha'][1]['whe']); foreach ($wherelist as $where) { if ( nfw_disabled_scan( $where, $nfw_options ) ) { continue; } // ================================================================= if ( $where == 'RAW' ) { if (! isset( $HTTP_RAW_POST_DATA ) ) { @$HTTP_RAW_POST_DATA = file_get_contents( 'php://input' ); } if ( nfw_matching( 'RAW', $_SERVER['REQUEST_METHOD'], $nfw_rules, $rules, 1, $id, $nfw_options, $HTTP_RAW_POST_DATA ) ) { nfw_check_subrule( 'RAW', $_SERVER['REQUEST_METHOD'], $nfw_rules, $nfw_options, $rules, $id ); } continue; } // ================================================================= if ( $where == 'POST' || $where == 'GET' || $where == 'COOKIE' || $where == 'SERVER' || $where == 'REQUEST' || $where == 'FILES' || $where == 'SESSION' ) { if (! isset( $GLOBALS['_'. $where ] ) ) { continue; } foreach ($GLOBALS['_' . $where] as $key => $val) { if ( nfw_matching( $where, $key, $nfw_rules, $rules, 1, $id, $nfw_options ) ) { nfw_check_subrule( $where, $key, $nfw_rules, $nfw_options, $rules, $id ); } } continue; } // ================================================================= if ( isset( $_SERVER[$where] ) ) { if ( nfw_matching( 'SERVER', $where, $nfw_rules, $rules, 1, $id, $nfw_options ) ) { nfw_check_subrule( 'SERVER', $where, $nfw_rules, $nfw_options, $rules, $id ); } continue; } // ================================================================= $w = explode(':', $where); // Look for temp hash if ( isset( $rules['cha'][1]['tmp'] ) && isset( $w[1] ) ) { $w[1] = @nfw_check_temp_hash( $w[0], $w[1] ); } if ( empty($w[1]) || ! isset( $GLOBALS['_'.$w[0]][$w[1]] ) || nfw_disabled_scan( $w[0], $nfw_options ) ) { continue; } if ( nfw_matching( $w[0], $w[1], $nfw_rules, $rules, 1, $id, $nfw_options ) ) { nfw_check_subrule( $w[0], $w[1], $nfw_rules, $nfw_options, $rules, $id ); } // ================================================================= } } } // ===================================================================== // Check hash found in a temporary rule (used for hotfix, 0-day etc). function nfw_check_temp_hash( $where, $what ) { global $nfw_; if (is_array( $GLOBALS["_{$where}"] ) && ! empty( $GLOBALS["_{$where}"] ) ) { // Loop foreach( $GLOBALS["_{$where}"] as $key => $value ) { if ( is_string( $key ) ) { // Search in the cache if ( isset( $nfw_['hash'][$key] ) ) { if ( $nfw_['hash'][$key] == $what ) { return $key; } } else { // Save it to the cache $nfw_['hash'][$key] = md5( substr_replace( $key, 'nfw', 2, 0 ) ); if ( $nfw_['hash'][$key] == $what ) { return $key; } } } } } return $what; } // ===================================================================== function nfw_check_subrule( $w0, $w1, $nfw_rules, $nfw_options, $rules, $id ) { if ( isset( $rules['cha'][1]['cap'] ) ) { nfw_matching( $w0, $w1, $nfw_rules, $rules, 2, $id, $nfw_options ); } else { $w = explode(':', $rules['cha'][2]['whe']); if (! isset( $w[1] ) ) { if ( $w[0] == 'RAW' ) { if ( nfw_disabled_scan( 'POST', $nfw_options) && $_SERVER['REQUEST_METHOD'] == 'POST' ) { return; } global $HTTP_RAW_POST_DATA; if (! isset( $HTTP_RAW_POST_DATA ) ) { @$HTTP_RAW_POST_DATA = file_get_contents( 'php://input' ); } nfw_matching( $_SERVER['REQUEST_METHOD'], 'RAW', $nfw_rules, $rules, 2, $id, $nfw_options, $HTTP_RAW_POST_DATA ); return; } $w[2] = $w[1] = $w[0]; $w[0] = 'SERVER'; } else { $w[2] = null; // Look for temp hash if ( isset( $rules['cha'][2]['tmp'] ) ) { $w[1] = @nfw_check_temp_hash( $w[0], $w[1] ); } } if (! isset( $GLOBALS['_'.$w[0]][$w[1]] ) ) { return; } if ( nfw_disabled_scan( $w[0], $nfw_options, $w[2] ) ) { return; } else { nfw_matching( $w[0], $w[1], $nfw_rules, $rules, 2, $id, $nfw_options); } } } // ===================================================================== function nfw_disabled_scan( $where, $nfw_options, $extra = null ) { if ( $extra ) { $where = $extra; } if ( $where == 'POST' && empty($nfw_options['post_scan']) || $where == 'GET' && empty($nfw_options['get_scan']) || $where == 'COOKIE' && empty($nfw_options['cookies_scan']) || $where == 'HTTP_USER_AGENT' && empty($nfw_options['ua_scan']) || $where == 'HTTP_REFERER' && empty($nfw_options['referer_scan']) ) { return 1; } return 0; } // ===================================================================== function nfw_matching( $where, $key, $nfw_rules, $rules, $subid, $id, $nfw_options, $RAW_POST = null ) { global $nfw_; if ( isset( $RAW_POST ) ) { $val = $RAW_POST; } else { $val = $GLOBALS['_'.$where][$key]; } // Check if the user has the required capability, if any if ( isset( $rules['cpb'] ) && isset( $_SESSION['allcaps'] ) ) { $caps = explode( '|', $rules['cpb'] ); foreach( $caps as $cap ) { if (! empty( $_SESSION['allcaps'][$cap] ) ) { return 0; } } } if ( is_array($val) ) { if ( isset( $nfw_['flattened'][$where][$key] ) ) { $val = $nfw_['flattened'][$where][$key]; } else { $val = nfw_flatten( ' ', $val ); $nfw_['flattened'][$where][$key] = $val; } } if ( $where == 'POST' && ! empty($nfw_options['post_b64']) && ! isset($nfw_['b64'][$where][$key]) && $val ) { nfw_check_b64($key, $val); $nfw_['b64'][$where][$key] = 1; } $transform = 1; // NF < 4.1.1: if ( isset( $rules['cha'][$subid]['exe'] ) ) { $transform = 0; if ( function_exists( $rules['cha'][$subid]['exe'] ) ) { $val = @$rules['cha'][$subid]['exe']( $val ); } } // NF >= 4.1.1: if ( isset( $rules['cha'][$subid]['exm'] ) ) { $transform = 0; $exe = explode( '|', $rules['cha'][$subid]['exm'] ); foreach ( $exe as $f ) { if (! function_exists( $f ) ) { break; } $val = @$f( $val ); } } $t = ''; if ( isset( $rules['cha'][$subid]['nor'] ) ) { $t .= 'N'; if ( isset( $nfw_[$t][$where][$key] ) && $transform ) { $val = $nfw_[$t][$where][$key]; } else { $val = nfw_normalize( $val, $nfw_rules ); if ( $transform ) { $nfw_[$t][$where][$key] = $val; } } } if ( isset( $rules['cha'][$subid]['tra'] ) ) { $t .= 'T' . $rules['cha'][$subid]['tra']; if ( isset( $nfw_[$t][$where][$key] ) && $transform ) { $val = $nfw_[$t][$where][$key]; } else { $val = nfw_transform_string( $val, $rules['cha'][$subid]['tra'] ); if ( $transform ) { $nfw_[$t][$where][$key] = $val; } } } if ( empty( $rules['cha'][$subid]['noc']) ) { $t .= 'C'; if ( isset( $nfw_[$t][$where][$key] ) && $transform ) { $val = $nfw_[$t][$where][$key]; } else { $val = nfw_compress_string( $val ); if ( $transform ) { $nfw_[$t][$where][$key] = $val; } } } if ( nfw_operator( $val, $rules['cha'][$subid]['wha'], $rules['cha'][$subid]['ope'] ) ) { if ( isset( $rules['cha'][$subid+1]) ) { return 1; } else { if ( isset( $nfw_['flattened'][$where][$key] ) ) { nfw_log($rules['why'], $where .':' . $key . ' = ' . $nfw_['flattened'][$where][$key], $rules['lev'], $id); } elseif ( isset( $RAW_POST ) ) { nfw_log($rules['why'], $where .':' . $key . ' = ' . $RAW_POST, $rules['lev'], $id); } else { nfw_log($rules['why'], $where .':' . $key . ' = ' . $GLOBALS['_'.$where][$key], $rules['lev'], $id); } nfw_block(); } } return 0; } // ===================================================================== function nfw_operator( $val, $what, $op ) { if (! $val ) { return false; } if ( $op == 2 ) { if ( $val != $what ) { return true; } } elseif ( $op == 3 ) { if ( strpos($val, $what) !== FALSE ) { return true; } } elseif ( $op == 4 ) { if ( stripos($val, $what) !== FALSE ) { return true; } } elseif ( $op == 5 ) { if ( preg_match("`$what`", $val ) ) { return true; } } elseif ( $op == 6 ) { if (! preg_match("`$what`", $val) ) { return true; } } elseif ( $op == 7 ) { return true; } elseif ( $op == 8 ) { if ( strpos($val, $what) === FALSE ) { return true; } } elseif ( $op == 9 ) { if ( stripos($val, $what) === FALSE ) { return true; } } else { if ( $val == $what ) { return true; } } } // ===================================================================== function nfw_normalize( $string, $nfw_rules ) { if ( empty( $string ) ) { return; } $norm = rawurldecode( $string ); if ( strpos( $norm, '%' ) !== false ) { $norm = rawurldecode( $norm ); } if (! $norm ) { return $string; } if ( preg_match('/&(?:#x(?:00)*[0-9a-f]{2}|#0*[12]?[0-9]{2}|amp|[lg]t|nbsp|quot)(?!;|\d)/i', $norm) ) { $norm = preg_replace('/&(#x(?:00)*[0-9a-f]{2}|#0*[12]?[0-9]{2}|amp|[lg]t|nbsp|quot)(?!;|\d)/i', '&\1;', $norm); if (! $norm ) { return $string; } } if ( preg_match('/\\\(?:0?[4-9][0-9]|1[0-7][0-9])/', $norm) ) { $norm = preg_replace_callback('/\\\(0?[4-9][0-9]|1[0-7][0-9])/', 'nfw_oct2ascii', $norm); if (! $norm ) { return $string; } } if ( preg_match('/\\\x[a-f0-9]{2}/i', $norm) ) { $norm = preg_replace_callback('/\\\x([a-f0-9]{2})/i', 'nfw_hex2ascii', $norm); if (! $norm ) { return $string; } } $norm = nfw_html_decode( $norm ); if (! $norm ) { return $string; } if ( preg_match('/&#x?[0-9a-f]+;/i', $norm) ) { $norm = preg_replace('/(&#x?[0-9a-f]+;)/i', '', $norm); if (! $norm ) { return $string; } } if ( preg_match( '/(?:%|\\\)u(?:[0-9a-f]{4}|\{0*[0-9a-f]{2}\})/i', $norm ) ) { $norm = preg_replace_callback('/(?:%|\\\)u(?:([0-9a-f]{4})|\{0*([0-9a-f]{2})\})/i', 'nfw_udecode', $norm); if (! $norm ) { return $string; } } if ( empty( $nfw_rules[2]['ena'] ) ) { $norm = preg_replace('/\x0|%00/', '', $norm); if (! $norm ) { return $string; } } return $norm; } // ===================================================================== function nfw_html_decode( $norm ) { global $nfw_; $nfw_['entity_in'] = array ( '	','
','!','"','"','#','$', '%','&','&',''','(',')','*', '*','+',',','.','/',':',';', '<','<','=','>','>','?','@','[', '[','\',']',']','^','_','`', '`','{','{','|','|','|', '}','}',' ',' ','<⃒','>⃒',"\xa0" ); $nfw_['entity_out'] = array ( '','','!','"','"','#','$','%','&','&',"'",'(',')','*','*','+',',','.','/', ':',';','<','<','=','>','>','?','@','[','[','\\',']',']','^','_','`','`', '{','{','|','|','|','}','}',' ',' ','','',' ' ); $normout = str_replace( $nfw_['entity_in'], $nfw_['entity_out'], $norm); $normout = html_entity_decode( $normout, ENT_QUOTES, 'UTF-8' ); return $normout; } // ===================================================================== function nfw_compress_string( $string, $where = null ) { if (! $string ) { return; } if ( $where == 1 ) { $replace = ' '; } else { $replace = ''; } $string = str_replace( ["\x09", "\x0a","\x0b", "\x0c", "\x0d"], $replace, $string); $string = trim ( preg_replace('/\x20{2,}/', ' ', $string) ); return $string; } // ===================================================================== function nfw_transform_string( $string, $where ) { if (! $string ) { return; } if ( $where == 1 ) { $norm = trim( preg_replace_callback('((^([^a-z/&|#]*)|([\'"])(?:\\\\.|[^\n\3\\\\])*?\3|(?:[0-9a-z_$]+)|.)'. '(?:\s|--[^\n]*+\n|/\*(?:[^*!]|\*(?!/))*+\*/)*'. '(?:(?:\#|--(?:[\x00-\x20\x7f]|$)|/\*$)[^\n]*+\n|/\*!(?:\d{5})?|\*/|/\*(?:[^*!]|\*(?!/))*+\*/)*)si', 'nfw_delcomments1', $string . "\n") ); $norm = preg_replace('/[\'"]\x20*\+?\x20*[\'"]/', '', $norm); $norm = strtolower( str_replace( ['+', "'", '"', "(", ')', '`', ',', ';'], ' ', $norm) ); } elseif ( $where == 2 ) { $norm = trim( preg_replace_callback('((^|([\'"])(?:\\\\.|[^\n\2\\\\])*?\2|(?:[0-9a-z_$]+)|.)'. '(?://[^\n]*+\n|/\*(?:[^*]|\*(?!/))*+\*/)*)si', 'nfw_delcomments2', $string . "\n") ); $norm = preg_replace( ['/[\n\r\t\f\v]/', '`/\*\s*\*/`', '/[\'"`]\x20*[+.]?\x20*[\'"`]/'], ['', ' ', ''], $norm ); } elseif ( $where == 3 ) { $norm = preg_replace( ['`([\\\"\'^]|\$\w+)`', '`([,;]|\s+)`'], ['', ' '], $string ); $norm = preg_replace( ['`/(\./)+`','`/{2,}`', '`/(.+?)/\.\./\1\b`', '`\n`', '`\\\`'], ['/', '/', '/\1', '', ''], $norm ); } return $norm; } // ===================================================================== function nfw_delcomments1 ( $match ) { if (! empty($match[2]) ) { return ' '; } if ( $match[0] != $match[1] ) { return $match[1]. ' '; } return $match[1]; } function nfw_delcomments2 ( $match ) { if ( $match[0] != $match[1] ) { return $match[1]. ' '; } return $match[1]; } // ===================================================================== 2023-05-16 function nfw_udecode( $match ) { if ( isset( $match[2] ) ) { return @json_decode('"\\u00'.$match[2].'"'); } return @json_decode('"\\u'.$match[1].'"'); } // ===================================================================== 2023-05-16 function nfw_oct2ascii( $match ) { return chr( octdec( $match[1] ) ); } // ===================================================================== 2023-05-16 function nfw_hex2ascii( $match ) { return chr( hexdec( $match[1] ) ); } // ===================================================================== 2023-05-16 // Flatten an array. function nfw_flatten( $glue, $pieces ) { if ( defined('NFW_STATUS') ) { return; } $ret = []; foreach ( $pieces as $r_pieces ) { if ( is_array( $r_pieces ) ) { $ret[] = nfw_flatten( $glue, $r_pieces ); } else { if (! empty( $r_pieces ) ) { $ret[] = $r_pieces; } } } return implode( $glue, $ret ); } // ===================================================================== function nfw_check_b64( $key, $string ) { if ( defined('NFW_STATUS') || strlen($string) < 4 ) { return; } $decoded = base64_decode($string); if ( strlen($decoded) < 4 ) { return; } if ( preg_match( '`\b(?:\$?_(COOKIE|ENV|FILES|(?:GE|POS|REQUES)T|SE(RVER|SSION))|HTTP_(?:(?:POST|GET)_VARS|RAW_POST_DATA)|GLOBALS)\s*[=\[)]|\b(?i:array_map|assert|base64_(?:de|en)code|chmod|curl_exec|(?:ex|im)plode|error_reporting|eval|file(?:_get_contents)?|f(?:open|write|close)|fsockopen|function_exists|gzinflate|md5|move_uploaded_file|ob_start|passthru|[ep]reg_replace|phpinfo|stripslashes|strrev|(?:shell_)?exec|substr|system|unlink)\s*\(|[\s;]echo\s*[\'"]|<(?i:applet|embed|i?frame(?:set)?|marquee|object|script)\b|\W\$\{\s*[\'"]\w+[\'"]|<\?(?i:php|=)\s|(?i:(?:\b|\d)select\b.+?from\b.+?(?:\b|\d)where|(?:\b|\d)insert\b.+?into\b|(?:\b|\d)union\b.+?(?:\b|\d)select\b|(?:\b|\d)update\b.+?(?:\b|\d)set\b)|^.{0,25}[;{}]?\b[OC]:\d+:"[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*":\d+:{.*?}`', $decoded) ) { if ( $key === 'args' && ! defined('NFW_WPWAF') && preg_match( '/^{"query":"SELECT/', $decoded ) && strpos($_SERVER['SCRIPT_NAME'], '/jetpack-temp/jp-helper-') !== FALSE ) { return; } nfw_log('BASE64-encoded injection', 'POST:' . $key . ' = ' . $string, '3', 0); nfw_block(); } } // ===================================================================== function nfw_sanitise( $str, $how, $msg ) { if ( defined('NFW_STATUS') ) { return; } if ( empty($str) ) { return $str; } global $nfw_; if (is_string($str) ) { if ($how == 1) { // Full WAF if (! empty( $nfw_['mysqli'] ) ) { $str2 = $nfw_['mysqli']->real_escape_string($str); // WP WAF } else { global $wpdb; $str2 = @$wpdb->_real_escape($str); } $str2 = str_replace( ['`', '<', '>'], ['\\`', '<', '>'], $str2); if ( $msg == 'GET' && strpos( $str2, '/') !== false ) { $str2 = str_replace( ['*', '?'], ['\*', '\?'], $str2 ); } } elseif ($how == 2) { $str2 = str_replace( ['\\', "'", '"', "\x0d", "\x0a", "\x00", "\x1a", '`', '<', '>'], ['\\\\', "\\'", '\\"', '-', '-', '-', '-', '\\`', '<', '>'], $str); } else { $str2 = str_replace( ['\\', "'", "\x00", "\x1a", '`', '<'], ['\\\\', "\\'", '-', '-', '\\`', '<'], $str); } if (! empty($nfw_['nfw_options']['debug']) ) { if ($str2 != $str) { nfw_log('Sanitising user input', $msg . ': ' . $str, 7, 0); // '7' for debugging mode only } return $str; } if ($str2 != $str) { nfw_log('Sanitising user input', $msg . ': ' . $str, 6, 0); } return $str2; } else if (is_array($str) ) { foreach($str as $key => $value) { if ($how == 3) { $key2 = str_replace( ['\\', "'", "\x00", "\x1a", '`', '<', '>'], ['\\\\', "\\'", '-', '-', '\\`', '<', '>'], $key, $occ); } else { $key2 = str_replace( ['\\', "'", '"', "\x0d", "\x0a", "\x00", "\x1a", '`', '<', '>'], ['\\\\', "\\'", '\\"', '-', '-', '-', '-', '`', '<', '>'], $key, $occ); } if ($occ) { unset($str[$key]); nfw_log('Sanitising user input', $msg . ': ' . $key, 6, 0); } $str[$key2] = nfw_sanitise($value, $how, $msg); } return $str; } } // ===================================================================== 2023-05-16 // Block the user and display a message. function nfw_block() { if ( defined('NFW_STATUS') ) { return; } global $nfw_; if (! empty( $nfw_['nfw_options']['debug'] ) ) { return; } $http_codes = [ 400 => '400 Bad Request', 403 => '403 Forbidden', 404 => '404 Not Found', 406 => '406 Not Acceptable', 418 => "418 I'm a teapot", 500 => '500 Internal Server Error', 503 => '503 Service Unavailable' ]; if (! isset( $http_codes[$nfw_['nfw_options']['ret_code']] ) ) { $nfw_['nfw_options']['ret_code'] = 403; } if ( empty( $nfw_['num_incident'] ) ) { $nfw_['num_incident'] = '000000'; } $tmp = str_replace( '%%NUM_INCIDENT%%', $nfw_['num_incident'], base64_decode( $nfw_['nfw_options']['blocked_msg'] ) ); if ( isset( $nfw_['nfw_options']['logo'] ) ) { $tmp = str_replace( '%%NINJA_LOGO%%', "<img alt='NinjaFirewall' src='{$nfw_['nfw_options']['logo']}' />", $tmp ); } $tmp = str_replace('%%REM_ADDRESS%%', NFW_REMOTE_ADDR, $tmp ); if ( isset( $nfw_['session_id'] ) ) { $_SESSION = []; session_destroy(); } if (! headers_sent() ) { header("HTTP/1.1 {$http_codes[$nfw_['nfw_options']['ret_code']]}" ); header("Status: {$http_codes[$nfw_['nfw_options']['ret_code']]}" ); header('Pragma: no-cache'); header('Cache-Control: no-cache, no-store, must-revalidate'); header('Expires: 0'); } echo "<!DOCTYPE HTML PUBLIC '-//IETF//DTD HTML 2.0//EN'><html><head>". "<title>NinjaFirewall {$http_codes[$nfw_['nfw_options']['ret_code']]}</title>". "<style>body{font-family:sans-serif;font-size:13px;color:#000;}</style>". "<meta http-equiv='Content-Type' content='text/html; charset=utf-8'></head>". "<body bgcolor='white'>$tmp</body></html>"; exit; } // ===================================================================== function nfw_log($loginfo, $logdata, $loglevel, $ruleid) { if ( defined('NFW_STATUS') ) { return; } global $nfw_; $nfw_['num_incident'] = mt_rand(1000000, 9000000); if ( $loglevel == 6) { $http_ret_code = '200'; } else { if (! empty($nfw_['nfw_options']['debug']) ) { $loglevel = 7; $http_ret_code = '200'; } else { $http_ret_code = $nfw_['nfw_options']['ret_code']; } } if ( defined('NFW_MAXPAYLOAD') ) { $NFW_MAXPAYLOAD = (int) NFW_MAXPAYLOAD; } else { $NFW_MAXPAYLOAD = 200; } if (strlen($logdata) > $NFW_MAXPAYLOAD ) { $logdata = mb_substr($logdata, 0, $NFW_MAXPAYLOAD , 'utf-8') . '...'; } $res = ''; $string = str_split($logdata); foreach ( $string as $char ) { if ( ord($char) < 32 || ord($char) > 126 ) { $res .= '%' . bin2hex($char); } else { $res .= $char; } } $cur_month = date('Y-m'); $stat_file = $nfw_['log_dir']. '/stats_' . $cur_month . '.php'; $log_file = $nfw_['log_dir']. '/firewall_' . $cur_month . '.php'; if ( file_exists( $stat_file ) ) { $nfw_stat = file_get_contents( $stat_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES ); $nfw_stat = str_replace( '<?php exit; ?>', '', $nfw_stat ); } else { $nfw_stat = '0:0:0:0:0:0:0:0:0:0'; } $nfw_stat_arr = explode(':', $nfw_stat . ':'); ++$nfw_stat_arr[$loglevel]; @file_put_contents( $stat_file, "<?php exit; ?>{$nfw_stat_arr[0]}:{$nfw_stat_arr[1]}:" . "{$nfw_stat_arr[2]}:{$nfw_stat_arr[3]}:{$nfw_stat_arr[4]}:" . "{$nfw_stat_arr[5]}:{$nfw_stat_arr[6]}:{$nfw_stat_arr[7]}:" . "{$nfw_stat_arr[8]}:{$nfw_stat_arr[9]}", LOCK_EX ); if (! file_exists($log_file) ) { $tmp = '<?php exit; ?>' . "\n"; } else { $tmp = ''; } if (! defined('NFW_REMOTE_ADDR') ) { define('NFW_REMOTE_ADDR', $_SERVER['REMOTE_ADDR']); } // Which encoding to use? if ( defined('NFW_LOG_ENCODING') ) { if ( NFW_LOG_ENCODING == 'b64') { $encoding = '[b64:'. base64_encode( $res ) .']'; } elseif ( NFW_LOG_ENCODING == 'none' ) { $encoding = '['. $res .']'; } else { $unp = unpack('H*', $res); $encoding = '[hex:'. array_shift( $unp ) .']'; } } else { $unp = unpack('H*', $res); $encoding = '[hex:'. array_shift( $unp ) .']'; } $elapse = nfw_fc_metrics('stop', $nfw_['fw_starttime']); @file_put_contents( $log_file, $tmp . '[' . time() . '] ' . '[' . $elapse .'] '. '[' . $_SERVER['SERVER_NAME'] . '] ' . '[#' . $nfw_['num_incident'] . '] ' . '[' . $ruleid . '] ' . '[' . $loglevel . '] ' . '[' . nfw_anonymize_ip() . '] ' . '[' . $http_ret_code . '] ' . '[' . $_SERVER['REQUEST_METHOD'] . '] ' . '[' . $_SERVER['SCRIPT_NAME'] . '] ' . '[' . $loginfo . '] ' . $encoding . "\n", FILE_APPEND | LOCK_EX ); } // ===================================================================== 2023-05-16 // Return the time using hrtime (PHP >= 7.3) or microtime. function nfw_fc_metrics( $action = 'start', $starttime = 0 ) { if ( function_exists('hrtime') ) { $metrics = 'hrtime'; } else { $metrics = 'microtime'; } // Start the chrono if ( $action == 'start') { return $metrics(true); } // Stop the chrono and return the formatted elapsed time if ( $metrics == 'hrtime') { return number_format( ( $metrics(true) - $starttime ) / 1000000000, 5 ); } else { return number_format( $metrics(true) - $starttime, 5 ); } } // ===================================================================== 2023-05-16 // Anonymize an IP address by hidding it last 3 characters. function nfw_anonymize_ip() { global $nfw_; if (! empty( $nfw_['nfw_options']['anon_ip'] ) && NFW_REMOTE_ADDR_PRIVATE === false ) { return substr( NFW_REMOTE_ADDR, 0, -3 ) .'xxx'; } return NFW_REMOTE_ADDR; } // ===================================================================== function nfw_bfd($where) { if ( defined('NFW_STATUS') ) { return; } global $nfw_; $bf_conf_dir = $nfw_['log_dir'] . '/cache'; if (! file_exists($bf_conf_dir . '/bf_conf.php') ) { return; } $now = time(); require($bf_conf_dir . '/bf_conf.php'); if ( empty($bf_enable) ) { return; } if ( $where == 2 && empty($bf_xmlrpc) ) { return; } // NinjaFirewall <= 3.4.2: if (! isset( $auth_msgtxt ) ) { $auth_msgtxt = $auth_msg; $b64 = 0; // NinjaFirewall > 3.4.2: } else { $b64 = 1; } // NinjaFirewall < 3.5: if (! isset( $bf_allow_bot ) ) { $bf_allow_bot = 0; } if (! isset( $bf_type ) ) { $bf_type = 0; } if ( $where == 1 && $bf_allow_bot == 0 ) { nfw_is_bot( 'wp-login.php' ); } if ( $where == 1 && isset( $_REQUEST['action'] ) && in_array( $_REQUEST['action'], ['postpass', 'logout', 'lostpassword', 'retrievepassword', 'resetpass', 'rp', 'register', 'confirmaction'] ) ) { return; } if ( $bf_enable == 2 ) { nfw_check_auth($auth_name, $auth_pass, $auth_msgtxt, $bf_rand, $b64, $bf_allow_bot, $bf_type, $captcha_text, $bf_nosig); return; } if ( file_exists($bf_conf_dir . '/bf_blocked' . $where . $_SERVER['SERVER_NAME'] . $bf_rand) ) { $mtime = filemtime( $bf_conf_dir . '/bf_blocked' . $where . $_SERVER['SERVER_NAME'] . $bf_rand ); if ( ($now - $mtime) < $bf_bantime * 60 ) { nfw_check_auth($auth_name, $auth_pass, $auth_msgtxt, $bf_rand, $b64, $bf_allow_bot, $bf_type, $captcha_text, $bf_nosig); return; } else { @unlink($bf_conf_dir . '/bf_blocked' . $where . $_SERVER['SERVER_NAME'] . $bf_rand); } } if ( strpos($bf_request, $_SERVER['REQUEST_METHOD']) === false ) { return; } if ( file_exists($bf_conf_dir . '/bf_' . $where . $_SERVER['SERVER_NAME'] . $bf_rand ) ) { $tmp_log = file( $bf_conf_dir . '/bf_' . $where . $_SERVER['SERVER_NAME'] . $bf_rand, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if ( count( $tmp_log) >= $bf_attempt ) { if ( ($tmp_log[count($tmp_log) - 1] - $tmp_log[count($tmp_log) - $bf_attempt]) <= $bf_maxtime ) { $bfdh = fopen( $bf_conf_dir . '/bf_blocked' . $where . $_SERVER['SERVER_NAME'] . $bf_rand, 'w'); fclose( $bfdh ); unlink( $bf_conf_dir . '/bf_' . $where . $_SERVER['SERVER_NAME'] . $bf_rand ); $nfw_['nfw_options']['ret_code'] = '401'; if ($where == 1) { $where = 'wp-login.php'; } else { $where = 'XML-RPC API'; } nfw_log('Brute-force attack detected on ' . $where, 'enabling HTTP authentication for ' . $bf_bantime . 'mn', 3, 0); if (! empty($bf_authlog) ) { if (defined('LOG_AUTHPRIV') ) { $tmp = LOG_AUTHPRIV; } else { $tmp = LOG_AUTH; } @openlog('ninjafirewall', LOG_NDELAY|LOG_PID, $tmp); @syslog(LOG_INFO, 'Possible brute-force attack from '. $_SERVER['REMOTE_ADDR'] . ' on '. $_SERVER['SERVER_NAME'] .' ('. $where .'). Blocking access for ' . $bf_bantime . 'mn.'); @closelog(); } nfw_check_auth($auth_name, $auth_pass, $auth_msgtxt, $bf_rand, $b64, $bf_allow_bot, $bf_type, $captcha_text, $bf_nosig); return; } } $mtime = filemtime( $bf_conf_dir . '/bf_' . $where . $_SERVER['SERVER_NAME'] . $bf_rand ); if ( ($now - $mtime) > $bf_bantime * 60 ) { unlink( $bf_conf_dir . '/bf_' . $where . $_SERVER['SERVER_NAME'] . $bf_rand ); } } @file_put_contents($bf_conf_dir . '/bf_' . $where . $_SERVER['SERVER_NAME'] . $bf_rand, $now . "\n", FILE_APPEND | LOCK_EX); } // ===================================================================== 2023-05-16 // Block the request if a bot is detected. function nfw_is_bot( $block = '') { global $nfw_; if ( empty( $_SERVER['HTTP_ACCEPT'] ) || empty( $_SERVER['HTTP_ACCEPT_LANGUAGE'] ) || empty( $_SERVER['HTTP_USER_AGENT'] ) || stripos( $_SERVER['HTTP_USER_AGENT'], 'Mozilla') === FALSE ) { if (! empty( $block ) ) { // Whitelist server IP and private addresses calling admin-ajax.php if ( $block == 'admin-ajax.php') { if ( NFW_REMOTE_ADDR == $_SERVER['SERVER_ADDR'] || NFW_REMOTE_ADDR_PRIVATE == true ) { return true; } $block = 'Blocked access to admin-ajax.php'; // No whitelist needed for the login page: } else { $block = 'Blocked access to the login page'; } header('HTTP/1.0 404 Not Found'); header('Pragma: no-cache'); header('Cache-Control: no-cache, no-store, must-revalidate'); header('Expires: 0'); $nfw_['nfw_options']['ret_code'] = '404'; nfw_log( $block, 'bot detection is enabled', 1, 0 ); if ( isset( $nfw_['session_id'] ) ) { $_SESSION = []; session_destroy(); } exit('404 Not Found'); } return true; } return false; } // ===================================================================== function nfw_check_auth( $auth_name, $auth_pass, $auth_msgtxt, $bf_rand, $b64, $bf_allow_bot, $bf_type, $captcha_text, $bf_nosig ) { if ( defined('NFW_STATUS') ) { return; } // Prevent favicon.ico 302 redirection to the login page // due to plugins that do not handle well the login page access: if ( isset( $_GET['redirect_to'] ) && strpos( $_GET['redirect_to'], 'favicon.ico' ) !== FALSE ) { exit; } nfw_check_session(); global $nfw_; if ( isset($_SESSION['nfw_bfd']) && $_SESSION['nfw_bfd'] == $bf_rand ) { return; } if ( $bf_type == 0 ) { // Password protection: if (! empty($_REQUEST['u']) && ! empty($_REQUEST['p']) ) { if ( $_REQUEST['u'] === $auth_name && sha1($_REQUEST['p']) === $auth_pass ) { $_SESSION['nfw_bfd'] = $bf_rand; return; } } } else { // Make sure the GD extension is loaded: if ( function_exists( 'gd_info' ) ) { // Captcha protection: if (! empty( $_REQUEST['c'] ) && isset( $_SESSION['nfw_bfd_c'] ) ) { if ( $_SESSION['nfw_bfd_c'] == strtolower( $_REQUEST['c'] ) ) { $_SESSION['nfw_bfd'] = $bf_rand; unset( $_SESSION['nfw_bfd_c'] ); return; } } } else { // Return in no GD extension: return; } } if ( isset( $nfw_['session_id'] ) ) { $_SESSION = []; session_destroy(); } if ( $b64 ) { $auth_msgtxt = base64_decode( $auth_msgtxt ); } header('HTTP/1.0 401 Unauthorized'); header('X-Frame-Options: SAMEORIGIN'); header('Pragma: no-cache'); header('Cache-Control: no-cache, no-store, must-revalidate'); header('Expires: 0'); if ( empty( $bf_nosig ) ) { $bf_nosig = 'Brute-force protection by NinjaFirewall'; } else { $bf_nosig = ''; } if ( $bf_type == 0 ) { $message = '<html><head><title>'. $bf_nosig .'</title><link rel="stylesheet" href="./wp-includes/css/buttons.min.css" type="text/css"><link rel="stylesheet" href="./wp-admin/css/login.min.css" type="text/css"><link rel="stylesheet" href="./wp-admin/css/forms.min.css" type="text/css"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body class="login wp-core-ui" style="color:#444"><div id="login"><center><h2>' . $auth_msgtxt . '</h2><form method="post"><label>'. $bf_nosig .'</label><br><br><p><input class="input" type="text" name="u" placeholder="Username"></p><p><input class="input" type="password" name="p" placeholder="Password"></p><p align="right"><input type="submit" value="Login Page »" class="button-secondary"></p><input type="hidden" name="reauth" value="1"></form></center></div></body></html>'; } else { $captcha = nfw_get_captcha(); if ( $captcha === false ) { return; } $message = '<html><head><title>'. $bf_nosig .'</title><link rel="stylesheet" href="./wp-includes/css/buttons.min.css" type="text/css"><link rel="stylesheet" href="./wp-admin/css/login.min.css" type="text/css"><link rel="stylesheet" href="./wp-admin/css/forms.min.css" type="text/css"><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body class="login wp-core-ui" style="color:#444"><div id="login"><center><form method="post"><p><label>'. base64_decode( $captcha_text ) .'</label></p><br><p>' . $captcha . '</p><p><input class="input" type="text" name="c" autofocus></p><p align="right"><input type="submit" value="Login Page »" class="button-secondary"></p><input type="hidden" name="reauth" value="1"></form><br><label>'. $bf_nosig .'</label></center></div></body></html>'; } if ( $bf_allow_bot == 0 ) { if ( @ini_set('zlib.output_compression','Off') !== false ) { header('Content-Encoding: gzip'); echo gzencode( $message, 1 ); exit; } } header('Content-Type: text/html; charset=utf-8'); echo $message; exit; } // ===================================================================== function nfw_get_captcha() { if (! function_exists( 'imagettftext' ) ) { echo "<div id='login_error'>NinjaFirewall error: PHP imagettftext() function doesn't exist, the captcha can't be displayed. Make sure PHP is compiled with freetype support (--with-freetype-dir=DIR).</div>"; return false; } nfw_check_session(); $characters = 'AaBbCcDdEeFfGgHhiIJjKkLMmNnPpRrSsTtUuVvWwXxYyZz123456789'; $captcha = ''; while( strlen( $captcha ) < 5 ) { $captcha .= substr( $characters, mt_rand() % strlen( $characters ), 1 ); } // Background image with dimensions $image = imagecreate( 200, 60 ); // Background color: imagecolorallocate( $image, 255, 255, 255 ); // Text color: $text_color = imagecolorallocate( $image, 77, 77, 77 ); // Font: global $nfw_; if ( file_exists( "{$nfw_['log_dir']}/font.ttf" ) ) { imagettftext( $image, 35, 0, 15, 45, $text_color, "{$nfw_['log_dir']}/font.ttf", $captcha ); } else { imagettftext( $image, 35, 0, 15, 45, $text_color, __DIR__ . '/share/font.ttf', $captcha ); } ob_start(); imagepng( $image ); $img_content = ob_get_contents(); ob_end_clean(); imagedestroy( $image ); $res = '<img src="data:image/png;base64,'. base64_encode( $img_content ) .'" />'; $_SESSION['nfw_bfd_c'] = strtolower( $captcha ); return $res; } // ===================================================================== 2023-05-16 // From WP db_connect() function nfw_check_dbhost() { global $nfw_; $nfw_['port'] = null; $nfw_['socket'] = null; $port_or_socket = strstr( $nfw_['DB_HOST'], ':'); if ( ! empty( $port_or_socket ) ) { $nfw_['DB_HOST'] = substr( $nfw_['DB_HOST'], 0, strpos( $nfw_['DB_HOST'], ':') ); $port_or_socket = substr( $port_or_socket, 1 ); if ( 0 !== strpos( $port_or_socket, '/') ) { $nfw_['port'] = intval( $port_or_socket ); $maybe_socket = strstr( $port_or_socket, ':'); if ( ! empty( $maybe_socket ) ) { $nfw_['socket'] = substr( $maybe_socket, 1 ); } } else { $nfw_['socket'] = $port_or_socket; } } } // ===================================================================== 2023-05-16 // Handle HTTP response headers. function nfw_response_headers() { if ( defined('NFW_CUSTHEADERS') ) { nfw_custom_headers(); } if (! defined('NFW_RESHEADERS') ) { return; } $NFW_RESHEADERS = NFW_RESHEADERS; // NFW_RESHEADERS: // 0000000000 // ||||||||||_ SameSite[0-2] // |||||||||__ Referrer-Policy [0-8] // ||||||||___ Content-Security-Policy (backend) [0-1] // |||||||____ Content-Security-Policy (frontend) [0-1] // ||||||_____ Strict-Transport-Security (includeSubDomains) [0-1] // |||||______ Strict-Transport-Security [0-4] // ||||_______ X-XSS-Protection [0-3] // |||________ X-Frame-Options [0-2] // ||_________ X-Content-Type-Options [0-1] // |__________ HttpOnly cookies [0-1] // Force HttpOnly and/or SameSite cookie if (! empty( $NFW_RESHEADERS[0] ) || ! empty( $NFW_RESHEADERS[9] ) ) { $rewrite = []; // Parse all response headers foreach (headers_list() as $header) { // Ignore it if it is not a cookie if ( strpos( $header, 'Set-Cookie:' ) === false ) { continue; } $extra = ''; // HttpOnly if (! empty( $NFW_RESHEADERS[0] ) ) { // Does it have the HttpOnly flag on if ( stripos( $header, '; HttpOnly') === false) { $extra .= '; HttpOnly'; } } // SameSite if (! empty( $NFW_RESHEADERS[9] ) ) { // Lax if ( $NFW_RESHEADERS[9] == 1 && stripos( $header, '; SameSite=Lax' ) === false ) { $extra .= '; SameSite=Lax'; // Strict } elseif ( $NFW_RESHEADERS[9] == 2 && stripos( $header, '; SameSite=Strict' ) === false ) { $extra .= '; SameSite=Strict'; } } // Save cookie $rewrite[] = "{$header}{$extra}"; } // Shall we rewrite cookies if (! empty( $rewrite ) ) { // Remove all original cookies header_remove('Set-Cookie'); foreach( $rewrite as $cookie ) { // Inject ours instead header( $cookie, false ); } } } if (! empty( $NFW_RESHEADERS[1] ) ) { header('X-Content-Type-Options: nosniff'); } if (! empty( $NFW_RESHEADERS[2] ) ) { if ($NFW_RESHEADERS[2] == 1) { header('X-Frame-Options: SAMEORIGIN'); } else { header('X-Frame-Options: DENY'); } } if ( empty( $NFW_RESHEADERS[3] ) ) { header('X-XSS-Protection: 0'); } elseif ( $NFW_RESHEADERS[3] == 1 ) { header('X-XSS-Protection: 1; mode=block'); } elseif ( $NFW_RESHEADERS[3] == 2 ) { header('X-XSS-Protection: 1'); } if (! empty( $NFW_RESHEADERS[6] ) && strpos($_SERVER['SCRIPT_NAME'], '/wp-admin/') === FALSE ) { header('Content-Security-Policy: ' . CSP_FRONTEND_DATA); } if (! empty( $NFW_RESHEADERS[7] ) && strpos($_SERVER['SCRIPT_NAME'], '/wp-admin/') !== FALSE ) { header('Content-Security-Policy: ' . CSP_BACKEND_DATA); } if (! empty( $NFW_RESHEADERS[8] ) ) { if ( $NFW_RESHEADERS[8] == 1 ) { $rf = 'no-referrer'; } elseif ( $NFW_RESHEADERS[8] == 2 ) { $rf = 'no-referrer-when-downgrade'; } elseif ( $NFW_RESHEADERS[8] == 3 ) { $rf = 'origin'; } elseif ( $NFW_RESHEADERS[8] == 4 ) { $rf = 'origin-when-cross-origin'; } elseif ( $NFW_RESHEADERS[8] == 5 ) { $rf = 'strict-origin'; } elseif ( $NFW_RESHEADERS[8] == 6 ) { $rf = 'strict-origin-when-cross-origin'; } elseif ( $NFW_RESHEADERS[8] == 7 ) { $rf = 'same-origin'; } else { $rf = 'unsafe-url'; } header("Referrer-Policy: $rf"); } // Stop here if no more headers if ( empty($NFW_RESHEADERS[4] ) ) { return; } // We don't send HSTS headers over HTTP if (! defined('NFW_IS_HTTPS') ) { nfw_is_https(); } if ( NFW_IS_HTTPS == false ) { return; } if ($NFW_RESHEADERS[4] == 1) { // 1 month $max_age = 'max-age=2628000'; } elseif ($NFW_RESHEADERS[4] == 2) { // 6 months $max_age = 'max-age=15768000'; } elseif ($NFW_RESHEADERS[4] == 3) { // 12 months $max_age = 'max-age=31536000'; } elseif ($NFW_RESHEADERS[4] == 4) { // Send an empty max-age to signal the UA to // cease regarding the host as a known HSTS Host $max_age = 'max-age=0'; } else { // 24 months $max_age = 'max-age=63072000'; } if (! empty( $NFW_RESHEADERS[5] ) ) { if ( $NFW_RESHEADERS[5] == 1 ) { $max_age .= '; includeSubDomains'; } elseif ( $NFW_RESHEADERS[5] == 2 ) { $max_age .= '; preload'; } else { $max_age .= '; includeSubDomains; preload'; } } header('Strict-Transport-Security: '. $max_age); } // ===================================================================== 2023-05-16 function nfw_custom_headers() { $headers = json_decode( NFW_CUSTHEADERS, true ); if (! empty( $headers ) ) { foreach( $headers as $key => $value ) { header( "$key: $value" ); } } } // ===================================================================== // EOF