Файловый менеджер - Редактировать - /home/beautybuzzbeyond/public_html/wp-content/plugins/sucuri-scanner/src/hardening.lib.php
Назад
<?php /** * Code related to the hardening.lib.php interface. * * PHP version 5 * * @category Library * @package Sucuri * @subpackage SucuriScanner * @author Daniel Cid <dcid@sucuri.net> * @copyright 2010-2018 Sucuri Inc. * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL2 * @link https://wordpress.org/plugins/sucuri-scanner */ if (!defined('SUCURISCAN_INIT') || SUCURISCAN_INIT !== true) { if (!headers_sent()) { /* Report invalid access if possible. */ header('HTTP/1.1 403 Forbidden'); } exit(1); } /** * Project hardening library. * * In computing, hardening is usually the process of securing a system by * reducing its surface of vulnerability. A system has a larger vulnerability * surface the more functions it fulfills; in principle a single-method system * is more secure than a multipurpose one. Reducing available vectors of attack * typically includes the removal of unnecessary software, unnecessary usernames * or logins and the disabling or removal of unnecessary services. * * There are various methods of hardening Unix and Linux systems. This may * involve, among other measures, applying a patch to the kernel such as Exec * Shield or PaX; closing open network ports; and setting up intrusion-detection * systems, firewalls and intrusion-prevention systems. There are also hardening * scripts and tools like Bastille Linux, JASS for Solaris systems and * Apache/PHP Hardener that can, for example, deactivate unneeded features in * configuration files or perform various other protective measures. * * @category Library * @package Sucuri * @subpackage SucuriScanner * @author Daniel Cid <dcid@sucuri.net> * @copyright 2010-2018 Sucuri Inc. * @license https://www.gnu.org/licenses/gpl-2.0.txt GPL2 * @link https://wordpress.org/plugins/sucuri-scanner */ class SucuriScanHardening extends SucuriScan { /* * This method is used to extract the folder and relative path (from one of the allowed folders) * given a full path and a list of allowed folders. * * @param string $fullPath Full path to the file. * @param array $allowed_folders List of allowed folders. * * @return array|false Array with the root directory and relative path * or null if the file is not in an allowed folder. */ public static function getFolderAndFilePath($path = '', $allowed_folders = array()) { $best_match = false; foreach ($allowed_folders as $base_directory) { if (strpos($path, $base_directory . DIRECTORY_SEPARATOR) === 0) { if ($best_match === false || substr_count( $base_directory, DIRECTORY_SEPARATOR ) > substr_count($best_match['base_directory'], DIRECTORY_SEPARATOR)) { $relative_path = str_replace($base_directory . DIRECTORY_SEPARATOR, '', $path); $best_match = array( 'base_directory' => $base_directory, 'relative_path' => $relative_path ); } } } return $best_match; } /** * Returns a list of access control rules for the Apache web server that can be * used to deny and allow certain files to be accessed by certain network nodes. * Currently supports Apache 2.2 and 2.4 and denies access to all PHP files with * any mixed extension case. * * @return array List of access control rules. */ private static function getRules() { return array( '<FilesMatch "\.(?i:php)$">', ' <IfModule !mod_authz_core.c>', ' Order allow,deny', ' Deny from all', ' </IfModule>', ' <IfModule mod_authz_core.c>', ' Require all denied', ' </IfModule>', '</FilesMatch>', ); } /** * Adds some rules to an existing access control file (or creates it if does not * exists) to deny access to all files with certain extension in any mixed case. * The permissions to modify the file are checked before anything else, this * method is self-contained. * * @param string $directory Valid directory path where to place the access rules. * @return bool True if the rules are successfully added, false otherwise. */ public static function hardenDirectory($directory = '') { if (!is_dir($directory) || !is_writable($directory)) { return self::throwException(__('Directory is not usable', 'sucuri-scanner')); } if (SucuriScan::isNginxServer() || SucuriScan::isIISServer()) { return self::throwException(__('Access control file is not supported', 'sucuri-scanner')); } $fhandle = false; $target = self::htaccess($directory); if (file_exists($target)) { self::fixPreviousHardening($directory); $fhandle = @fopen($target, 'a'); } else { $fhandle = @fopen($target, 'w'); } if (!$fhandle) { return false; } $deny_rules = self::getRules(); $rules_text = implode("\n", $deny_rules); $written = @fwrite($fhandle, "\n" . $rules_text . "\n"); @fclose($fhandle); return (bool)($written !== false); } /** * Deletes some rules from an existing access control file to allow access to * all files with certain extension in any mixed case. The file is truncated if * after the operation its size is equals to zero. * * @param string $directory Valid directory path where to access rules are. * @return bool True if the rules are successfully deleted, false otherwise. */ public static function unhardenDirectory($directory = '') { if (!self::isHardened($directory)) { return self::throwException(__('Directory is not hardened', 'sucuri-scanner')); } $fpath = self::htaccess($directory); $content = SucuriScanFileInfo::fileContent($fpath); $deny_rules = self::getRules(); $rules_text = implode("\n", $deny_rules); $content = str_replace($rules_text, '', $content); $written = @file_put_contents($fpath, $content); $trimmed = trim($content); if (!filesize($fpath) || empty($trimmed)) { @unlink($fpath); } return (bool)($written !== false); } /** * Remove the hardening applied in previous versions. * * @param string $directory Valid directory path. * @return bool True if the access control file was fixed. */ private static function fixPreviousHardening($directory = '') { $fpath = self::htaccess($directory); $content = SucuriScanFileInfo::fileContent($fpath); $rules = "<Files *.php>\ndeny from all\n</Files>"; /* no previous hardening rules exist */ if (strpos($content, $rules) === false) { return true; } $content = str_replace($rules, '', $content); $written = @file_put_contents($fpath, $content); return (bool)($written !== false); } /** * Check whether a directory is hardened or not. * * @param string $directory Valid directory path. * @return bool True if the directory is hardened, false otherwise. */ public static function isHardened($directory = '') { if (!is_dir($directory)) { return false; } $fpath = self::htaccess($directory); $content = SucuriScanFileInfo::fileContent($fpath); $deny_rules = self::getRules(); $rules_text = implode("\n", $deny_rules); return (bool)(strpos($content, $rules_text) !== false); } /** * Returns the path to the Apache access control file. * * @param string $folder Folder where the htaccess file is supposed to be. * @return string Path to the htaccess file in the specified folder. */ private static function htaccess($folder = '') { if (!function_exists('get_home_path')) { require_once ABSPATH . 'wp-admin/includes/file.php'; } $folder = str_replace(get_home_path(), '', $folder); $bpath = rtrim(get_home_path(), DIRECTORY_SEPARATOR); return $bpath . '/' . $folder . '/.htaccess'; } /** * Generates Apache access control rules for a file. * * Assuming that the directory hosting the specified file is hardened, this * method will generate the necessary rules to allowlist such file so anyone * can send a direct request to it. The method will generate both the rules * for Apache 2.4. * * Please note that since v1.9.5 we allow relatives paths to be used in the * REQUEST_URI condition. This is useful when the file is located in a subfolder * of the folder being hardened. * * @param string $filepath File path to be ignored by the hardening. * @param string $folder Folder hosting the specified file. * * @return string Access control rules to allowlist the file. */ private static function allowlistRule($filepath = '', $folder = '') { $filepath = str_replace(array('<', '>', '..'), '', $filepath); $relative_folder = str_replace(ABSPATH, '/', $folder); $relative_folder = '/' . ltrim($relative_folder, '/'); $path = sprintf( "<Files %s>\n" . " <If \"%%{REQUEST_URI} =~ m#^%s/%s$#\">\n" . " <IfModule !mod_authz_core.c>\n" . " Allow from all\n" . " </IfModule>\n" . " <IfModule mod_authz_core.c>\n" . " Require all granted\n" . " </IfModule>\n" . " </If>\n" . "</Files>\n", basename($filepath), rtrim($relative_folder, '/'), ltrim($filepath, '/') ); return $path; } /** * Generates Apache access control rules for a file (legacy). * * Assuming that the directory hosting the specified file is hardened, this * method will generate the necessary rules to allowlist such file so anyone * can send a direct request to it. The method will generate both the rules * for Apache 2.4 and a compatibility conditional for older versions. * * @param string $filepath File to be ignored by the hardening. * @return string Access control rules to allowlist the file. */ private static function allowlistRuleLegacy($filepath = '', $folder = '') { $filepath = str_replace(array('<', '>', '..'), '', $filepath); return sprintf( "<Files %s>\n" . " <IfModule !mod_authz_core.c>\n" . " Allow from all\n" . " </IfModule>\n" . " <IfModule mod_authz_core.c>\n" . " Require all granted\n" . " </IfModule>\n" . "</Files>", basename($filepath) ); } /** * Adds file in the specified folder to the allowlist. * * If the website owner has applied the hardening to the folder where the * specified file is located, all the requests sent directly to the file * will be blocked by the web server using its access control module. An * admin can ignore this hardening in one or more files if direct access to * it is required, as is the case with some 3rd-party plugins and themes. * * @param string $filepath File to be ignored by the hardening. * @param string $folder Folder hosting the specified file. * @return bool True if the file has been added to the allowlist, false otherwise. */ public static function allow($filepath = '', $folder = '') { if (SucuriScan::isNginxServer() || SucuriScan::isIISServer()) { throw new Exception(__('Access control file is not supported', 'sucuri-scanner')); } $htaccess = self::htaccess($folder); if (!file_exists($htaccess)) { throw new Exception(__('Access control file does not exists', 'sucuri-scanner')); } if (!is_writable($htaccess)) { throw new Exception(__('Access control file is not writable', 'sucuri-scanner')); } $rules = self::allowlistRule($filepath, $folder); $content = SucuriScanFileInfo::fileContent($htaccess); if (strpos($content, $rules) !== false) { throw new Exception(__('File is already in the allowlist', 'sucuri-scanner')); } return (bool)@file_put_contents( $htaccess, "\n" . self::allowlistRule($filepath, $folder), FILE_APPEND ); } /** * Blocks a file in the specified folder. * * If the website owner has applied the hardening to the folder where the * specified file is located, all the requests sent directly to the file * will be blocked by the web server using its access control module. If an * admin has added a file to the allowlist in this folder because a 3rd-party plugin or * theme required it, they can decide to remove this file from the allowlist using this * method which is executed by one of the tools in the settings page. * * @param string $filepath File to stop ignoring from the hardening. * @param string $folder Folder hosting the specified file. * @param bool $is_legacy Whether to use the legacy allowlist rule. * * @return bool True if the file has been removed from the allowlist, false otherwise. */ public static function removeFromAllowlist($filepath = '', $folder = '', $is_legacy = false) { $rules = self::allowlistRule($filepath, $folder); $htaccess = self::htaccess($folder); $content = SucuriScanFileInfo::fileContent($htaccess); if (!$content || !is_writable($htaccess)) { return self::throwException(__('Cannot remove file from the allowlist; no permissions.', 'sucuri-scanner')); } if ($is_legacy) { $rules = self::allowlistRuleLegacy($filepath, $folder); } $content = str_replace($rules, '', $content); $content = rtrim($content) . "\n"; return (bool)@file_put_contents($htaccess, $content); } /* * This method is used to get the list of files in the allowlist in a folder. * This returns the list of files with both the old and new patterns. * * @param string $content Content of the .htaccess file. * * @return array List of files in the allowlist. */ private static function getFiles($content = '') { preg_match_all('/<Files (\S+)>/', $content, $matches); return isset($matches[1]) ? $matches[1] : array(); } /* * This method is used to get the list of all files with new pattern in the .htaccess file * introduced in version 1.9.5. This pattern is based on the relative URL from the root directory * that the user selected. * * @param string $content Content of the .htaccess file. * * @return array List of files with new pattern in the .htaccess file. */ private static function getFilesWithNewPattern($content = '', $folder = '') { preg_match_all('/m#\^(\S+\/(\S+))\$\#/', $content, $new_matches, PREG_SET_ORDER, 0); $files_with_new_pattern = array(); if (empty($new_matches)) { return array(); } foreach ($new_matches as $match) { $uri = $match[0]; if (empty($uri)) { continue; } $cleaned_uri = str_replace(array('m#^', '$#'), '', $uri); $relative_folder_uri = str_replace(ABSPATH, '', $folder); $relative_path = str_replace($relative_folder_uri, '', $cleaned_uri); $relative_path = ltrim($relative_path, '/'); $files_with_new_pattern[] = array( 'file' => basename($cleaned_uri), 'relative_path' => $relative_path, ); } return $files_with_new_pattern; } /* This method is used to build the allowlist from the list of files and files with new pattern. * * @param array $files List of files in the allowlist. * @param array $filesWithNewPattern List of files with new pattern in the .htaccess file. * * @return array List of files in the allowlist. */ private static function buildAllowlist($files = array(), $files_with_new_pattern = array()) { if (empty($files)) { return array(); } $allowlist = array(); $processed_files = array(); foreach ($files as $file) { $wildcard_pattern = true; $relative_path = ''; // If this file is found in $files_with_new_pattern, it should not be marked as a wildcard pattern foreach ($files_with_new_pattern as $file_new_pattern) { if ($file_new_pattern['file'] === $file) { if (isset($processed_files[$file])) { continue; } $wildcard_pattern = false; $relative_path = $file_new_pattern['relative_path']; break; } } $processed_files[$file] = true; $allowlist[] = array( 'file' => $file, 'relative_path' => $relative_path ?: $file, 'wildcard_pattern' => $wildcard_pattern, ); } return $allowlist; } /** * Returns a list of files in the allowlist in folder. * * @param string $folder Directory to scan for files in the allowlist. * @return array List of files in the allowlist. Each file is an array with the keys: * - file: The name of the file. * - relative_path: The relative path of the file. * - wildcard_pattern: Whether the file is a wildcard pattern. */ public static function getAllowlist($folder = '') { $htaccess = self::htaccess($folder); $content = SucuriScanFileInfo::fileContent($htaccess); $files = self::getFiles($content); $files_with_new_pattern = self::getFilesWithNewPattern($content, $folder); $allowlist = self::buildAllowlist($files, $files_with_new_pattern); return $allowlist; } }
| ver. 1.4 |
Github
|
.
| PHP 8.0.30 | Генерация страницы: 0 |
proxy
|
phpinfo
|
Настройка