str_replace("'", "|x|", $_SERVER['REQUEST_URI']); * 2018-06-04 -- SLM - Added omission for redirect if the calling server is a PAG * 2018-08-14 -- SLM - Updated security files to have `.log` as an extension * 2021-03-10 -- SLM - Stop double encoded URL i.e. `../` --> `%252e%252e%252f`; `%253C`; `%253E` * 2022-04-01 -- SLM - Remove all <> from GET's for %3C `<` and %3E `>` * 2022-04-01 -- SLM - Remove any open/close on the URI MRS PEN test 07-03-2018 * 2022-08-26 -- SLM - Remove any UTF8 encoding from the URL for the SSL redirect * 2022-08-26 -- SLM - Add a Dynamic URL generator -- https://dev-42-glowm_www4.cms10.ama.uk.com --> dev-[VERSION]-[SITENAME].[SERVER].ama.uk.com * 2023-01-22 -- SLM - Add NECRO to the system; Line 2 - 2023-03-15 -- IB * 2023-05-11 -- IB - Added new log function and more filters for url security * 2023-09-29 -- SLM - Reduce PHP Errors -- Changed `root_bb_real_escape_string($_SERVER['HTTP_USER_AGENT'])` for * `htmlspecialchars($_SERVER['HTTP_USER_AGENT'])` within the fn `bootstrap_mail_withauth` * 2023-10-24 -- SLM - Added `date("Y-m-d").` to the Security logging filename * 2024-04-16 -- SLM - Check if the query is an array, if so, null the var * 2024-04-23 -- SLM - Add fn `getallheaders` for PHP-FPM setup on new Servers * 2024-04-23 -- SLM - 2.00 - Generalise all bootloader to version 2.0 * 2024-04-29 -- SLM - 2.01 - Updatede `http_sanitizer` to `http_sanitizer_log`, so to file contents and for MARK II to monitor * 2024-10-08 -- IB - Added date prefix to url security logs * 2025-04-08 -- SLM - Added option for `web50` to be added to `Dynamic URL generator` * 2026-04-25 -- SLM - Added Virgin and local ip to stop any rediredt when proofing */ ## ## Setup contacts ## define("_INDEX_CALL_CHECK", "okay-to-go"); date_default_timezone_set('UTC'); ## ## Top Level Blocker ## include("/var/www/cms/_sys/http_necro/http_necro.php"); ## ## Error Listing ## $_SESSION['error']['001'] = "001 - Connect Error - Primary bootstrap"; $_SESSION['error']['002'] = "002 - Select Error - Strata Database controller"; $_SESSION['error']['003'] = "003 - Query Error - DN Controller"; $_SESSION['error']['004'] = "004 - Connect Error - Access to Site Name not found. Check for OLD pwd"; $_SESSION['error']['005'] = "005 - Select Error - Site Name"; $_SESSION['error']['006'] = "006 - Connect Error to `globals` [inc_db]"; $_SESSION['error']['007'] = "007 - Sorry this IP has been blocked:"; ## ## Function ## 2014-05-13 - SLM ## 2017-11-21 - SLM - update to include alternative mailing address function bootstrap_mail_withauth($mail_subject, $mail_body, $mail_address="errorlist@ama.uk.com") { ## 2017-11-21 - SLM - Added `$mail_address` include_once "/var/www/cms/_sys/smtp/class.phpmailer.php"; include_once "/var/www/cms/_sys/smtp/class.smtp.php"; $mail_body .= "

User: {$_SESSION['current_username']}
SITE NAME: {$_SESSION['_SITE_NAME']}  CMS: {$_SESSION["CMS_VERSION"]}
SQL Server: {$_SESSION['_sql_server']}  WEB Server: {$_SESSION['_WEB_SERVER']}
Page No: {$_SESSION['current_page']}  URI: {$_SERVER['REQUEST_URI']}
SESSID: ".session_id()."  IP: {$_SERVER['REMOTE_ADDR']}


HTTP: {$_SERVER[HTTP_HOST]}{$_SERVER['REQUEST_URI']}

