8 const DEFAULT_REQUEST_ORDER =
"GP";
9 private $doBlock =
false;
11 private $requestFilter =
null;
13 private $serverFilter =
null;
16 private $splittingChar =
'';
17 protected $defaultAuditors =
array(
18 array(
'type' =>
'XSS',
'class' =>
'Bitrix\Security\Filter\Auditor\Xss'),
19 array(
'type' =>
'SQL',
'class' =>
'Bitrix\Security\Filter\Auditor\Sql'),
20 array(
'type' =>
'PHP',
'class' =>
'Bitrix\Security\Filter\Auditor\Path')
25 if(isset($customOptions[
"stop"]))
27 $this->doBlock = $customOptions[
"stop"];
31 $this->doBlock = (\COption::getOptionString(
"security",
"filter_stop") ===
'Y');
34 $this->requestFilter =
new Filter\Request($customOptions);
35 $this->serverFilter =
new Filter\Server($customOptions);
36 $this->context = \Bitrix\Main\Application::getInstance()->getContext();
37 $this->splittingChar = $char;
40 public static function OnBeforeProlog()
42 if (CSecuritySystemInformation::isCliMode())
50 && self::currentUserHaveRightsForSkip()
52 !isset($_POST[
'____SECFILTER_CONVERT_JS'])
53 || !$_POST[
'____SECFILTER_CONVERT_JS']
67 public static function IsActive()
73 $event[
"TO_MODULE_ID"] ==
"security"
74 &&
$event[
"TO_CLASS"] ==
"CSecurityFilter"
88 public static function SetActive($bActive =
false)
92 if(!CSecurityFilter::IsActive())
94 registerModuleDependences(
"main",
"OnBeforeProlog",
"security",
"CSecurityFilter",
"OnBeforeProlog",
"5");
95 registerModuleDependences(
"main",
"OnEndBufferContent",
"security",
"CSecurityXSSDetect",
"OnEndBufferContent", 9999);
100 if(CSecurityFilter::IsActive())
102 unregisterModuleDependences(
"main",
"OnBeforeProlog",
"security",
"CSecurityFilter",
"OnBeforeProlog");
103 unregisterModuleDependences(
"main",
"OnEndBufferContent",
"security",
"CSecurityXSSDetect",
"OnEndBufferContent");
112 public static function GetAuditTypes()
115 "SECURITY_FILTER_SQL" =>
"[SECURITY_FILTER_SQL] ".getMessage(
"SECURITY_FILTER_SQL"),
116 "SECURITY_FILTER_XSS" =>
"[SECURITY_FILTER_XSS] ".getMessage(
"SECURITY_FILTER_XSS"),
117 "SECURITY_FILTER_XSS2" =>
"[SECURITY_FILTER_XSS2] ".getMessage(
"SECURITY_FILTER_XSS"),
118 "SECURITY_FILTER_PHP" =>
"[SECURITY_FILTER_PHP] ".getMessage(
"SECURITY_FILTER_PHP"),
119 "SECURITY_REDIRECT" =>
"[SECURITY_REDIRECT] ".getMessage(
"SECURITY_REDIRECT"),
120 "SECURITY_OTP" =>
"[SECURITY_OTP] ".getMessage(
"SECURITY_OTP"),
129 public static function GetEventsCount($timestampX =
'')
138 public static function OnAdminInformerInsertItems()
145 $setupLink =
'/bitrix/admin/security_filter.php?lang='.LANGUAGE_ID;
146 $WAFAIParams =
array(
147 "TITLE" => getMessage(
"SECURITY_FILTER_INFORM_TITLE"),
149 "FOOTER" =>
'<a href="'.$setupLink.
'">'.getMessage(
"SECURITY_FILTER_INFORM_LINK_TO_SETUP_ON").
'</a>'
154 if (self::IsActive())
157 $days = COption::getOptionInt(
"main",
"event_log_cleanup_days", 7);
160 $timestampX =
ConvertTimeStamp(time()-$days*24*3600+CTimeZone::getOffset());
161 $eventLink =
'/bitrix/admin/event_log.php?set_filter=Y&find_type=audit_type_id&find_audit_type[]=SECURITY_FILTER_SQL&find_audit_type[]=SECURITY_FILTER_XSS&find_audit_type[]=SECURITY_FILTER_XSS2&find_audit_type[]=SECURITY_FILTER_PHP&mod=security&find_timestamp_x_1='.$timestampX.
'&lang='.LANGUAGE_ID;
163 $eventCount = self::getEventsCount($timestampX);
164 if($eventCount > 999)
165 $eventCount = round($eventCount/1000,1).
'K';
168 $descriptionText = getMessage(
"SECURITY_FILTER_INFORM_EVENT_COUNT").
'<a href="'.$eventLink.
'">'.$eventCount.
'</a>';
170 $descriptionText = getMessage(
"SECURITY_FILTER_INFORM_EVENT_COUNT_EMPTY");
172 $WAFAIParams[
"FOOTER"] =
'<a href="'.$setupLink.
'">'.getMessage(
"SECURITY_FILTER_INFORM_LINK_TO_SETUP").
'</a>';
173 $WAFAIParams[
"ALERT"] =
false;
175 $WAFAIParams[
"HTML"] =
'
176<div class="adm-informer-item-section">
177 <span class="adm-informer-item-l">
178 <span class="adm-informer-strong-text">'.getMessage(
"SECURITY_FILTER_INFORM_FILTER_ON").
'</span>
179 <span>'.$descriptionText.
'</span>
186 $WAFAIParams[
"ALERT"] =
true;
188 $WAFAIParams[
"HTML"] =
'
189<div class="adm-informer-item-section">
190 <span class="adm-informer-item-l">
191 <span class="adm-informer-strong-text">'.getMessage(
"SECURITY_FILTER_INFORM_FILTER_OFF").
'</span>
192 <span>'.getMessage(
"SECURITY_FILTER_INFORM_FILTER_ON_RECOMMENDATION",
array(
"#LINK#" => $setupLink)).
'</span>
200 $WAFAIParams[
"TITLE"] .=
" - ".getMessage(
"top_panel_ai_title_err");
201 $WAFAIParams[
"ALERT"] =
true;
202 $WAFAIParams[
"HTML"] = $e->getMessage();
214 public static function ClearTmpFiles()
226 public function testXSS($pValue, $pAction =
"clear")
231 public static function processVar(
array|
string $var)
237 $skip = !CSecurityFilter::IsActive();
250 $auditors =
$instance->getAuditorInstances();
251 $instance->requestFilter->setAuditors($auditors);
253 $array = is_array(
$var) ? [
'data' =>
$var] : [
'data' => [
'key' =>
$var]];
255 $filteredValues =
$instance->requestFilter->filter($array,
false);
256 $filteredValues = $filteredValues[
'data'];
265 return is_array(
$var) ? $filteredValues : ($filteredValues[
'key'] ??
'') ;
268 protected function process()
270 $auditors = $this->getAuditorInstances();
271 $this->requestFilter->setAuditors($auditors);
272 $this->serverFilter->setAuditors($auditors);
273 $this->getHttpRequest()->addFilter($this->requestFilter);
274 $this->context->getServer()->addFilter($this->serverFilter);
276 if ($this->isAuditorsTriggered())
278 if ($this->isSomethingChanged())
280 $this->overrideSuperGlobals();
282 if ($this->currentUserHaveRightsForSkip())
288 $this->doPostProcessActions();
292 protected function getAuditors()
294 $wafConfig = \Bitrix\Main\Config\Configuration::getValue(
"waf");
295 if (is_array($wafConfig) && isset($wafConfig[
'auditors']))
296 return $wafConfig[
'auditors'];
298 return $this->defaultAuditors;
301 protected function getAuditorInstances()
303 $auditors = $this->getAuditors();
305 foreach($auditors as $auditor)
307 if (isset($auditor[
'file']))
309 include_once $auditor[
'file'];
312 $class = $auditor[
'class'];
313 $result[$auditor[
'type']] =
new $class($this->splittingChar);
318 protected function overrideSuperGlobals()
320 self::cleanGlobals();
322 $httpRequest = $this->getHttpRequest();
323 $_GET = $httpRequest->getQueryList()->toArray();
324 $_POST = $httpRequest->getPostList()->toArray();
325 $_COOKIE = $httpRequest->getCookieRawList()->toArray();
326 $_SERVER = $this->context->getServer()->toArray();
328 self::reconstructRequest();
329 self::restoreGlobals();
336 protected function isAuditorsTriggered()
339 $this->requestFilter->isAuditorsTriggered()
340 || $this->serverFilter->isAuditorsTriggered()
347 protected function isSomethingChanged()
350 count($this->requestFilter->getChangedVars()) > 0
351 ||
count($this->serverFilter->getChangedVars()) > 0
358 protected function getChangedVars()
360 return $this->requestFilter->getChangedVars() + $this->serverFilter->getChangedVars();
366 protected function getHttpRequest()
368 return $this->context->getRequest();
374 protected function isBlockNeeded()
376 return $this->doBlock;
382 protected static function currentUserHaveRightsForSkip()
387 return $USER->CanDoOperation(
'security_filter_bypass');
397 protected function blockCurrentUser($ip =
"")
399 if(self::currentUserHaveRightsForSkip())
402 if(!is_string($ip) || $ip ===
"")
405 $rule =
new CSecurityIPRule;
409 $endTimestamp =
ConvertTimeStamp(time()+COption::getOptionInt(
"security",
"filter_duration")*60,
"FULL");
410 $ruleList = $rule->GetList(
array(
"ID"),
array(
413 "=ADMIN_SECTION" =>
"Y",
414 "=NAME" => getMessage(
"SECURITY_FILTER_IP_RULE",
array(
"#IP#" => $ip)),
415 "<=ACTIVE_FROM" => $startTimestamp,
416 "<=ACTIVE_TO" => $endTimestamp,
417 ),
array(
"ID" =>
"DESC"));
418 while ($prevRule = $ruleList->Fetch())
420 if ($rule->Update($prevRule[
'ID'],
array(
"ACTIVE_TO" => $endTimestamp)))
427 $added = $rule->Add(
array(
430 "ADMIN_SECTION" =>
"Y",
431 "NAME" => getMessage(
"SECURITY_FILTER_IP_RULE",
array(
"#IP#" => $ip)),
432 "ACTIVE_FROM" => $startTimestamp,
433 "ACTIVE_TO" => $endTimestamp,
434 "INCL_IPS" =>
array($ip),
435 "INCL_MASKS" =>
array(
"/*"),
445 protected static function getSafetyGlobals()
447 static $safetyVars =
array(
457 "HTTP_GET_VARS" => 1,
458 "HTTP_POST_VARS" => 1,
459 "HTTP_SERVER_VARS" => 1,
460 "HTTP_ENV_VARS" => 1,
461 "HTTP_COOKIE_VARS" => 1,
462 "HTTP_FILES_VARS" => 1,
463 "HTTP_REQUEST_VARS" => 1,
464 "HTTP_SESSION_VARS" => 1,
466 "HTTP_RAW_POST_DATA" => 1,
467 "http_response_header" => 1,
470 "DOCUMENT_ROOT" => 1,
477 protected static function cleanGlobals()
479 $safetyGlobals = self::getSafetyGlobals();
493 protected static function getSuperGlobalArray(
$type)
523 protected static function getRequestOrder()
525 $result = ini_get(
"request_order");
528 $result = ini_get(
"variables_order");
531 $result = self::DEFAULT_REQUEST_ORDER;
536 protected static function reconstructRequest()
538 $systemOrder = static::getRequestOrder();
540 $_REQUEST = self::getSuperGlobalArray($systemOrder[0]);
543 $targetArray = self::getSuperGlobalArray($systemOrder[
$i]);
544 foreach($targetArray as
$k => $v)
551 protected static function restoreGlobals()
553 $safetyGlobals = self::getSafetyGlobals();
556 if(!isset($safetyGlobals[
$key])
568 protected function doPostProcessActions()
571 $this->isBlockNeeded()
572 && $this->blockCurrentUser()
580 protected function showForm()
582 if(!isset($_POST[
'____SECFILTER_CONVERT_JS']) || empty($_POST[
'____SECFILTER_CONVERT_JS']))
587 isset($_GET[
"bx_task_action_request"])
588 && $_GET[
"bx_task_action_request"] ===
"Y"
589 && isset($_GET[
"action"])
590 && $_GET[
"action"] ===
"folder_edit"
594 isset($_GET[
'show_wizard'])
595 && $_GET[
'show_wizard'] ===
"Y"
596 && isset($_POST[
'AJAX_CALL'])
597 && $_POST[
'AJAX_CALL'] ===
"Y"
602 && !empty($_POST[
'q'])
603 && isset($_POST[
'ajax_call'])
604 && $_POST[
'ajax_call'] ===
"y"
607 || defined(
'BX_SECURITY_SHOW_MESSAGE')
610 $this->showTextForm();
614 $this->showAjaxForm();
618 $originalPostVars = $this->getHttpRequest()->getPostList()->toArrayRaw();
619 if (!$originalPostVars)
620 $originalPostVars =
array();
622 $this->showHtmlForm($originalPostVars);
632 protected function showTextForm()
634 echo
"[WAF] ".getMessage(
"SECURITY_FILTER_FORM_SUB_TITLE").
" ".getMessage(
"SECURITY_FILTER_FORM_TITLE").
".";
640 protected function showAjaxForm()
642 echo
'<script>top.BX.closeWait(); top.BX.WindowManager.Get().ShowError(\''.getMessageJS(
"SECURITY_FILTER_FORM_SUB_TITLE").
" ".getMessageJS(
"SECURITY_FILTER_FORM_TITLE").
".".
'\')</script>
';
648 protected function showHtmlForm($originalPostVars = array())
654 <meta http-equiv="Content-Type" content="text/html; charset=<?echo LANG_CHARSET?>" />
655 <meta name="robots" content="none" />
656 <title><?echo getMessage("SECURITY_FILTER_FORM_TITLE")?></title>
657 <link rel="stylesheet" type="text/css" href="/bitrix/themes/.default/adminstyles.css" />
658 <link rel="stylesheet" type="text/css" href="/bitrix/themes/.default/404.css" />
661 <script>if(document.location!=top.location)top.location=document.location;</script>
663 div.description td { font-family:Verdana,Arial,sans-serif; font-size:70%; border: 1px solid #BDC6E0; padding:3px; background-color: white; }
664 div.description table { border-collapse:collapse; }
665 div.description td.head { background-color:#E6E9F4; }
668 <div class="error-404">
669 <table class="error-404" border="0" cellpadding="0" cellspacing="0" align="center">
670 <tbody><tr class="top">
671 <td class="left"><div class="empty"></div></td>
672 <td><div class="empty"></div></td>
673 <td class="right"><div class="empty"></div></td>
676 <td class="left"><div class="empty"></div></td>
679 <table cellpadding="0" cellspacing="0">
681 <td><div class="icon"></div></td>
682 <td><?echo getMessage("SECURITY_FILTER_FORM_SUB_TITLE")?></td>
686 <div class="description">
687 <?echo getMessage("SECURITY_FILTER_FORM_MESSAGE")?><br /><br />
688 <table cellpadding="0" cellspacing="0" witdh="100%">
690 <td class="head" align="center"><?echo getMessage("SECURITY_FILTER_FORM_VARNAME")?></td>
691 <td class="head" align="center"><?echo getMessage("SECURITY_FILTER_FORM_VARDATA")?></td>
693 <?foreach($this->getChangedVars() as $var_name => $str):?>
695 <td><?echo htmlspecialcharsbx($var_name)?></td>
696 <td><?echo htmlspecialcharsbx($str)?></td>
700 <form method="POST" <?if(defined('POST_FORM_ACTION_URI
')):?> action="<?echo POST_FORM_ACTION_URI?>" <?endif?>>
701 <?echo self::formatHiddenFields($originalPostVars);?>
702 <?echo bitrix_sessid_post();?>
703 <input type="submit" name='____SECFILTER_ACCEPT_JS
' value="<?echo getMessage('SECURITY_FILTER_FORM_ACCEPT
')?>" />
704 <input type="submit" name='____SECFILTER_CONVERT_JS
' value="<?echo getMessage('SECURITY_FILTER_FORM_CONVERT
')?>" />
708 <td class="right"><div class="empty"></div></td>
711 <td class="left"><div class="empty"></div></td>
712 <td><div class="empty"></div></td>
713 <td class="right"><div class="empty"></div></td>
727 protected static function formatHiddenFields(array $array, $prefix = null)
730 foreach($array as $key => $value)
733 $key = $prefix."[".$key."]";
737 $result .= self::formatHiddenFields($value, $key);
741 $result .= "<input type=hidden name=\"".htmlspecialcharsbx($key)."\" value=\"".htmlspecialcharsbx($value)."\">\r\n";
static Check($siteId, $uri)
static OnPageStart($use_query=false)
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
$_SERVER["DOCUMENT_ROOT"]
check_bitrix_sessid($varname='sessid')
ConvertTimeStamp($timestamp=false, $type="SHORT", $site=false, $bSearchInSitesOnly=false)
GetModuleEvents($MODULE_ID, $MESSAGE_ID, $bReturnArray=false)
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
__construct(?int $storeId, int $productId, string $barcode, int $userId)
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
if(empty($signedUserToken)) $key
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
$GLOBALS['_____370096793']