• Модуль: security
  • Путь к файлу: ~/bitrix/modules/security/classes/general/redirect.php
  • Класс: CSecurityRedirect
  • Вызов: CSecurityRedirect::BeforeLocalRedirect
static function BeforeLocalRedirect(&$url, $skip_security_check)
{
	// ToDo: refactoring candidate

	//This define will be used on buffer end handler
	if(!defined("BX_SECURITY_LOCAL_REDIRECT"))
		define("BX_SECURITY_LOCAL_REDIRECT", true);

	$kernelSession = BitrixMainApplication::getInstance()->getKernelSession();
	if ($kernelSession->isStarted() && $kernelSession->has("LOCAL_REDIRECTS"))
	{
		if($kernelSession["LOCAL_REDIRECTS"]["C"] == 0 && $kernelSession["LOCAL_REDIRECTS"]["R"] == '')
			$kernelSession["LOCAL_REDIRECTS"]["R"] = ($_SERVER["HTTP_REFERER"] ?? '');

		$kernelSession["LOCAL_REDIRECTS"]["C"]++;
	}
	else
	{
		$kernelSession["LOCAL_REDIRECTS"] = array("C" => 1, "R" => ($_SERVER["HTTP_REFERER"] ?? ''));
	}

	if($skip_security_check)
		return;

	/** global CMain $APPLICATION */
	global $APPLICATION;

	$good = true;
	$url = str_replace("xe2x80xae", "", $url);
	$url_l = str_replace(array("r", "n"), "", $url);

	//In case of absolute url will check if server to be redirected is our
	$bSkipCheck = false;
	if(preg_match('~^(?:http|https)://(.*?)(\\|/|?|#|$|%252f|%2f)~iD', $url_l, $arMatch))
	{
		if(defined("BX24_HOST_NAME"))
		{
			$arSite = array(
				"SERVER_NAME" => BX24_HOST_NAME,
				"DOMAINS" => ""
			);
		}
		elseif(defined("SITE_ID"))
		{
			$rsSite = CSite::GetByID(SITE_ID);
			$arSite = $rsSite->Fetch();
		}
		else
		{
			$arSite = false;
		}

		if(!$bSkipCheck && $arSite && $arSite["SERVER_NAME"])
		{
			$bSkipCheck = $arMatch[1] === $arSite["SERVER_NAME"];
		}

		if(!$bSkipCheck && $arSite && $arSite["DOMAINS"])
		{
			$arDomains = explode("n", str_replace("r", "n", $arSite["DOMAINS"]));
			foreach($arDomains as $domain)
			{
				$domain = trim($domain, " tnr");
				if($domain <> '')
				{
					if($domain === mb_substr($arMatch[1], -mb_strlen($domain)))
					{
						$bSkipCheck = true;
						break;
					}
				}
			}
		}

		if(!$bSkipCheck)
		{
			$host = COption::GetOptionString("main", "server_name", "");
			$bSkipCheck = $host && $arMatch[1] === $host;
		}

		if (strpos(strtolower($arMatch[2]), '%2f') === 0)
		{
			$good = false;
			$bSkipCheck = false;
		}
	}

	if(!$bSkipCheck && preg_match("/^(http|https|ftp):\/\//i", $url_l))
	{
		if($kernelSession["LOCAL_REDIRECTS"]["C"] > 1)
			$REFERER_TO_CHECK = $kernelSession["LOCAL_REDIRECTS"]["R"];
		else
			$REFERER_TO_CHECK = ($_SERVER["HTTP_REFERER"] ?? '');

		if($good && COption::GetOptionString("security", "redirect_referer_check") == "Y")
		{
			$good &= $REFERER_TO_CHECK <> '';
		}

		if($good && $REFERER_TO_CHECK <> '' && COption::GetOptionString("security", "redirect_referer_site_check") == "Y")
		{
			$valid_site = ($APPLICATION->IsHTTPS()? "https://": "http://").$_SERVER['HTTP_HOST']."/";
			$good &= mb_strpos($REFERER_TO_CHECK, $valid_site) === 0;
		}

		if($good && COption::GetOptionString("security", "redirect_href_sign") == "Y")
		{
			$sid = static::GetSeed();
			$good &=  static::Sign($sid, $url) === $_GET["af"];
		}

		if(!$good)
		{
			global $APPLICATION;

			if(COption::GetOptionString("security", "redirect_log") == "Y")
				CSecurityEvent::getInstance()->doLog(
						"SECURITY",
						"SECURITY_REDIRECT",
						$APPLICATION->GetCurPage(),
						$url
				);

			if(COption::GetOptionString("security", "redirect_action") == "show_message_and_stay")
			{
				$mess = COption::GetOptionString("security", "redirect_message_warning_".LANGUAGE_ID);
				if($mess == '')
					$mess = COption::GetOptionString("security", "redirect_message_warning");
				$charset = COption::GetOptionString("security", "redirect_message_charset");
				if($mess == '')
				{
					$mess = CSecurityRedirect::GetDefaultMessage();
					$charset = LANG_CHARSET;
				}
				$html_mess = str_replace("+", "+", htmlspecialcharsbx($mess));

				//Convert to site encoding
				if (!defined("BX_UTF") && defined("LANG_CHARSET"))
				{
					$url_c = BitrixMainTextEncoding::convertEncoding($url, "UTF-8", LANG_CHARSET);
				}
				else
				{
					$url_c = $url;
				}

				if (preg_match('~^(http|https)(://)(.*?)(?:\\|/|?|#|$)~iD', $url_c, $arMatch))
				{
					$converter = CBXPunycode::GetConverter();
					$url_e = $arMatch[1].$arMatch[2].$converter->Encode($arMatch[3]).mb_substr($url_c, mb_strlen($arMatch[1].$arMatch[2].$arMatch[3]));
				}
				else
				{
					$url_e = $url;
				}

				$url = htmlspecialcharsbx($url);
				$html_url = ''.htmlspecialcharsEx($url_c).'';
				$html_mess = str_replace("#URL#", $html_url, $html_mess);
				CHTTP::SetStatus("404 Not Found");
				header('X-Frame-Options: DENY');
				header('X-Robots-Tag: noindex, nofollow');
	?>