1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
filter.php
См. документацию.
1<?php
2
5
6class CSecurityFilter
7{
8 const DEFAULT_REQUEST_ORDER = "GP";
9 private $doBlock = false;
11 private $requestFilter = null;
13 private $serverFilter = null;
15 private $context = 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')
21 );
22
23 public function __construct($customOptions = array(), $char = "")
24 {
25 if(isset($customOptions["stop"]))
26 {
27 $this->doBlock = $customOptions["stop"];
28 }
29 else
30 {
31 $this->doBlock = (\COption::getOptionString("security", "filter_stop") === 'Y');
32 }
33
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;
38 }
39
40 public static function OnBeforeProlog()
41 {
42 if (CSecuritySystemInformation::isCliMode())
43 return;
44
46 return;
47
48 if(
50 && self::currentUserHaveRightsForSkip()
51 && (
52 !isset($_POST['____SECFILTER_CONVERT_JS'])
53 || !$_POST['____SECFILTER_CONVERT_JS']
54 )
55 )
56 {
57 return;
58 }
59
60 $filter = new CSecurityFilter;
61 $filter->process();
62 }
63
67 public static function IsActive()
68 {
69 $bActive = false;
70 foreach(GetModuleEvents("main", "OnBeforeProlog", true) as $event)
71 {
72 if(
73 $event["TO_MODULE_ID"] == "security"
74 && $event["TO_CLASS"] == "CSecurityFilter"
75 )
76 {
77 $bActive = true;
78 break;
79 }
80 }
81 return $bActive;
82 }
83
84
88 public static function SetActive($bActive = false)
89 {
90 if($bActive)
91 {
92 if(!CSecurityFilter::IsActive())
93 {
94 registerModuleDependences("main", "OnBeforeProlog", "security", "CSecurityFilter", "OnBeforeProlog", "5");
95 registerModuleDependences("main", "OnEndBufferContent", "security", "CSecurityXSSDetect", "OnEndBufferContent", 9999);
96 }
97 }
98 else
99 {
100 if(CSecurityFilter::IsActive())
101 {
102 unregisterModuleDependences("main", "OnBeforeProlog", "security", "CSecurityFilter", "OnBeforeProlog");
103 unregisterModuleDependences("main", "OnEndBufferContent", "security", "CSecurityXSSDetect", "OnEndBufferContent");
104 }
105 }
106 }
107
108
112 public static function GetAuditTypes()
113 {
114 return array(
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"),
121 );
122 }
123
129 public static function GetEventsCount($timestampX = '')
130 {
131 return CSecurityEvent::getInstance()->getEventsCount($timestampX);
132 }
133
138 public static function OnAdminInformerInsertItems()
139 {
141 global $APPLICATION;
142 if ($APPLICATION->GetGroupRight("security") < "W")
143 return false;
144
145 $setupLink = '/bitrix/admin/security_filter.php?lang='.LANGUAGE_ID;
146 $WAFAIParams = array(
147 "TITLE" => getMessage("SECURITY_FILTER_INFORM_TITLE"),
148 "COLOR" => "blue",
149 "FOOTER" => '<a href="'.$setupLink.'">'.getMessage("SECURITY_FILTER_INFORM_LINK_TO_SETUP_ON").'</a>'
150 );
151
152 try
153 {
154 if (self::IsActive())
155 {
156
157 $days = COption::getOptionInt("main", "event_log_cleanup_days", 7);
158 if($days > 7)
159 $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;
162
163 $eventCount = self::getEventsCount($timestampX);
164 if($eventCount > 999)
165 $eventCount = round($eventCount/1000,1).'K';
166
167 if($eventCount > 0)
168 $descriptionText = getMessage("SECURITY_FILTER_INFORM_EVENT_COUNT").'<a href="'.$eventLink.'">'.$eventCount.'</a>';
169 else
170 $descriptionText = getMessage("SECURITY_FILTER_INFORM_EVENT_COUNT_EMPTY");
171
172 $WAFAIParams["FOOTER"] = '<a href="'.$setupLink.'">'.getMessage("SECURITY_FILTER_INFORM_LINK_TO_SETUP").'</a>';
173 $WAFAIParams["ALERT"] = false;
174
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>
180 </span>
181</div>
182';
183 }
184 else
185 {
186 $WAFAIParams["ALERT"] = true;
187
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>
193 </span>
194</div>
195';
196 }
197 }
198 catch (Exception $e)
199 {
200 $WAFAIParams["TITLE"] .= " - ".getMessage("top_panel_ai_title_err");
201 $WAFAIParams["ALERT"] = true;
202 $WAFAIParams["HTML"] = $e->getMessage();
203 }
204
205 CAdminInformer::AddItem($WAFAIParams);
206 return true;
207 }
208
209
214 public static function ClearTmpFiles()
215 {
216 return "";
217 }
218
226 public function testXSS($pValue, $pAction = "clear")
227 {
228 return $pValue;
229 }
230
231 public static function processVar(array|string $var)
232 {
233 static $skip = null;
234
235 if (is_null($skip))
236 {
237 $skip = !CSecurityFilter::IsActive();
238 $skip = $skip || CSecuritySystemInformation::isCliMode();
239 $skip = $skip || CSecurityFilterMask::Check(SITE_ID, $_SERVER["REQUEST_URI"]);
240 $skip = $skip || (check_bitrix_sessid() && self::currentUserHaveRightsForSkip());
241 }
242
243 if ($skip)
244 {
245 return $var;
246 }
247
248 $instance = new CSecurityFilter();
249
250 $auditors = $instance->getAuditorInstances();
251 $instance->requestFilter->setAuditors($auditors);
252
253 $array = is_array($var) ? ['data' => $var] : ['data' => ['key' => $var]];
254
255 $filteredValues = $instance->requestFilter->filter($array, false);
256 $filteredValues = $filteredValues['data'];
257
258 if ($instance->isAuditorsTriggered())
259 {
260 $instance->doPostProcessActions();
261 }
262
263 unset($instance);
264
265 return is_array($var) ? $filteredValues : ($filteredValues['key'] ?? '') ;
266 }
267
268 protected function process()
269 {
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);
275
276 if ($this->isAuditorsTriggered())
277 {
278 if ($this->isSomethingChanged())
279 {
280 $this->overrideSuperGlobals();
281
282 if ($this->currentUserHaveRightsForSkip())
283 {
284 $this->showForm();
285 }
286 }
287
288 $this->doPostProcessActions();
289 }
290 }
291
292 protected function getAuditors()
293 {
294 $wafConfig = \Bitrix\Main\Config\Configuration::getValue("waf");
295 if (is_array($wafConfig) && isset($wafConfig['auditors']))
296 return $wafConfig['auditors'];
297
298 return $this->defaultAuditors;
299 }
300
301 protected function getAuditorInstances()
302 {
303 $auditors = $this->getAuditors();
304 $result = array();
305 foreach($auditors as $auditor)
306 {
307 if (isset($auditor['file']))
308 {
309 include_once $auditor['file'];
310 }
311
312 $class = $auditor['class'];
313 $result[$auditor['type']] = new $class($this->splittingChar);
314 }
315 return $result;
316 }
317
318 protected function overrideSuperGlobals()
319 {
320 self::cleanGlobals();
321
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();
327
328 self::reconstructRequest();
329 self::restoreGlobals();
330 }
331
336 protected function isAuditorsTriggered()
337 {
338 return (
339 $this->requestFilter->isAuditorsTriggered()
340 || $this->serverFilter->isAuditorsTriggered()
341 );
342 }
343
347 protected function isSomethingChanged()
348 {
349 return (
350 count($this->requestFilter->getChangedVars()) > 0
351 || count($this->serverFilter->getChangedVars()) > 0
352 );
353 }
354
358 protected function getChangedVars()
359 {
360 return $this->requestFilter->getChangedVars() + $this->serverFilter->getChangedVars();
361 }
362
366 protected function getHttpRequest()
367 {
368 return $this->context->getRequest();
369 }
370
374 protected function isBlockNeeded()
375 {
376 return $this->doBlock;
377 }
378
382 protected static function currentUserHaveRightsForSkip()
383 {
385 global $USER;
386 if(is_object($USER))
387 return $USER->CanDoOperation('security_filter_bypass');
388 else
389 return false;
390 }
391
392
397 protected function blockCurrentUser($ip = "")
398 {
399 if(self::currentUserHaveRightsForSkip())
400 return false;
401
402 if(!is_string($ip) || $ip === "")
403 $ip = $_SERVER["REMOTE_ADDR"];
404
405 $rule = new CSecurityIPRule;
406
408 $startTimestamp = ConvertTimeStamp(false, "FULL");
409 $endTimestamp = ConvertTimeStamp(time()+COption::getOptionInt("security", "filter_duration")*60, "FULL");
410 $ruleList = $rule->GetList(array("ID"), array(
411 "=RULE_TYPE" => "A",
412 "=ACTIVE" => "Y",
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())
419 {
420 if ($rule->Update($prevRule['ID'], array("ACTIVE_TO" => $endTimestamp)))
421 {
423 return true;
424 }
425 break;
426 }
427 $added = $rule->Add(array(
428 "RULE_TYPE" => "A",
429 "ACTIVE" => "Y",
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("/*"),
436 ));
438
439 return ($added > 0);
440 }
441
445 protected static function getSafetyGlobals()
446 {
447 static $safetyVars = array(
448 "_GET" => 1,
449 "_POST" => 1,
450 "_SERVER" => 1,
451 "_ENV" => 1,
452 "_COOKIE" => 1,
453 "_FILES" => 1,
454 "_REQUEST" => 1,
455 "_SESSION" => 1,
456 "GLOBALS" => 1,
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,
465 "php_errormsg" => 1,
466 "HTTP_RAW_POST_DATA" => 1,
467 "http_response_header" => 1,
468 "argc" => 1,
469 "argv" => 1,
470 "DOCUMENT_ROOT" => 1,
471 "_UNSECURE" => 1
472 );
473
474 return $safetyVars;
475 }
476
477 protected static function cleanGlobals()
478 {
479 $safetyGlobals = self::getSafetyGlobals();
480 foreach($_REQUEST as $key => $value)
481 {
482 if(!isset($safetyGlobals[$key]) && $value === $GLOBALS[$key])
483 {
484 unset($GLOBALS[$key]);
485 }
486 }
487 }
488
493 protected static function getSuperGlobalArray($type)
494 {
495 switch($type)
496 {
497 case "g":
498 case "G":
499 return $_GET;
500 break;
501 case "p":
502 case "P":
503 return $_POST;
504 break;
505 case "c":
506 case "C":
507 return $_COOKIE;
508 break;
509 case "s":
510 case "S":
511 return $_SERVER;
512 break;
513 case "e":
514 case "E":
515 return $_ENV;
516 break;
517 default:
518 return array();
519 break;
520 }
521 }
522
523 protected static function getRequestOrder()
524 {
525 $result = ini_get("request_order");
526
527 if (!$result)
528 $result = ini_get("variables_order");
529
530 if (!$result)
531 $result = self::DEFAULT_REQUEST_ORDER;
532
533 return $result;
534 }
535
536 protected static function reconstructRequest()
537 {
538 $systemOrder = static::getRequestOrder();
539
540 $_REQUEST = self::getSuperGlobalArray($systemOrder[0]);
541 for($i = 1, $count = mb_strlen($systemOrder); $i < $count; $i ++)
542 {
543 $targetArray = self::getSuperGlobalArray($systemOrder[$i]);
544 foreach($targetArray as $k => $v)
545 {
546 $_REQUEST[$k] = $v;
547 }
548 }
549 }
550
551 protected static function restoreGlobals()
552 {
553 $safetyGlobals = self::getSafetyGlobals();
554 foreach($_REQUEST as $key => $value)
555 {
556 if(!isset($safetyGlobals[$key])
557 && !(
558 isset($GLOBALS[$key])
559 || array_key_exists($key, $GLOBALS)
560 )
561 )
562 {
564 }
565 }
566 }
567
568 protected function doPostProcessActions()
569 {
570 if (
571 $this->isBlockNeeded()
572 && $this->blockCurrentUser()
574 )
575 {
577 }
578 }
579
580 protected function showForm()
581 {
582 if(!isset($_POST['____SECFILTER_CONVERT_JS']) || empty($_POST['____SECFILTER_CONVERT_JS']))
583 {
584 if(
585 //intranet tasks folder created
586 (
587 isset($_GET["bx_task_action_request"])
588 && $_GET["bx_task_action_request"] === "Y"
589 && isset($_GET["action"])
590 && $_GET["action"] === "folder_edit"
591 )
592 //or create ticket with wizard
593 || (
594 isset($_GET['show_wizard'])
595 && $_GET['show_wizard'] === "Y"
596 && isset($_POST['AJAX_CALL'])
597 && $_POST['AJAX_CALL'] === "Y"
598 )
599 //or by bitrix:search.title
600 || (
601 isset($_POST['q'])
602 && !empty($_POST['q'])
603 && isset($_POST['ajax_call'])
604 && $_POST['ajax_call'] === "y"
605 )
606 //or by constant defined on the top of the page
607 || defined('BX_SECURITY_SHOW_MESSAGE')
608 )
609 {
610 $this->showTextForm();
611 }
612 elseif(defined('BX_PUBLIC_MODE') && BX_PUBLIC_MODE == 1)
613 {
614 $this->showAjaxForm();
615 }
616 else
617 {
618 $originalPostVars = $this->getHttpRequest()->getPostList()->toArrayRaw();
619 if (!$originalPostVars)
620 $originalPostVars = array();
621
622 $this->showHtmlForm($originalPostVars);
623 }
624
625 die();
626 }
627 }
628
632 protected function showTextForm()
633 {
634 echo "[WAF] ".getMessage("SECURITY_FILTER_FORM_SUB_TITLE")." ".getMessage("SECURITY_FILTER_FORM_TITLE").".";
635 }
636
640 protected function showAjaxForm()
641 {
642 echo '<script>top.BX.closeWait(); top.BX.WindowManager.Get().ShowError(\''.getMessageJS("SECURITY_FILTER_FORM_SUB_TITLE")." ".getMessageJS("SECURITY_FILTER_FORM_TITLE").".".'\')</script>';
643 }
644
648 protected function showHtmlForm($originalPostVars = array())
649 {
650
651 ?>
652 <html>
653 <head>
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" />
659 </head>
660 <body>
661 <script>if(document.location!=top.location)top.location=document.location;</script>
662 <style>
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; }
666 </style>
667
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>
674 </tr>
675 <tr>
676 <td class="left"><div class="empty"></div></td>
677 <td class="content">
678 <div class="title">
679 <table cellpadding="0" cellspacing="0">
680 <tr>
681 <td><div class="icon"></div></td>
682 <td><?echo getMessage("SECURITY_FILTER_FORM_SUB_TITLE")?></td>
683 </tr>
684 </table>
685 </div>
686 <div class="description">
687 <?echo getMessage("SECURITY_FILTER_FORM_MESSAGE")?><br /><br />
688 <table cellpadding="0" cellspacing="0" witdh="100%">
689 <tr>
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>
692 </tr>
693 <?foreach($this->getChangedVars() as $var_name => $str):?>
694 <tr valign="top">
695 <td><?echo htmlspecialcharsbx($var_name)?></td>
696 <td><?echo htmlspecialcharsbx($str)?></td>
697 </tr>
698 <?endforeach?>
699 </table><br />
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')?>" />
705 </form>
706 </div>
707 </td>
708 <td class="right"><div class="empty"></div></td>
709 </tr>
710 <tr class="bottom">
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>
714 </tr>
715 </tbody></table>
716 </div>
717 </body>
718 </html>
719 <?
720 }
721
727 protected static function formatHiddenFields(array $array, $prefix = null)
728 {
729 $result = "";
730 foreach($array as $key => $value)
731 {
732 if($prefix !== null)
733 $key = $prefix."[".$key."]";
734
735 if(is_array($value))
736 {
737 $result .= self::formatHiddenFields($value, $key);
738 }
739 else
740 {
741 $result .= "<input type=hidden name=\"".htmlspecialcharsbx($key)."\" value=\"".htmlspecialcharsbx($value)."\">\r\n";
742 }
743 }
744
745 return $result;
746 }
747
748}
749
$count
Определения admin_tab.php:4
$type
Определения options.php:106
global $APPLICATION
Определения include.php:80
static AddItem($arParams)
Определения admin_informer.php:27
static getInstance()
Определения event.php:41
static Check($siteId, $uri)
Определения filter_mask.php:69
static IsActive()
Определения iprule.php:900
static OnPageStart($use_query=false)
Определения iprule.php:954
static isCliMode()
Определения system_information.php:74
static Disable()
Определения time.php:31
static Enable()
Определения time.php:36
const BX_PUBLIC_MODE
Определения file_edit.php:2
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$_REQUEST["admin_mnu_menu_id"]
Определения get_menu.php:8
$result
Определения get_property_values.php:14
$filter
Определения iblock_catalog_list.php:54
$_SERVER["DOCUMENT_ROOT"]
Определения cron_frame.php:9
global $USER
Определения csv_new_run.php:40
$context
Определения csv_new_setup.php:223
check_bitrix_sessid($varname='sessid')
Определения tools.php:4686
ConvertTimeStamp($timestamp=false, $type="SHORT", $site=false, $bSearchInSitesOnly=false)
Определения tools.php:733
GetModuleEvents($MODULE_ID, $MESSAGE_ID, $bReturnArray=false)
Определения tools.php:5177
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
Определения tools.php:3778
__construct(?int $storeId, int $productId, string $barcode, int $userId)
Определения basestorebarcodeaction.php:38
$value
Определения Param.php:39
$var
Определения payment.php:63
$event
Определения prolog_after.php:141
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$instance
Определения ps_b24_final.php:14
if(empty($signedUserToken)) $key
Определения quickway.php:257
die
Определения quickway.php:367
$i
Определения factura.php:643
</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."%"
Определения waybill.php:936
const SITE_ID
Определения sonet_set_content_view.php:12
$k
Определения template_pdf.php:567
$GLOBALS['_____370096793']
Определения update_client.php:1