Agent
".htmlspecialchars($_SERVER['HTTP_USER_AGENT'])."&host={}&uri={$_SERVER['REQUEST_URI']}
\$_SERVER
".print_r($_SERVER, true)."

\$_POST
".print_r($_POST, true)."

\$_GET
".print_r($_GET, true)."

"; $mail = new PHPMailer(); $mail->IsSMTP(); // send via SMTP $mail->SMTPAuth = true; // turn on SMTP authentication $mail->Host = __AMA_MAIL_SERVER_HST__; $mail->Username = __AMA_MAIL_SERVER_USR__; $mail->Password = __AMA_MAIL_SERVER_PWD__; $mail->From = "bootstrap@ama.uk.com"; $mail->FromName = "{$_SESSION["CMS_VERSION"]}.{$_SERVER[HTTP_HOST]} -- Bootstrap"; $mail->AddAddress($mail_address); ## 2017-11-21 - SLM - Updated to allow alternatives $mail->Subject = $mail_subject; $mail->WordWrap = 100; $mail->IsHTML($IsHTML); $mail->Body = $mail_body; $mail->ContentType = "text/html"; $mail->Send(); } ## 2024-04-23 -- SLM -- Add fn `getallheaders` for PHP-FPM setup on new Servers if (!function_exists('getallheaders')) { /** * Get all HTTP header key/values as an associative array for the current request. * @return string[string] The HTTP header key/value pairs. */ function getallheaders() { $headers = array(); $copy_server = array( 'CONTENT_TYPE' => 'Content-Type', 'CONTENT_LENGTH' => 'Content-Length', 'CONTENT_MD5' => 'Content-Md5', ); foreach ($_SERVER as $key => $value) { if (substr($key, 0, 5) === 'HTTP_') { $key = substr($key, 5); if (!isset($copy_server[$key]) || !isset($_SERVER[$key])) { $key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $key)))); $headers[$key] = $value; } } elseif (isset($copy_server[$key])) { $headers[$copy_server[$key]] = $value; } } if (!isset($headers['Authorization'])) { if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) { $headers['Authorization'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION']; } elseif (isset($_SERVER['PHP_AUTH_USER'])) { $basic_pass = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : ''; $headers['Authorization'] = 'Basic ' . base64_encode($_SERVER['PHP_AUTH_USER'] . ':' . $basic_pass); } elseif (isset($_SERVER['PHP_AUTH_DIGEST'])) { $headers['Authorization'] = $_SERVER['PHP_AUTH_DIGEST']; } } return $headers; } } ## ## Error Pages ## function http_404($string=NULL) { header("CMS-Powered-By: AMA DataSet Limited - (www.ama.uk.com)"); header("CMS-Version: CMS Strata (c)2003-".date("Y")); header("Content-Type:text/html; charset=ISO-8859-1,utf-8;q=0.7,*;q=0.3", true, 404); header("AMA-XSS-protection:failed", true, 404); header("HTTP/1.0 404 Not Found"); $html = file_get_contents("404.html"); echo eval("?>{$html}{$html}{$string}"; ## Log Error and email $file = __PATH_LOG_SECURITY__.date("Y-m-d")."--http_500--{$_SERVER['HTTP_HOST']}.log"; $date = date("Y-m-d H-i-s"); $text .= "
";
    $text .= "{$date} {$_SERVER['REQUEST_METHOD']} IP:{$_SERVER['REMOTE_ADDR']} URL:{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}\n";
    $text .= "\$_SESSION['_SQL_SERVER']:'{$_SESSION['_SQL_SERVER']}'\n";
    $text .= "\$_SESSION['_SQL_SERVER_CMS']:'{$_SESSION['_SQL_SERVER_CMS']}'\n";
    $text .= "\$_SESSION['_SITE_NAME']:'{$_SESSION['_SITE_NAME']}'\n";
    $text .= "\$_SESSION['_SQL_SERVER_PWD']:'{$_SESSION['_SQL_SERVER_PWD']}'\n";
    $text .= "\$_SESSION['_SQL_TYPE']:'{$_SESSION['_SQL_TYPE']}'\n";
    $text .= "__MYSQL_PORT__:'".__MYSQL_PORT__."'\n";
    $text .= "message:{$string}\n";
    $text .= "mysql_error:".root_bb_error();
    $text .= "\n\n";
    $text .= "
