Priority File Manager

📁 public_html
Base Directory:
/home/ecedu/public_html/wp-content/plugins/really-simple-ssl/security
NameTypeSizeActions
📁 .. Folder -
📄 class-rsssl-htaccess-file-manager.php File 20985
Edit Download
📄 cron.php File 4169
Edit Download
📄 deactivate-integration.php File 1611
Edit Download
📄 firewall-manager.php File 22754
Edit Download
📄 functions.php File 20506
Edit Download
📄 hardening.php File 2260
Edit Download
📁 includes Folder -
📄 index.php File 32
Edit Download
📄 integrations.php File 4813
Edit Download
📄 notices.php File 6174
Edit Download
📄 security.php File 1805
Edit Download
📁 server Folder -
📄 sync-settings.php File 2860
Edit Download
📁 tests Folder -
📄 tests.php File 13704
Edit Download
📁 wordpress Folder -
htAccessFile = $htaccessFile; self::$this = $this; // Determine firewall.php path, allowing custom content dir or fallback. $wpContentPath = defined( 'WP_CONTENT_DIR' ) ? trailingslashit( WP_CONTENT_DIR ) : ''; if ( empty( $wpContentPath ) ) { $wpContentPath = ABSPATH . 'wp-content/'; } $this->firewall_file_path = apply_filters( 'rsssl_firewall_file_path', $wpContentPath . 'firewall.php' ); // trigger this action to force rules update add_action( 'rsssl_update_rules', array( $this, 'install' ) ); add_action( 'rsssl_after_saved_fields', array( $this, 'install' ), 100 ); add_action( 'rsssl_deactivate', array( $this, 'uninstall' ), 20 ); add_filter( 'rsssl_notices', array( $this, 'notices' ) ); //handle activation and deactivation of wp rocket add_action( 'rocket_activation', array( $this, 'remove_prepend_file_in_htaccess' ) ); add_action( 'rocket_deactivation', array( $this, 'include_prepend_file_in_htaccess' ) ); if ( ! defined( 'RSSSL_IS_WP_ENGINE' ) ) { define( 'RSSSL_IS_WP_ENGINE', isset( $_SERVER['IS_WPE'] ) ); } if ( ! defined( 'RSSSL_IS_FLYWHEEL' ) ) { define( 'RSSSL_IS_FLYWHEEL', isset( $_SERVER['SERVER_SOFTWARE'] ) && strpos( $_SERVER['SERVER_SOFTWARE'], 'Flywheel/' ) === 0 ); } if ( ! defined( 'RSSSL_IS_PRESSABLE' ) ) { define( 'RSSSL_IS_PRESSABLE', ( defined( 'IS_ATOMIC' ) && IS_ATOMIC ) || ( defined( 'IS_PRESSABLE' ) && IS_PRESSABLE ) ); } } /** * Main installer for the firewall file */ public function install(): void { if ( ! rsssl_admin_logged_in() ) { return; } if ( wp_doing_ajax() ) { return; } if ( empty( $this->rules ) ) { $this->rules = apply_filters( 'rsssl_firewall_rules', '' ); } // no rules? remove the file. if ( empty( trim( $this->rules ) ) ) { // $this->delete_file(); $this->remove_prepend_file_in_htaccess(); $this->remove_prepend_file_in_wp_config(); return; } // update the file to be included. $this->update_firewall( $this->rules ); $this->include_prepend_file_in_wp_config(); if ( $this->uses_htaccess() ) { // only include in the admin_init, to prevent issues with the htaccess file not being writable. if( current_filter() !== 'plugins_loaded' ) { $this->include_prepend_file_in_htaccess(); } } if ( $this->has_user_ini_file() ) { $this->include_prepend_file_in_user_ini(); } } /** * Remove file and file inclusions */ public function uninstall(): void { if ( ! rsssl_user_can_manage() ) { return; } if ( wp_doing_ajax() ) { return; } $this->remove_prepend_file_in_htaccess(); $this->remove_prepend_file_in_wp_config(); $this->remove_auto_prepend_file_in_user_ini(); $this->delete_file(); } /** * Check if our firewall file exists * * @param string $file // filename, including path * * @return bool */ private function file_exists( string $file ): bool { return file_exists( $file ); } /** * Initialize the WP_Filesystem */ private function init_file_system():? WP_Filesystem_Base { if ( ! function_exists( 'WP_Filesystem' ) ) { include_once ABSPATH . 'wp-admin/includes/file.php'; } if ( false === ( $credentials = request_filesystem_credentials( site_url(), '', false, false ) ) ) { return null; // stop processing here. } global $wp_filesystem; if ( ! WP_Filesystem( $credentials ) ) { // request_filesystem_credentials(site_url(), '', true, false, null); return null; } return $wp_filesystem; } /** * Update the file that contains the firewall rules, advanced-headers.php */ public function update_firewall( string $rules ): void { if ( ! rsssl_admin_logged_in() ) { return; } $contents = 'get_headers_nonce() . ' ) return;' . "\n\n"; //if already included at some point, don't execute again. $contents .= 'if ( defined("RSSSL_HEADERS_ACTIVE" ) ) return;' . "\n"; $contents .= 'define( "RSSSL_HEADERS_ACTIVE", true );' . "\n"; // If the main firewall (firewall.php) is enabled, add the include directive for it. if ( rsssl_get_option( 'enable_firewall', false ) ) { $firewallFilePath = $this->firewall_file_path; $contents .= 'if ( file_exists( "' . $firewallFilePath . '" ) ) {' . "\n"; $contents .= ' require_once "' . $firewallFilePath . '";' . "\n"; $contents .= '}' . "\n\n"; } $contents .= "//RULES START\n" . $rules; $this->put_contents( $this->file, $contents ); } /** * Save data to a file */ private function put_contents(string $file, string $contents ): void { if ( ! rsssl_admin_logged_in() ) { return; } if ( !is_file($file) || $this->is_writable($file)) { // $wp_filesystem = $this->init_file_system(); // $result = $wp_filesystem->put_contents($contents, $this->file); file_put_contents( $file, $contents );//phpcs:ignore } else if ( !$this->is_writable($file)) { return; } //only chmod other files than .htaccess and wpconfig. We leave these as is. if ( strpos($file, 'htaccess') === false || strpos($file, 'wp-config.php') === false ) { if ( $this->file_exists( $this->file) ) { chmod( $this->file, 0644 );//phpcs:ignore } } } /** * Get the contents of a file */ private function get_contents( string $file ): string { if ( ! $this->file_exists( $file ) ) { return ''; } return file_get_contents( $file );//phpcs:ignore } /** * Delete a file */ private function delete_file(): void { if ( ! rsssl_user_can_manage() ) { return; } if ( $this->file_exists( $this->file ) ) { unlink( $this->file );//phpcs:ignore } } /** * Check if installation uses htaccess.conf (Bitnami) */ private function uses_htaccess_conf(): bool { $htaccess_conf_file = dirname( ABSPATH ) . '/conf/htaccess.conf'; //conf/htaccess.conf can be outside of open basedir, return false if so $open_basedir = ini_get( 'open_basedir' ); if ( ! empty( $open_basedir ) ) { return false; } return is_file( $htaccess_conf_file ); } /** * Get the .htaccess path */ private function htaccess_path(): string { if ( $this->uses_htaccess_conf() ) { $htaccess_file = realpath( dirname( ABSPATH ) . '/conf/htaccess.conf' ); } else { $htaccess_file = $this->get_home_path() . '.htaccess'; } return $htaccess_file; } /** * Get the home path */ public function get_home_path(): string { if ( ! function_exists( 'get_home_path' ) ) { include_once ABSPATH . 'wp-admin/includes/file.php'; } if ( defined('RSSSL_IS_FLYWHEEL') && RSSSL_IS_FLYWHEEL && isset( $_SERVER['DOCUMENT_ROOT'] ) ) { return trailingslashit( $this->sanitize_path( wp_unslash( $_SERVER['DOCUMENT_ROOT'] ) ) ); } return get_home_path(); } /** * Sanitize a path */ private function sanitize_path( string $path ): string { // prevent path traversal. return preg_replace( '/\.\.\//', '/', realpath( sanitize_text_field( $path ) ) ); } /** * Check if this server uses .htaccess. Not by checking the server header, but simply by checking * if the htaccess file exists. */ private function uses_htaccess(): bool { return $this->file_exists( $this->htaccess_path() ); } /** * Include the prepend file in the .htaccess */ public function include_prepend_file_in_htaccess(): void { if ( ! $this->file_exists( $this->file ) ) { return; } // check if the wp-config contains the if constant condition, to prevent duplicate loading. If not, try upgrading. If that fails, skip. if ( ! $this->wp_config_contains_latest() ) { return; } $htaccess_file = $this->htaccess_path(); if ( !$this->file_exists($htaccess_file) || !$this->is_writable($htaccess_file) ) { return; } $htaccess_manager = new RSSSL_Htaccess_File_Manager(); $rules_string = $this->get_htaccess_rules(); $rule_definition = [ 'marker' => self::HTACCESS_MARKER_PREPEND, 'lines' => empty(trim($rules_string)) ? [] : explode("\n", $rules_string), ]; $htaccess_manager->write_rule($rule_definition, 'include prepend file in htaccess'); } /** * Get the .htaccess rules for the prepend file * Add user.ini blocking rules if user.ini filename exist. */ private function get_htaccess_rules() : string { if ( defined('RSSSL_HTACCESS_SKIP_AUTO_PREPEND') && RSSSL_HTACCESS_SKIP_AUTO_PREPEND ) { return ''; } if (isset(RSSSL()->server) ) { $config = RSSSL()->server->auto_prepend_config(); } else { $config = get_option('rsssl_auto_prepend_config'); if (empty($config)) { return ''; } } $file = addcslashes($this->file, "'"); switch ($config) { case 'litespeed': $rules = array( '', 'php_value auto_prepend_file ' . $file , '', '', 'php_value auto_prepend_file ' . $file, '', ); break; case 'apache-mod_php': default: $rules = array( '', 'php_value auto_prepend_file ' . $file , '', '', 'php_value auto_prepend_file ' . $file, '', ); } $userIni = ini_get('user_ini.filename'); if ($userIni) { array_push( $rules, sprintf( '', addcslashes( $userIni, '"' ) ), '', 'Require all denied', '', '', 'Order deny,allow', 'Deny from all', '', '' ); } return implode( "\n", $rules ); } /** * Include the file in the wp-config */ private function include_prepend_file_in_wp_config(): void { if ( ! rsssl_user_can_manage() ) { return; } $file = $this->wpconfig_path(); $content = $this->get_contents( $file ); if ( $this->is_writable( $file ) && strpos( $content, 'advanced-headers.php' ) === false ) { $rule = $this->get_wp_config_rule(); // if RSSSL comment is found, insert after. $rsssl_comment = '//END Really Simple Security Server variable fix'; if ( strpos( $content, $rsssl_comment ) !== false ) { $pos = strrpos( $content, $rsssl_comment ); $updated = substr_replace( $content, $rsssl_comment . "\n" . $rule . "\n", $pos, strlen( $rsssl_comment ) ); } else { $updated = preg_replace( '/<\?php/', "put_contents( $file, $updated ); } // save errors. if ( $this->is_writable( WP_CONTENT_DIR ) && ( $this->is_writable( $file ) || strpos( $content, 'advanced-headers.php' ) !== false ) ) { update_option( 'rsssl_firewall_error', false, false ); } elseif ( ! $this->is_writable( $file ) ) { update_option( 'rsssl_firewall_error', 'wpconfig-notwritable', false ); } elseif ( ! $this->is_writable( WP_CONTENT_DIR ) ) { update_option( 'rsssl_firewall_error', 'advanced-headers-notwritable', false ); } } /** * Clear the rules */ public function remove_prepend_file_in_htaccess(): void { if ( ! rsssl_user_can_manage() ) { return; } // Determine the correct .htaccess file path this instance of firewall manager should use. $specific_htaccess_path = $this->htaccess_path(); // Ensure the injected htaccess_file_manager service instance is configured to use this specific path. $this->htAccessFile->set_htaccess_file_path($specific_htaccess_path); // Call clear_rule on the htaccess_file_manager service. // The service itself is responsible for handling file existence and writability. $this->htAccessFile->clear_rule(self::HTACCESS_MARKER_PREPEND, 'testregel'); } /** * Remove the prepend file from the config */ private function remove_prepend_file_in_wp_config(): void { if ( ! rsssl_user_can_manage() ) { return; } $file = $this->wpconfig_path(); if ( $this->is_writable( $file ) ) { $content = $this->get_contents( $file ); $rule = $this->get_wp_config_rule(); if ( strpos( $content, $rule ) !== false ) { $content = str_replace( $rule, '', $content ); if ( strpos( $content, "\n\n\n" ) !== false ) { $content = str_replace( "\n\n\n", "\n\n", $content ); } $this->put_contents( $file, $content ); } } } /** * Wrapper function */ private function is_writable( string $fileNameIncludingPath ): bool { return is_writable( $fileNameIncludingPath ); } /** * This class has its own settings page, to ensure it can always be called */ public function is_settings_page(): bool { if ( rsssl_is_logged_in_rest() ) { return true; } if ( isset( $_GET['page'] ) && 'really-simple-security' === $_GET['page'] ) {//phpcs:ignore return true; } return false; } /** * Generate and return a random nonce */ public function get_headers_nonce(): int { if ( ! get_site_option( 'rsssl_header_detection_nonce' ) ) { update_site_option( 'rsssl_header_detection_nonce', wp_rand( 1000, 999999999 ) ); } return (int) get_site_option( 'rsssl_header_detection_nonce' ); } /** * Check if any rules were added */ public function has_rules(): bool { if ( empty( $this->rules ) ) { $this->rules = apply_filters( 'rsssl_firewall_rules', '' ); } return ! empty( trim( $this->rules ) ); } /** * Get the status for the firewall rules writing */ public function firewall_write_error() { return get_site_option( 'rsssl_firewall_error' ); } /** * Get the status for the firewall rules loading */ public function firewall_active_error(): bool { if ( ! $this->has_rules() ) { return false; } return ! defined( 'RSSSL_HEADERS_ACTIVE' ); } /** * Show some notices */ public function notices( array $notices ): array { $notices['firewall-error'] = array( 'callback' => 'RSSSL_SECURITY()->firewall_manager->firewall_write_error', 'score' => 5, 'output' => array( 'wpconfig-notwritable' => array( 'title' => __( 'Firewall', 'really-simple-ssl' ), 'msg' => __( 'A firewall rule was enabled, but the wp-config.php is not writable.', 'really-simple-ssl' ) . ' ' . __( 'Please set the wp-config.php to writable until the rule has been written.', 'really-simple-ssl' ), 'icon' => 'open', 'dismissible' => true, ), 'advanced-headers-notwritable' => array( 'title' => __( 'Firewall', 'really-simple-ssl' ), 'msg' => __( 'A firewall rule was enabled, but /the wp-content/ folder is not writable.', 'really-simple-ssl' ) . ' ' . __( 'Please set the wp-content folder to writable:', 'really-simple-ssl' ), 'icon' => 'open', 'dismissible' => true, ), ), 'show_with_options' => array( 'disable_http_methods', ), ); $notices['firewall-active'] = array( 'condition' => array( 'RSSSL_SECURITY()->firewall_manager->firewall_active_error' ), 'callback' => '_true_', 'score' => 5, 'output' => array( 'true' => array( 'title' => __( 'Firewall', 'really-simple-ssl' ), 'msg' => __( 'A firewall rule was enabled, but the firewall does not seem to get loaded correctly.', 'really-simple-ssl' ) . ' ' . __( 'Please check if the advanced-headers.php file is included in the wp-config.php, and exists in the wp-content folder.', 'really-simple-ssl' ), 'icon' => 'open', 'dismissible' => true, ), ), 'show_with_options' => array( 'disable_http_methods', ), ); return $notices; } /** * // As WP_CONTENT_DIR is not defined at this point in the wp-config, we can't use that. * // for those setups where the WP_CONTENT_DIR is not in the default location, we hardcode the path. */ public function get_wp_config_rule(): string { if ( $this->use_dynamic_path ) { $rule = 'if (!defined("RSSSL_HEADERS_ACTIVE") && file_exists( ABSPATH . "wp-content/advanced-headers.php")) {' . "\n"; $rule .= "\t" . 'require_once ABSPATH . "wp-content/advanced-headers.php";' . "\n" . '}'; } else { $rule = 'if (!defined("RSSSL_HEADERS_ACTIVE") && file_exists(\'' . WP_CONTENT_DIR . '/advanced-headers.php\')) {' . "\n"; $rule .= "\t" . 'require_once \'' . WP_CONTENT_DIR . '/advanced-headers.php\';' . "\n" . '}'; } return $rule; } /** * Check if the wp-config contains the if constant condition, to prevent duplicate loading. If not, try upgrading. If that fails, skip. * Wrapper function added for clearer purpose in code */ private function wp_config_contains_latest(): bool { return $this->update_wp_config_rule(); } /** * Called in upgrade.php, to upgrade older rules to the latest. * Returns true if the wpconfig contains the upgraded lines */ public function update_wp_config_rule(): bool { $file = $this->wpconfig_path(); if ( ! $file ) { return false; } $content = $this->get_contents( $file ); $find = '(file_exists( ABSPATH . "wp-content/advanced-headers.php"))'; if ( false !== strpos( $content, $find ) ) { if ( ! $this->is_writable( $file ) ) { return false; } $replace = '(!defined("RSSSL_HEADERS_ACTIVE") && file_exists( ABSPATH . "wp-content/advanced-headers.php"))'; $content = str_replace( $find, $replace, $content ); $this->put_contents( $file, $content ); } return true; } /** * Admin is not always loaded here, so we define our own function */ public function wpconfig_path(): ?string { // Allow the wp-config.php path to be overridden via a filter. $filtered_path = apply_filters( 'rsssl_wpconfig_path', '' ); // If a filtered path is provided, validate it. if ( ! empty( $filtered_path ) ) { $directory = dirname( $filtered_path ); // Ensure the directory exists before checking for the file. if ( is_dir( $directory ) && file_exists( $filtered_path ) ) { return $filtered_path; } } // Limit number of iterations to 5. $i = 0; $maxiterations = 5; $dir = ABSPATH; do { ++ $i; if ( $this->file_exists( $dir . 'wp-config.php' ) ) { return $dir . 'wp-config.php'; } } while ( ( $dir = "$dir/.." ) && ( $i < $maxiterations ) ); return ''; } /** * Clear the headers */ public function remove_advanced_headers(): void { $this->uninstall(); } /** * Check if a user.ini file exists or is in user.ini format. */ private function has_user_ini_file(): bool { if ( ini_get('user_ini.filename') ) { return true; } return false; } /** * Add auto prepend file to user.ini */ private function include_prepend_file_in_user_ini(): void { if ( ! rsssl_user_can_manage() ) { return; } if ( defined('RSSSL_HTACCESS_SKIP_AUTO_PREPEND') && RSSSL_HTACCESS_SKIP_AUTO_PREPEND ) { return; } $config = RSSSL()->server->auto_prepend_config(); if ( !$this->has_user_ini_file() ) { return; } $autoPrependIni = ''; $userIniPath = $this->get_user_ini_path(); if ($userIniPath === null) { return; } // .user.ini configuration switch ($config) { case 'cgi': case 'nginx': case 'apache-suphp': case 'litespeed': case 'iis': $autoPrependIni = sprintf("; BEGIN Really Simple Auto Prepend File auto_prepend_file = '%s' ; END Really Simple Auto Prepend File", addcslashes($this->file, "'")); break; } if ( !empty($autoPrependIni) ) { // Modify .user.ini $userIniContent = $this->get_contents($userIniPath); if ( $userIniContent ) { $userIniContent = str_replace('auto_prepend_file', ';auto_prepend_file', $userIniContent); $regex = '/; BEGIN Really Simple Auto Prepend File.*?; END Really Simple Auto Prepend File/is'; if (preg_match($regex, $userIniContent )) { $userIniContent = preg_replace($regex, $autoPrependIni, $userIniContent); } else { $userIniContent .= "\n" . $autoPrependIni; } } else { $userIniContent = $autoPrependIni; } $this->put_contents($userIniPath, $userIniContent); } } /** * Get the user.ini path */ public function get_user_ini_path():? string { $userIni = ini_get('user_ini.filename'); if ($userIni) { return $this->get_home_path() . $userIni; } return null; } /** * Remove the added auto prepend file */ private function remove_auto_prepend_file_in_user_ini(): void { if ( ! rsssl_user_can_manage() ) { return; } if ( ! $this->has_user_ini_file() ) { return; } $userIniPath = $this->get_user_ini_path(); if ($userIniPath === null) { return; } $userIniContent = $this->get_contents( $userIniPath ); $userIniContent = preg_replace( '/; BEGIN Really Simple Auto Prepend File.*?; END Really Simple Auto Prepend File/is', '', $userIniContent ); $userIniContent = str_replace( 'auto_prepend_file', ';auto_prepend_file', $userIniContent ); $this->put_contents( $userIniPath, $userIniContent ); } }