1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
environment.php
См. документацию.
1<?
8
11
17 extends CSecurityBaseTest
18{
19 const MIN_UID = 10;
20 const MIN_GID = 10;
21
22 protected $internalName = "EnvironmentTest";
23 protected $tests = array(
24 "sessionDir" => array(
25 "method" => "checkPhpSessionDir"
26 ),
27 "collectivePhpSession" => array(
28 "method" => "checkCollectivePhpSession"
29 ),
30 "uploadScriptExecution" => array(
31 "method" => "checkUploadScriptExecution"
32 ),
33 "uploadNegotiationEnabled" => array(
34 "method" => "checkUploadNegotiationEnabled"
35 ),
36 "privilegedPhpUserOrGroup" => array(
37 "method" => "checkPhpUserAndGroup"
38 ),
39 "bitrixTempPath" => array(
40 "method" => "checkBitrixTempPath"
41 )
42 );
43 //TODO: check custom php/py/perl/etc handlers in .htaccess files
44
45 public function __construct()
46 {
47 IncludeModuleLangFile(__FILE__);
48 }
49
50 protected function getSessionGeneralHandlerType(): ?string
51 {
52 $resolver = new SessionConfigurationResolver(Configuration::getInstance());
53 $sessionConfig = $resolver->getSessionConfig();
54
55 return $sessionConfig['handlers']['general']['type'] ?? null;
56 }
57
62 protected function checkUploadScriptExecution()
63 {
64 $baseMessageKey = "SECURITY_SITE_CHECKER_UPLOAD_EXECUTABLE";
65
66 $isHtaccessOverrided = false;
67// ToDo: fix and enable later
68// if(self::isHtaccessOverrided())
69// {
70// $isHtaccessOverrided = true;
71// $this->addUnformattedDetailError("SECURITY_SITE_CHECKER_UPLOAD_HTACCESS", CSecurityCriticalLevel::LOW);
72// }
73
74 $isPhpExecutable = false;
75 $uniqueString = randString(20);
76 if(self::isScriptExecutable("test.php", "<?php echo '{$uniqueString}'; ?>", $uniqueString))
77 {
78 $isPhpExecutable = true;
79 $this->addUnformattedDetailError($baseMessageKey."_PHP", CSecurityCriticalLevel::LOW);
80 }
81
82 $isPhpDoubleExtensionExecutable = false;
83 if(!$isPhpExecutable && self::isScriptExecutable("test.php.any", "<?php echo '{$uniqueString}'; ?>", $uniqueString))
84 {
85 $isPhpDoubleExtensionExecutable = true;
86 $this->addUnformattedDetailError($baseMessageKey."_PHP_DOUBLE", CSecurityCriticalLevel::LOW);
87 }
88
89 $isPythonCgiExecutable = false;
90 if(self::isScriptExecutable("test.py", "print 'Content-type:text/html\\r\\n\\r\\n{$uniqueString}'", $uniqueString))
91 {
92 $isPythonCgiExecutable = true;
93 $this->addUnformattedDetailError($baseMessageKey."_PY", CSecurityCriticalLevel::LOW);
94 }
95
96 if ($isPhpExecutable || $isPhpDoubleExtensionExecutable || $isHtaccessOverrided || $isPythonCgiExecutable)
97 return self::STATUS_FAILED;
98 else
99 return self::STATUS_PASSED;
100 }
101
106 protected function checkUploadNegotiationEnabled()
107 {
108 $testingText = "test";
109 $testFileContent = "
110Content-language: ru
111Content-type: text/html;
112Body:----------ru--
113".$testingText."
114----------ru--
115
116";
117
118 if(self::isScriptExecutable("test.var.jpg", $testFileContent, $testingText))
119 {
120 $this->addUnformattedDetailError("SECURITY_SITE_CHECKER_UPLOAD_NEGOTIATION", CSecurityCriticalLevel::MIDDLE);
121 return self::STATUS_FAILED;
122 }
123
124 return self::STATUS_PASSED;
125 }
126
131 protected function isHtaccessOverrided()
132 {
133 $uploadDir = self::getUploadDir();
134 $uploadPathTestFile = $uploadDir.'test/test.php';
135 $uploadPathHtaccessFile = $uploadDir.'test/.htaccess';
136 $uploadPathTestUri = $uploadDir.'test/test_notexist.php';
137
138 if(!CheckDirPath($_SERVER['DOCUMENT_ROOT'].$uploadPathTestFile))
139 return false;
140
141 $testingText = "testing text here...";
142 $htaccessText = <<<HTACCESS
143ErrorDocument 404 ${uploadPathTestFile}
144
145<IfModule mod_rewrite.c>
146 RewriteEngine Off
147</IfModule>
148HTACCESS;
149
150 $result = false;
151 if(file_put_contents($_SERVER['DOCUMENT_ROOT'].$uploadPathTestFile, $testingText))
152 {
153 if(file_put_contents($_SERVER['DOCUMENT_ROOT'].$uploadPathHtaccessFile, $htaccessText))
154 {
155 $response = self::doRequestToLocalhost($uploadPathTestUri);
156 if($response && $response == $testingText)
157 {
158 $result = true;
159 }
160 unlink($_SERVER['DOCUMENT_ROOT'].$uploadPathHtaccessFile);
161 }
162 unlink($_SERVER['DOCUMENT_ROOT'].$uploadPathTestFile);
163 }
164 return $result;
165 }
166
174 protected function checkPhpUserAndGroup($minUid = self::MIN_UID, $minGid = self::MIN_GID)
175 {
176 if(self::isRunOnWin())
177 return self::STATUS_PASSED;
178
179 $uid = self::getCurrentUID();
180 $uidCheckFailed = false;
181 if($uid !== null && $uid < $minUid)
182 $uidCheckFailed = true;
183
184 $gid = self::getCurrentGID();
185 $gidCheckFailed = false;
186 if($gid !== null && $gid < $minGid)
187 $gidCheckFailed = true;
188
189 if ($uidCheckFailed || $gidCheckFailed)
190 {
192 'SECURITY_SITE_CHECKER_PHP_PRIVILEGED_USER',
194 getMessage('SECURITY_SITE_CHECKER_PHP_PRIVILEGED_USER_ADDITIONAL', array(
195 '#UID#' => static::formatUID($uid),
196 '#GID#' => static::formatGID($gid)
197 ))
198 );
199 return self::STATUS_FAILED;
200 }
201
202 return self::STATUS_PASSED;
203 }
204
209 protected static function getUploadDir()
210 {
211 return "/".COption::GetOptionString("main", "upload_dir", "upload")."/tmp/";
212 }
213
218 protected static function getCurrentHost()
219 {
220 $host = $_SERVER['HTTP_HOST'] ? $_SERVER['HTTP_HOST'] : 'localhost';
221 $errors = array();
223 }
224
229 protected static function getCurrentSiteUrl()
230 {
231 $url = $_SERVER['HTTPS'] == 'on' ? 'https://' : 'http://';
233 $url .= $_SERVER['SERVER_PORT'] ? ':'.$_SERVER['SERVER_PORT'] : '';
234 return $url;
235 }
236
242 protected static function doRequestToLocalhost($pPath)
243 {
245 $url .= $pPath;
246 $url .= "?".mt_rand(); //Prevent web-server cache
247 return @CHTTP::sGet($url);
248 }
249
256 protected function isScriptExecutable($pFileName, $pText, $pSearch)
257 {
258 $uploadPath = self::getUploadDir().$pFileName;
259 if(!CheckDirPath($_SERVER['DOCUMENT_ROOT'].$uploadPath))
260 return false;
261
262 $result = false;
263 if(file_put_contents($_SERVER['DOCUMENT_ROOT'].$uploadPath, $pText))
264 {
266 if($response)
267 {
268 if($response != $pText && mb_strpos($response, $pSearch) !== false)
269 {
270 $result = true;
271 }
272 }
273 unlink($_SERVER['DOCUMENT_ROOT'].$uploadPath);
274 }
275 return $result;
276 }
277
282 protected static function getTmpDirFromEnv()
283 {
284 if ($_ENV["TMP"])
285 {
286 return realpath($_ENV["TMP"]);
287 }
288 elseif ($_ENV["TMPDIR"])
289 {
290 return realpath($_ENV["TMPDIR"]);
291 }
292 elseif ($_ENV["TEMP"])
293 {
294 return realpath($_ENV["TEMP"]);
295 }
296 else
297 {
298 return "";
299 }
300 }
301
307 protected static function getTmpDir($pPhpSettingKey = "upload_tmp_dir")
308 {
309 $result = ini_get($pPhpSettingKey);
310 if(!$result)
311 {
312 if (function_exists("sys_get_temp_dir"))
313 {
314 $result = sys_get_temp_dir();
315 }
316 else
317 {
319 }
320 }
321
322 return preg_replace('#[\\\/]+#', '/', $result);
323 }
324
329 protected static function getSessionUniqID()
330 {
331 return bitrix_sess_sign();
332 }
333
338 protected function checkCollectivePhpSession()
339 {
340 if(self::isRunOnWin())
341 return self::STATUS_PASSED;
342
343 if($this->getSessionGeneralHandlerType() !== SessionConfigurationResolver::TYPE_FILE)
344 return self::STATUS_PASSED;
345
346 if(ini_get("session.save_handler") != "files")
347 return self::STATUS_PASSED;
348
349 $tmpDir = self::getTmpDir("session.save_path");
350 if(!$tmpDir)
351 return self::STATUS_PASSED;
352
353 $additionalInfo = "";
354 $isFailed = false;
355 $currentUID = self::getCurrentUID();
356 $sessionSign = self::getSessionUniqID();
357 foreach (glob($tmpDir."/sess_*", GLOB_NOSORT) as $fileName)
358 {
359
360 if($currentUID !== null)
361 {
362 $fileOwner = fileowner($fileName);
363 if($currentUID != $fileOwner)
364 {
365 $additionalInfo = getMessage("SECURITY_SITE_CHECKER_COLLECTIVE_SESSION_ADDITIONAL_OWNER", array(
366 "#FILE#" => $fileName,
367 "#FILE_ONWER#" => $fileOwner,
368 "#CURRENT_OWNER#" => $currentUID,
369 ));
370 $isFailed = true;
371 break;
372 }
373 }
374
375 if(is_readable($fileName))
376 {
377 $fileContent = file_get_contents($fileName);
378 if (mb_strpos($fileContent, $sessionSign) === false)
379 {
380 $additionalInfo = getMessage("SECURITY_SITE_CHECKER_COLLECTIVE_SESSION_ADDITIONAL_SIGN", array(
381 "#FILE#" => $fileName,
382 "#FILE_CONTENT#" => htmlspecialcharsbx(mb_substr($fileContent, 0, 1024)),
383 "#SIGN#" => $sessionSign
384 ));
385 $isFailed = true;
386 break;
387 }
388 }
389 }
390
391 if($isFailed)
392 {
394 "SECURITY_SITE_CHECKER_COLLECTIVE_SESSION",
396 $additionalInfo
397 );
398 return self::STATUS_FAILED;
399 }
400
401 return self::STATUS_PASSED;
402 }
403
408 protected function checkPhpSessionDir()
409 {
410 if (self::isRunOnWin())
411 return self::STATUS_PASSED;
412
413 if ($this->getSessionGeneralHandlerType() !== SessionConfigurationResolver::TYPE_FILE)
414 return self::STATUS_PASSED;
415
416 if (ini_get("session.save_handler") != "files")
417 return self::STATUS_PASSED;
418
419 $tmpDir = self::getTmpDir("session.save_path");
420 if (!$tmpDir)
421 return self::STATUS_PASSED;
422
423 $dir = $tmpDir;
424 while ($dir && $dir != '/')
425 {
426 $perms = static::getFilePerm($dir);
427 if (($perms & 0x0001) === 0)
428 return self::STATUS_PASSED;
429
430 $dir = dirname($dir);
431 }
432
434 "SECURITY_SITE_CHECKER_SESSION_DIR",
436 getMessage("SECURITY_SITE_CHECKER_SESSION_DIR_ADDITIONAL", array(
437 "#DIR#" => $tmpDir,
438 "#PERMS#" => self::formatFilePermissions(static::getFilePerm($tmpDir)),
439 ))
440 );
441
442 return self::STATUS_FAILED;
443 }
444
450 protected static function getCurrentUID()
451 {
452 if(is_callable("getmyuid"))
453 {
454 return getmyuid();
455 }
456 elseif(is_callable("posix_geteuid"))
457 {
458 return posix_geteuid();
459 }
460 else
461 {
462 return null;
463 }
464 }
465
471 protected static function getCurrentGID()
472 {
473 if(is_callable("getmygid"))
474 {
475 return getmygid();
476 }
477 elseif(is_callable("posix_getegid"))
478 {
479 return posix_getegid();
480 }
481 else
482 {
483 return null;
484 }
485 }
486
493 protected static function formatUID($uid)
494 {
495 if(is_callable("posix_getpwuid"))
496 {
497 $uid = posix_getpwuid($uid);
498 return sprintf('%s(%s)', $uid['name'], $uid['uid']);
499 }
500
501 return $uid;
502 }
503
510 protected static function formatGID($gid)
511 {
512 if(is_callable("posix_getgrgid"))
513 {
514 $gid = posix_getgrgid($gid);
515 return sprintf('%s(%s)', $gid['name'], $gid['gid']);
516 }
517
518 return $gid;
519 }
520
521 protected static function formatFilePermissions($perms)
522 {
523 // http://www.php.net/manual/en/function.fileperms.php
524
525 if (($perms & 0xC000) == 0xC000)
526 {
527 // Socket
528 $info = 's';
529 }
530 elseif (($perms & 0xA000) == 0xA000)
531 {
532 // Symbolic Link
533 $info = 'l';
534 }
535 elseif (($perms & 0x8000) == 0x8000)
536 {
537 // Regular
538 $info = '-';
539 }
540 elseif (($perms & 0x6000) == 0x6000)
541 {
542 // Block special
543 $info = 'b';
544 }
545 elseif (($perms & 0x4000) == 0x4000)
546 {
547 // Directory
548 $info = 'd';
549 }
550 elseif (($perms & 0x2000) == 0x2000)
551 {
552 // Character special
553 $info = 'c';
554 }
555 elseif (($perms & 0x1000) == 0x1000)
556 {
557 // FIFO pipe
558 $info = 'p';
559 }
560 else
561 {
562 // Unknown
563 $info = 'u';
564 }
565
566 // Owner
567 $info .= (($perms & 0x0100) ? 'r' : '-');
568 $info .= (($perms & 0x0080) ? 'w' : '-');
569 $info .= (($perms & 0x0040) ?
570 (($perms & 0x0800) ? 's' : 'x' ) :
571 (($perms & 0x0800) ? 'S' : '-'));
572
573 // Group
574 $info .= (($perms & 0x0020) ? 'r' : '-');
575 $info .= (($perms & 0x0010) ? 'w' : '-');
576 $info .= (($perms & 0x0008) ?
577 (($perms & 0x0400) ? 's' : 'x' ) :
578 (($perms & 0x0400) ? 'S' : '-'));
579
580 // World
581 $info .= (($perms & 0x0004) ? 'r' : '-');
582 $info .= (($perms & 0x0002) ? 'w' : '-');
583 $info .= (($perms & 0x0001) ?
584 (($perms & 0x0200) ? 't' : 'x' ) :
585 (($perms & 0x0200) ? 'T' : '-'));
586
587 return $info;
588 }
589
596 protected function checkBitrixTempPath()
597 {
599
600 $path = CTempFile::GetAbsoluteRoot();
601 $path = $io->CombinePath($path);
602
603 $documentRoot = self::getParam("DOCUMENT_ROOT", $_SERVER["DOCUMENT_ROOT"]);
604 $documentRoot = $io->CombinePath($documentRoot);
605
606 if (mb_strpos($path, $documentRoot) === 0)
607 {
609 "SECURITY_SITE_CHECKER_BITRIX_TMP_DIR",
611 getMessage("SECURITY_SITE_CHECKER_BITRIX_TMP_DIR_ADDITIONAL", array(
612 "#DIR#" => $path
613 ))
614 );
615
616 return static::STATUS_FAILED;
617 }
618
619 return static::STATUS_PASSED;
620 }
621}
$path
Определения access_edit.php:21
static ToASCII($domainName, &$arErrors)
Определения punycode.php:44
static GetInstance()
Определения virtual_io.php:60
static sGet($url, $follow_redirect=false)
Определения http.php:409
Определения base_test.php:14
addUnformattedDetailError($baseMessageKey, $critical, $additionalInfo="")
Определения base_test.php:283
getParam($name, $defaultValue="")
Определения base_test.php:182
const LOW
Определения critical_level.php:15
const MIDDLE
Определения critical_level.php:16
const HIGHT
Определения critical_level.php:17
__construct()
Определения environment.php:45
static getCurrentSiteUrl()
Определения environment.php:229
static getUploadDir()
Определения environment.php:209
static getSessionUniqID()
Определения environment.php:329
static getTmpDir($pPhpSettingKey="upload_tmp_dir")
Определения environment.php:307
checkPhpUserAndGroup($minUid=self::MIN_UID, $minGid=self::MIN_GID)
Определения environment.php:174
isScriptExecutable($pFileName, $pText, $pSearch)
Определения environment.php:256
checkUploadScriptExecution()
Определения environment.php:62
checkCollectivePhpSession()
Определения environment.php:338
const MIN_UID
Определения environment.php:19
checkUploadNegotiationEnabled()
Определения environment.php:106
static getTmpDirFromEnv()
Определения environment.php:282
isHtaccessOverrided()
Определения environment.php:131
static doRequestToLocalhost($pPath)
Определения environment.php:242
static getCurrentHost()
Определения environment.php:218
const MIN_GID
Определения environment.php:20
getSessionGeneralHandlerType()
Определения environment.php:50
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$fileContent
Определения file_property.php:47
$result
Определения get_property_values.php:14
$host
Определения .description.php:9
$uid
Определения hot_keys_act.php:8
$errors
Определения iblock_catalog_edit.php:74
$_SERVER["DOCUMENT_ROOT"]
Определения cron_frame.php:9
$io
Определения csv_new_run.php:98
foreach(['Bitrix\\Main'=> '/lib', 'Psr\\Container'=> '/vendor/psr/container/src', 'Psr\\Log'=> '/vendor/psr/log/src', 'Psr\\Http\\Message'=> '/vendor/psr/http-message/src', 'Psr\\Http\\Client'=> '/vendor/psr/http-client/src', 'Http\\Promise'=> '/vendor/php-http/promise/src', 'PHPMailer\\PHPMailer'=> '/vendor/phpmailer/phpmailer/src', 'GeoIp2'=> '/vendor/geoip2/geoip2/src', 'MaxMind\\Db'=> '/vendor/maxmind-db/reader/src/MaxMind/Db', 'PhpParser'=> '/vendor/nikic/php-parser/lib/PhpParser', 'Recurr'=> '/vendor/simshaun/recurr/src/Recurr',] as $namespace=> $namespacePath) $documentRoot
Определения autoload.php:27
if($NS['step']==6) if( $NS[ 'step']==7) if(COption::GetOptionInt('main', 'disk_space', 0) > 0) $info
Определения backup.php:924
CheckDirPath($path)
Определения tools.php:2707
bitrix_sess_sign()
Определения tools.php:4681
htmlspecialcharsbx($string, $flags=ENT_COMPAT, $doubleEncode=true)
Определения tools.php:2701
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
Определения tools.php:3778
randString($pass_len=10, $pass_chars=false)
Определения tools.php:2154
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$dir
Определения quickway.php:303
$fileName
Определения quickway.php:305
$response
Определения result.php:21
checkPhpSessionDir()
Определения environment.php:408
checkBitrixTempPath()
Определения environment.php:596
$url
Определения iframe.php:7