"; file_put_contents($file, $text, FILE_APPEND); bootstrap_mail_withauth($string, $text); exit; } function http_sanitizer_log($string=NULL) { ## Build filename $filePathName = __PATH_LOG_SANITIZER__.date("Y-m-d")."-"."{$_SERVER['HTTP_HOST']}.log"; ## Create File with correct perms if(!file_exists($filePath)) { touch($filePathName); chmod($filePathName, 0660); chown($filePathName, 33); chgrp($filePathName, 5001); } ## Build contents $line = str_pad( $_SERVER['REMOTE_ADDR'], 16)."| "; $line .= str_pad( $_SERVER['SERVER_PORT'], 4, " ")."| "; $line .= str_pad( $_SERVER['REQUEST_METHOD'], 5, " ")."| "; ### $line .= str_pad( $_SERVER['HTTP_HOST'], 32, " ")."| "; $line .= str_pad( $string, 48, " ")."| "; $line .= $_SERVER['REQUEST_URI']."| "; $line .= $_SERVER['HTTP_USER_AGENT']; ## Save all feeds file_put_contents($filePathName, date("Y-m-d\TH:i:s")." | ".$line."\n", FILE_APPEND); } ## 2023-05-11 - IB -- added for pen test function url_replacement_log($matched_string, $URL){ $dateTime = date("Y-m-d"); $text = date("Y-m-d H:i:s")." - URL SECURITY ISSUE: matched - {$matched_string} : URL - {$URL} : IP - {$_SERVER['REMOTE_ADDR']}\n"; file_put_contents(__PATH_LOG_SECURITY__."{$dateTime}--BL-URL-replacement--".$_SERVER['HTTP_HOST'].".log", $text, FILE_APPEND); } ## ## Bring in Config File ## global $_SITE_INDEX, $_SQL_SERVER, $_PAG_SERVER, $_WEB_SERVER, $SERVER_NAME; ## Legacy include_once("/var/www/cms/_config.php"); ## Load Config Details ## Deafault the Error logs prior to the SITENAME $dateTime = date("Y-m-d"); $path = __PATH_LOG_PHP_ERROR__."{$dateTime}--BOOTLOADER.log"; ini_set("error_log", __PATH_LOG_PHP_ERROR__."{$dateTime}--BOOTLOADER.log"); include_once("/var/www/cms/_sys/sql_blackbox/root.php"); ## Load SQL commands for Bootloader include_once("/var/www/cms/_sys/error_handler.php"); ## Load PHP Error Logger $_SESSION['_SQL_SERVER'] = $_SQL_SERVER; ## 2011-02-21 - SLM -- Default SQL, used to get DN controller (removed web20.ama.uk.com) $_SESSION['_SQL_SERVER_CMS'] = $_SQL_SERVER_CMS; $_SESSION['_SQL_SERVER_PWD'] = $_SQL_SERVER_PWD; ## 2011-02-21 - SLM -- Default SQL since place PWD $_SESSION['_PAG_SERVER'] = $_PAG_SERVER; ## Default added 2008-10-21 --- London 9 pagination server $_SESSION['_WEB_SERVER'] = $_WEB_SERVER; ## 2011-02-21 - SLM -- Change for the working server, WEBXX ## ## Check for SQL Injection and XSS ## ## 2021-03-10 -- SLM - Stop double encoded URL i.e. `../` --> `%252e%252e%252f`; `%253C`; `%253E` if(strpos( strtoupper($_SERVER['REQUEST_URI']), "%252E%252E%252F")) {$security_error='Double encoded `../`';} if(strpos( strtoupper($_SERVER['REQUEST_URI']), "%253C")) {$security_error='Double encoded `<`';} if(strpos( strtoupper($_SERVER['REQUEST_URI']), "%253E")) {$security_error='Double encoded `>`';} $_SERVER['REQUEST_URI'] = str_replace("+", "%2B", $_SERVER['REQUEST_URI']); ## 2017-06-29 - SLM -- Convert `+` in URI to URL encode %2B $_SERVER['REQUEST_URI'] = urldecode($_SERVER['REQUEST_URI']); ## 2021-03-18 - SLM -- Remove all <> from GET's for %3C `<` and %3E `>` ## e.g. https://dev-mrs.dev10.ama.uk.com/?test=%3Cimg%20src%3da%20onerror%3dalert(123)%3E ## 2022-03-30 - SLM Remove all <> from KEY for %3C `<` and %3E `>` and rebuild REQUEST_URI ## e.g. https://www.research-live.com/?%22%3e%3ciYaJs%3c=1 ## 2024-06-24 - SLM -- Check for an Ajax call, allow `parameters` since this is an array foreach( $_GET AS $name => $value) { ## 2024-04-16 - SLM -- Check if the query is an array, if so null the var if(is_array($value)) { ## Check that is not from AMA Ajax if($name <> 'parameters') unset($_GET[$name]); } else { $value = urldecode($value); if(preg_match("#<(.*?)>#", $value)) { $valueNew = preg_replace("#<(.*?)>#", "$1", $value); http_sanitizer_log("{$name}={$value}->{$valueNew}"); $_GET[$name] = $valueNew; } } } ## $_SERVER['REQUEST_URI'] = str_replace("'", "|x|", $_SERVER['REQUEST_URI']); ## 2015-12-09 - SLM -- Remove Quote -- 2017-11-21 - SLM -- Removed ## 2018-03-22 Line 1; 2022-04-01 Line 2 - SLM -- Remove any open/close on the URI MRS PEN test 07-03-2018 $_SERVER['REQUEST_URI'] = preg_replace("#<(.*?)>#", "$1", $_SERVER['REQUEST_URI']); ## 2023-05-11 - IB -- Added for pen test if(preg_match("#<|>#", $_SERVER['REQUEST_URI'])){ url_replacement_log("#<|>#", $_SERVER['REQUEST_URI']); $_SERVER['REQUEST_URI'] = preg_replace("#<|>#", "", $_SERVER['REQUEST_URI']); } ## 2023-05-11 - IB -- Added for pen test if(preg_match("#'#", $_SERVER['REQUEST_URI'])){ url_replacement_log("#'#", $_SERVER['REQUEST_URI']); $_SERVER['REQUEST_URI'] = preg_replace("#'#", "", $_SERVER['REQUEST_URI']); } $boot_inj_URI = strtoupper(urldecode($_SERVER['REQUEST_URI'])); $boot_inj_URI_strip = str_replace(" ", "", $boot_inj_URI); if(strpos($boot_inj_URI_strip, 'INFORMATION_SCHEMA')) {$security_error='INFORMATION_SCHEMA';} else if(strpos($boot_inj_URI_strip, 'DELAY(')) {$security_error='DELAY(';} if(strpos($boot_inj_URI_strip, 'SLEEP(')) {$security_error='SLEEP(';} if(strpos($boot_inj_URI_strip, 'CONCAT(')) {$security_error='CONCAT(';} if(strpos($boot_inj_URI_strip, 'BENCHMARK(')) {$security_error='BENCHMARK(';} if(strpos($boot_inj_URI_strip, 'UNION/*')) {$security_error='UNION/*';} if(strpos($boot_inj_URI_strip, 'SELECT/*')) {$security_error='SELECT/*';} #if(strpos($boot_inj_URI, 'DELAY ')) {$security_error='DELAY ';} #if(strpos($boot_inj_URI, 'WAITFOR ')) {$security_error='WAITFOR ';} if(strpos($boot_inj_URI, 'SELECT ')) {$security_error='SELECT ';} if(strpos($boot_inj_URI, 'UNION ')) {$security_error='UNION *';} if(strpos($boot_inj_URI, ' in `cmsXX.ama.uk.com` ## if(preg_match("#^dev-([0-9]{2})(web50)?-([^\.-]+)(-php8)?\.cms\.ama\.uk\.com$#", $SERVER_NAME, $matches)) { ## ## Check Pattern URL ## $matches[2] = $matches[2]=="" ? "":".{$matches[2]}"; $row['f_version'] = "cms-0.9.{$matches[1]}-alpha{$matches[2]}"; $row['f_site_name'] = $matches[3]; $row['f_page'] = "index.php"; ## Flag that we are using the DN Controller $cms_controller = true; } else { ## ## Check DN controller ## $q = "SELECT * FROM `t_dn_controller` WHERE `f_url_match`='{$SERVER_NAME}' AND `f_omit`='0' AND `f_removed`='0'"; $r = root_bb_query($q) or http_500($_SESSION['error']['003']); if (root_bb_num_rows($r) == '1') { $row = root_bb_fetch_assoc($r); ## 2012-03-10 -- Add click to system ## 2015-02-01 -- Updated to take into account click timestamp and click web server ## 2015-04-08 -- Ignore extensions .js .css .jpg .png .gif .pdf .ico if(!preg_match("#(.js|.css|.jpg|.png|.gif|.pdf|.ico)$#", $_SERVER['REQUEST_URI'], $m)) { root_bb_query(" UPDATE `t_dn_controller` SET `f_clicks` = `f_clicks`+1, `f_clicks_hour` = `f_clicks_hour`+1, `f_clicks_day` = `f_clicks_day`+1, `f_clicks_week` = `f_clicks_week`+1, `f_clicks_month` = `f_clicks_month`+1, `f_clicks_year` = `f_clicks_year`+1, `f_click_timestamp` = '".date("Y-m-d H:i:s")."', `f_click_web_server`= '{$_WEB_SERVER}' WHERE `f_id`='{$row['f_id']}' "); } ## 2012-03-10 -- Check for redirect -- SLL, if active and we enter as HTTP, force to HTTPS ## 2016-06-30 -- SLM - Added redirect as 301 rather than the default 302 if(($row['f_redirect'] <> "") && ($row['f_redirect'] <> $SERVER_NAME)) { if(strstr($row['f_redirect'], "http")) header("Location: {$row['f_redirect']}{$_SERVER['REQUEST_URI']}", TRUE, 301); else header("Location: http://{$row['f_redirect']}{$_SERVER['REQUEST_URI']}", TRUE, 301); exit; } ## 2011-05-07 -- Check for SSL, if active and we enter as HTTP, force to HTTPS ## 2016-06-30 -- SLM - Added redirect as 301 rather than the default 302 ## 2017-03-31 -- SLM - Add exetension `php` to omittion of SSL redirect ## 2018-06-04 -- SLM - Added omission for redirect if the calling server is a PAG. Due to GFG and its CERT ## 2026-04-25 -- SLM - Added Virgin and local ip to stop any rediredt when proofing if( !preg_match("#81\.142\.231\.#", $_SERVER['REMOTE_ADDR']) && ## ip range for BT !preg_match("#213\.48\.240\.#", $_SERVER['REMOTE_ADDR']) && ## ip range for Virgin !preg_match("#192\.168\.0\.#", $_SERVER['REMOTE_ADDR']) ){ ## ip range for Local if($row['f_ssl'] == 1 && $_SERVER['HTTPS'] != "on") { ## 2013-12-03 - SLM -- Check for extension, skip if image or PDF $extension = strtolower(array_pop(explode('.',$_SERVER['REQUEST_URI']))); ## Get extension $extension_exception = array("jpg", "png", "gif", "pdf", "php"); if(!in_array($extension, $extension_exception)) { session_regenerate_id(); ## 2017-09-12 -- SLM -- added to destroy SESSID when redirct from HTTP --> HTTPS header("Referer: ".$_SERVER['HTTP_REFERER']); $url = utf8_decode($_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']); ## 2022-08-26 - SLM -- Remove any UTF8 encoding from the URL for the SSL redirect header("Location: https://{$url}", TRUE, 301); exit; } } } ## Validate findings and process DN request if($row['f_site_name'] && $row['f_version'] && $row['f_page']) $cms_controller = true; } } ## ## Okay, do we have a DN Controller ## if($cms_controller) { ## Get SQL server to connect to if($row['f_db_server'] == "") $_SESSION['_SQL_SERVER'] = $_SQL_SERVER = "localhost"; else $_SESSION['_SQL_SERVER'] = $_SQL_SERVER = $row['f_db_server']; ## 2015-11-26 - SLM -- Check what type of SQL we are to use for the SITE_NAME, default `__SQL_TYPE_DEFAULT__` if($row['f_site_sql_type'] == "") $_SESSION['_SQL_TYPE'] = __SQL_TYPE_DEFAULT__; else $_SESSION['_SQL_TYPE'] = $row['f_site_sql_type']; ## Get SiteName and redirect PHP error log $_SESSION['_SITE_NAME'] = $_SITE_NAME = $row['f_site_name']; ## 2011-04-23 - SLM -- Added ## Redirect the error logs to the SITENAME ini_set("error_log", __PATH_LOG_PHP_ERROR__."{$dateTime}--{$_SESSION['_SITE_NAME']}.log"); ## 2015-08-27 - SLM -- Added ## Reconnect to the SITENAME and select the working DB root_bb_connect($_SESSION['_SQL_SERVER'], $_SESSION['_SITE_NAME'], $_SESSION['_SQL_SERVER_PWD']) or http_500($_SESSION['error']['004']); root_bb_select_db($_SESSION['_SITE_NAME']) or http_500($_SESSION['error']['005']); ## Get Paginator server from dn controller if($row['f_pg_server'] <> $_PAG_SERVER && trim($row['f_pg_server'])) { $_SESSION['_PAG_SERVER'] = $_PAG_SERVER = $row['f_pg_server']; ## Added SLM 2008-10-21 } ## 2011-02-21 - SLM stamp which version is required, no need to update CMS's index file ## 2012-01-19 - SLM dynamic verion switching if(isset($_SESSION["CMS_VERSION"]) && $row['f_fg_absolute_version'] <> 1) { $row['f_version'] = "cms-".$_SESSION["CMS_VERSION"]; } else { $_SESSION["CMS_VERSION"] = str_replace("cms-", "", $row['f_version']); } ## ## Check for SCC abuse ## if(!($_SESSION['user_access_level'] > 0) && isset($_POST['SCC'])) { bootstrap_mail_withauth($_SERVER['REMOTE_ADDR']." -- SCC Bootstrap Error", "Posted SCC without 'user_access_level'"); unset($_POST['SCC']); } ## ## Add AMA Signature ## header("X-FRAME-OPTIONS: SAMEORIGIN"); header('X-Content-Type-Options: nosniff'); header('X-XSS-Protection: 1; mode=block'); header("CMS-Powered-By: AMA DataSet Limited - (www.ama.uk.com)"); header("CMS-Version: CMS Strata (c)2003-".date("Y")." {$row['f_version']}-{$_WEB_SERVER}"); header("CMS-XSS-protection:okay"); header("Content-Security-Policy: frame-ancestors 'self'"); #IB 2024-11-04 new setting to stop xframe scripting ## ## Draw the page in ## if(is_file("cms/{$row['f_version']}/{$row['f_page']}")) { include("cms/{$row['f_version']}/{$row['f_page']}"); } else { echo("Missing CMS version `{$row['f_version']}`"); } } ## ## If we do not locate it in the db, then check old select ## if(!$cms_controller) { switch ($_SERVER['SERVER_NAME']) { ## PHPINFO case "phpinfo.".__AMA_SERVER__.".ama.uk.com": phpinfo(); break; default: http_404("We seem to have no site name for this domain"); exit; } } ?>