File Editor
Directories:
.. (Back)
server
tests
wordpress
Files:
cron.php
deactivate-integration.php
firewall-manager.php
functions.php
hardening.php
index.php
integrations.php
notices.php
security.php
sync-settings.php
tests.php
Create New File
Create
Edit File: tests.php
<?php defined( 'ABSPATH' ) or die(); /** * Check if XML-RPC requests are allowed on this site * POST a request, if the request returns a 200 response code the request is allowed */ function rsssl_xmlrpc_allowed() { $allowed = get_transient( 'rsssl_xmlrpc_allowed' ); if ( !$allowed ) { $allowed = 'allowed'; if ( function_exists( 'curl_init' ) ) { //set a default, in case of time out set_transient( 'rsssl_xmlrpc_allowed', 'no-response', DAY_IN_SECONDS ); $url = site_url() . '/xmlrpc.php'; $ch = curl_init($url); // XML-RPC listMethods call // Valid XML-RPC request $xmlstring = '<?xml version="1.0" encoding="utf-8"?> <methodCall> <methodName>system.listMethods</methodName> <params></params> </methodCall>'; curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // Post string curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlstring ); curl_setopt($ch, CURLOPT_TIMEOUT, 3); //timeout in seconds curl_exec($ch); $response_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($response_code === 200) { $allowed = 'allowed'; } else { $allowed = 'not-allowed'; } } set_transient( 'rsssl_xmlrpc_allowed', $allowed, DAY_IN_SECONDS ); } return $allowed === 'allowed'; } /** * @return bool * Test if HTTP methods are allowed */ function rsssl_http_methods_allowed() { if ( ! rsssl_user_can_manage() ) { return false; } $methods = [ 'GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS', 'CONNECT', 'TRACE', 'TRACK', 'PATCH', 'COPY', 'LINK', 'UNLINK', 'PURGE', 'LOCK', 'UNLOCK', 'PROPFIND', 'VIEW', ]; $tested = get_option( 'rsssl_http_methods_allowed' ); #if the option was reset, start couting from 0 if ( !$tested ){ delete_option('rsssl_last_tested_http_method'); } $last_tested = get_option('rsssl_last_tested_http_method', -1); $nr_of_tests_on_batch = 4; if ( !$tested || ( $last_tested < count($methods)-1 ) ) { $tested = get_option( 'rsssl_http_methods_allowed', [] ); $next_test = $last_tested+1; $test_methods = array_slice($methods, $next_test, $nr_of_tests_on_batch, true); update_option('rsssl_last_tested_http_method', $last_tested+$nr_of_tests_on_batch, false); foreach ( $test_methods as $method ) { #set a default, in case a timeout occurs $tested['not-allowed'][] = $method; update_option( 'rsssl_http_methods_allowed', $tested, false ); if ( function_exists( 'curl_init' ) ) { $ch = curl_init(); curl_setopt( $ch, CURLOPT_URL, site_url() ); curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, $method ); curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true ); curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false ); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); curl_setopt( $ch, CURLOPT_HEADER, true ); curl_setopt( $ch, CURLOPT_NOBODY, true ); curl_setopt( $ch, CURLOPT_VERBOSE, true ); curl_setopt( $ch, CURLOPT_TIMEOUT, 3 ); //timeout in seconds curl_exec( $ch ); #if there are no errors, the request is allowed if ( ! curl_errno( $ch ) ) { //remove the not allowed entry $not_allowed_index = array_search( $method, $tested['not-allowed'], true ); if ( $not_allowed_index !== false ) { unset( $tested['not-allowed'][ $not_allowed_index ] ); } $tested['allowed'][] = $method; } curl_close( $ch ); update_option( 'rsssl_http_methods_allowed', $tested, false ); } } } if ( !empty($tested['allowed'])) { return true; } return false; } /** * @return bool * * Check if DB has default wp_ prefix */ function rsssl_is_default_wp_prefix() { global $wpdb; if ( $wpdb->prefix === 'wp_' ) { return true; } return false; } function rsssl_xmlrpc_enabled(){ return apply_filters('xmlrpc_enabled', true ); } /** * @return bool * * Check if user admin exists */ function rsssl_has_admin_user() { if ( !rsssl_user_can_manage() ) { return false; } //transient is more persistent then wp cache set $count = get_transient('rsssl_admin_user_count'); //get from cache, but not on settings page if ( $count === false || RSSSL()->admin->is_settings_page() ){ //use wp_cache_get to prevent duplicate queries in one pageload $count = wp_cache_get('rsssl_admin_user_count', 'really-simple-ssl'); if ( $count === false ) { global $wpdb; $count = $wpdb->get_var( "SELECT COUNT(*) FROM {$wpdb->base_prefix}users WHERE user_login = 'admin'" ); wp_cache_set('rsssl_admin_user_count', $count, 'really-simple-ssl', HOUR_IN_SECONDS ); } set_transient('rsssl_admin_user_count', $count, HOUR_IN_SECONDS); } return $count > 0; } /** * Check if username is valid for use * @return bool */ function rsssl_new_username_valid(): bool { $new_user_login = trim(sanitize_user(rsssl_get_option('new_admin_user_login'))); if ( $new_user_login === 'admin' ) { return false; } $user_exists = get_user_by('login', $new_user_login); if ( $user_exists ) { return false; } return is_string($new_user_login) && strlen($new_user_login)>2; } /** * For backward compatibility we need to wrap this function, as older versions do not have this function (<5.6) * @return bool */ function rsssl_wp_is_application_passwords_available(){ if ( function_exists('wp_is_application_passwords_available') ) { return wp_is_application_passwords_available(); } return false; } /** * Get users where display name is the same as login * * @param bool $return_users * * @return bool | array * */ function rsssl_get_users_where_display_name_is_login( $return_users=false ) { $found_users = []; $users = get_transient('rsssl_admin_users'); if ( !$users ){ $args = array( 'role' => 'administrator', ); $users = get_users( $args ); set_transient('rsssl_admin_users', $users, HOUR_IN_SECONDS); } foreach ( $users as $user ) { if ($user->display_name === $user->user_login) { $found_users[] = $user->user_login; } } // Maybe return users in integration if ( $return_users ) { return $found_users; } if ( count($found_users) > 0 ) { return true; } return false; } /** * Check if debugging in WordPress is enabled * * @return bool */ function rsssl_is_debugging_enabled() { return ( defined('WP_DEBUG') && WP_DEBUG && defined('WP_DEBUG_LOG') && WP_DEBUG_LOG ); } function rsssl_debug_log_value_is_default(){ $value = rsssl_get_debug_log_value(); return (string) $value === 'true'; } /** * Get value of debug_log constant * Please note that for a value 'true', you should check for the string value === 'true' * @return bool|string */ function rsssl_get_debug_log_value(){ if ( !defined('WP_DEBUG_LOG')) { return false; } $wpconfig_path = rsssl_find_wp_config_path(); if ( !$wpconfig_path ) { return false; } $wpconfig = file_get_contents( $wpconfig_path ); // Get WP_DEBUG_LOG declaration $regex = "/^\s*define\([ ]{0,2}[\'|\"]WP_DEBUG_LOG[\'|\"][ ]{0,2},[ ]{0,2}(.*)[ ]{0,2}\);/m"; preg_match( $regex, $wpconfig, $matches ); if ($matches && isset($matches[1]) ){ return trim($matches[1]); } return false; } /** * Check if the debug log file exists in the default location, and if it contains our bogus info * @return bool * */ function rsssl_debug_log_file_exists_in_default_location(){ $default_file = trailingslashit(WP_CONTENT_DIR).'debug.log'; if ( !file_exists($default_file) ) { return false; } //limit max length of string to 500 $content = file_get_contents($default_file, false, null, 0, 500 ); return trim( $content ) !== 'Access denied'; } /** * @return string * Test if code execution is allowed in /uploads folder */ function rsssl_code_execution_allowed() { $code_execution_allowed = get_transient('rsssl_code_execution_allowed_status'); if ( !$code_execution_allowed ) { $upload_dir = wp_get_upload_dir(); //set a default, in case of timeouts $code_execution_allowed = 'not-allowed'; set_transient( 'rsssl_code_execution_allowed_status', $code_execution_allowed, DAY_IN_SECONDS ); $test_file = $upload_dir['basedir'] . '/' . 'code-execution.php'; if ( is_writable($upload_dir['basedir'] ) && ! file_exists( $test_file ) ) { try { copy( rsssl_path . 'security/tests/code-execution.php', $test_file ); } catch (Exception $e) { $code_execution_allowed = 'not-allowed'; } } if ( file_exists( $test_file ) ) { $uploads = wp_upload_dir(); $upload_url = trailingslashit($uploads['baseurl']).'code-execution.php'; $response = wp_remote_get($upload_url); if ( !is_wp_error($response) ) { if ( is_array( $response ) ) { $status = wp_remote_retrieve_response_code( $response ); $web_source = wp_remote_retrieve_body( $response ); } if ( $status != 200 ) { //Could not connect to website $code_execution_allowed = 'not-allowed'; } elseif ( strpos( $web_source, "RSSSL CODE EXECUTION MARKER" ) === false ) { //Mixed content fixer marker not found in the websource $code_execution_allowed = 'not-allowed'; } else { $code_execution_allowed = 'allowed'; } } else { $code_execution_allowed = 'not-allowed'; } } //clean up file again if ( file_exists($test_file) ) { unlink($test_file); } set_transient('rsssl_code_execution_allowed_status', $code_execution_allowed, DAY_IN_SECONDS); } return $code_execution_allowed === 'allowed'; } /** * Test if directory indexing is allowed * We assume allowed if test is not possible due to restrictions. Only an explicity 403 on the response results in "forbidden". * On non htaccess servers, the default is non indexing, so we return forbidden. * * @return bool */ function rsssl_directory_indexing_allowed() { $status = get_transient('rsssl_directory_indexing_status'); if ( !$status ) { if ( !rsssl_uses_htaccess() ) { $status = 'forbidden'; } else { $status = 'allowed'; //set a default, in case of timeouts set_transient( 'rsssl_directory_indexing_status', $status, DAY_IN_SECONDS ); try { $test_folder = 'indexing-test'; $test_dir = trailingslashit(ABSPATH) . $test_folder; if ( ! is_dir( $test_dir ) ) { mkdir( $test_dir, 0755 ); } $response = wp_remote_get(trailingslashit( site_url($test_folder) ) ); if ( is_dir( $test_dir ) ) { rmdir( $test_dir ); } // WP_Error doesn't contain response code, return false if ( !is_wp_error( $response ) ) { $response_code = $response['response']['code']; if ( $response_code === 403 ) { $status = 'forbidden'; } } } catch( Exception $e ) { } } set_transient('rsssl_directory_indexing_status', $status, DAY_IN_SECONDS ); } return $status !== 'forbidden'; } /** * Check if file editing is allowed * @return bool */ function rsssl_file_editing_allowed() { if ( function_exists('wp_is_block_theme') && wp_is_block_theme() ) { return false; } return !defined('DISALLOW_FILE_EDIT' ) || !DISALLOW_FILE_EDIT; } /** * Check if user registration is allowed * @return bool */ function rsssl_user_registration_allowed() { return get_option( 'users_can_register' ); } /** * Check if page source contains WordPress version information * @return bool */ function rsssl_src_contains_wp_version() { $result = get_option('rsssl_wp_version_detected' ); if ( $result===false ) { $result = 'no-response'; update_option( 'rsssl_wp_version_detected', 'no-response', false ); try { $wp_version = get_bloginfo( 'version' ); $web_source = ""; $response = wp_remote_get( home_url() ); if ( ! is_wp_error( $response ) ) { if ( is_array( $response ) ) { $status = wp_remote_retrieve_response_code( $response ); $web_source = wp_remote_retrieve_body( $response ); } if ( $status != 200 ) { $result = 'no-response'; } elseif ( strpos( $web_source, 'ver='.$wp_version ) === false ) { $result = 'not-found'; } else { $result = 'found'; } } update_option( 'rsssl_wp_version_detected', $result, false ); } catch(Exception $e) { update_option( 'rsssl_wp_version_detected', 'no-response', false ); } } return $result==='found'; } /** * Count the number of open hardening features * @return int */ function rsssl_count_open_hardening_features() { $open = 0; $fields = rsssl_fields( false ); // Filter out unused fields $recommended_hardening_fields = array_filter($fields, function($field){ return isset($field['recommended']) && $field['recommended']; }); // Create $hardening_options dynamically based on recommended field IDs $hardening_options = array_map(function($field) { return $field['id']; }, $recommended_hardening_fields); foreach ( $hardening_options as $option ) { // Get the field $field = array_filter( $fields, function ( $f ) use ( $option ) { return $f['id'] === $option; } ); if ( ! empty( $field ) ) { $field = reset( $field ); // Apply the rsssl_disable_fields filter $field = apply_filters( 'rsssl_field', $field, $field['id'] ); // Check if the option is not set to true and the field is not disabled if ( rsssl_get_option( $option ) !== true && ( ! isset( $field['disabled'] ) || $field['disabled'] !== true ) && ( ! isset( $field['value'] ) || $field['value'] !== true ) ) { $open ++; } } } return $open; } function rsssl_has_open_hardening_features() { return rsssl_count_open_hardening_features() > 0; }
Save Changes
Rename File
Rename