From e9ae604b63ebbc387cfd23647af9b751043a6521 Mon Sep 17 00:00:00 2001 From: Pablo Hinojosa Date: Wed, 4 Jun 2025 08:39:27 +0200 Subject: [PATCH 1/9] feat: Add rule SAMEORIGIN to htaccess refs: #NHH-953 --- index.php | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/index.php b/index.php index 457955c..a06fb8b 100644 --- a/index.php +++ b/index.php @@ -11,6 +11,16 @@ exit; } +function wp_security_activation() +{ + if (!is_admin()) { + return; + } + wp_security_add_htaccess_rules(); +} +register_activation_hook( __FILE__, 'wp_security_activation' ); + + add_action( 'init', 'wp_security_github_plugin_updater' ); function wp_security_github_plugin_updater() { @@ -74,6 +84,20 @@ function wp_security_sar_block_xmlrpc_attacks( $methods ) { return $methods; } +/** + * Add rules to HTACCESS file + */ +function wp_security_add_htaccess_rules(){ + $blocks = array( + "\nHeader set X-Frame-Options SAMEORIGIN\n", + ); + $marker = "WpSecurityPlugin"; + $htaccess_path = ABSPATH . '.htaccess'; + if (file_exists($htaccess_path)) { + insert_with_markers($htaccess_path, $marker, $blocks); + } +} + /** * Check WP version. */ From be6666745837cce206d3301d05722980eb24a2e4 Mon Sep 17 00:00:00 2001 From: Pablo Hinojosa Date: Wed, 4 Jun 2025 09:13:57 +0200 Subject: [PATCH 2/9] feat: securize Cookies refs: #NHH-953 --- index.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/index.php b/index.php index a06fb8b..abf1d81 100644 --- a/index.php +++ b/index.php @@ -49,6 +49,14 @@ function wp_security_custom_author_url(){ } add_filter('author_link', 'wp_security_custom_author_url'); +function wp_security_secure_cookie() { + @ini_set('session.cookie_httponly', true); + @ini_set('session.cookie_secure', true); + @ini_set('session.use_only_cookies', true); + @ini_set('session.use_strict_mode', 1); +} +add_action('plugins_loaded', 'wp_security_secure_cookie'); + function wp_security_disable_feed(){ global $wp_query; $wp_query->set_404(); From efa61319c6f17e72fda08a6f57c9fd5dfc400b64 Mon Sep 17 00:00:00 2001 From: Pablo Hinojosa Date: Wed, 4 Jun 2025 11:34:09 +0200 Subject: [PATCH 3/9] feat: Actions on load, update and unload plugin refs: #NHH-953 --- index.php | 139 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 91 insertions(+), 48 deletions(-) diff --git a/index.php b/index.php index abf1d81..54e0394 100644 --- a/index.php +++ b/index.php @@ -11,21 +11,52 @@ exit; } -function wp_security_activation() +const WPSP_HTACCESS_MARKER = "WpSecurityPlugin"; +const WPSP_HTACCESS_BLOCKS = array( + "\nHeader set X-Frame-Options SAMEORIGIN\n", +); + + +function wp_security_plugin_activation() { if (!is_admin()) { return; } - wp_security_add_htaccess_rules(); + wp_security_execute_on_plugin_update(); } -register_activation_hook( __FILE__, 'wp_security_activation' ); +register_activation_hook(__FILE__, 'wp_security_plugin_activation'); +function wp_security_plugin_loaded() +{ + if (is_admin()) { + $previous_version = get_option('wp-security-plugin-version', 0); + if ($previous_version != wp_security_get_plugin_version()) { + wp_security_execute_on_plugin_update(); + } + } + wp_security_secure_cookie(); + wp_security_remove_feed_after_load(); +} +add_action('plugins_loaded', 'wp_security_plugin_loaded'); + +function wp_security_plugin_deactivate() +{ + wp_security_add_htaccess_rules(["# WP Security plugin deactivated", "# this block can be safely removed"]); +} -add_action( 'init', 'wp_security_github_plugin_updater' ); +add_action("deactivate_plugin", "wp_security_plugin_deactivate", 10, 1); -function wp_security_github_plugin_updater() { + +function wp_security_execute_on_plugin_update() +{ + update_option('wp-security-plugin-version', wp_security_get_plugin_version()); + wp_security_add_htaccess_rules(); +} + +function wp_security_github_plugin_updater() +{ include_once('updater.php'); - define( 'WP_GITHUB_FORCE_UPDATE', true ); + define('WP_GITHUB_FORCE_UPDATE', true); if (is_admin()) { // note the use of is_admin() to double check that this is happening in the admin $config = array( @@ -43,21 +74,25 @@ function wp_security_github_plugin_updater() { new WP_GitHub_Updater($config); } } +add_action('init', 'wp_security_github_plugin_updater'); -function wp_security_custom_author_url(){ + +function wp_security_custom_author_url() +{ return home_url('/'); } add_filter('author_link', 'wp_security_custom_author_url'); -function wp_security_secure_cookie() { +function wp_security_secure_cookie() +{ @ini_set('session.cookie_httponly', true); @ini_set('session.cookie_secure', true); @ini_set('session.use_only_cookies', true); @ini_set('session.use_strict_mode', 1); } -add_action('plugins_loaded', 'wp_security_secure_cookie'); -function wp_security_disable_feed(){ +function wp_security_disable_feed() +{ global $wp_query; $wp_query->set_404(); status_header(404); @@ -65,7 +100,8 @@ function wp_security_disable_feed(){ exit; } -function wp_security_remove_feed_after_load(){ +function wp_security_remove_feed_after_load() +{ add_action('do_feed', 'wp_security_disable_feed', 1); add_action('do_feed_rdf', 'wp_security_disable_feed', 1); add_action('do_feed_rss', 'wp_security_disable_feed', 1); @@ -77,59 +113,66 @@ function wp_security_remove_feed_after_load(){ remove_action('wp_head', 'feed_links', 2); } -add_action('plugins_loaded', 'wp_security_remove_feed_after_load'); - -add_filter( 'xmlrpc_methods', 'wp_security_sar_block_xmlrpc_attacks' ); - /** * Unset XML-RPC Methods. * * @param array $methods Array of current XML-RPC methods. */ -function wp_security_sar_block_xmlrpc_attacks( $methods ) { - unset( $methods['pingback.ping'] ); - unset( $methods['pingback.extensions.getPingbacks'] ); - return $methods; +function wp_security_sar_block_xmlrpc_attacks($methods) +{ + unset($methods['pingback.ping']); + unset($methods['pingback.extensions.getPingbacks']); + return $methods; } +add_filter('xmlrpc_methods', 'wp_security_sar_block_xmlrpc_attacks'); /** * Add rules to HTACCESS file */ -function wp_security_add_htaccess_rules(){ - $blocks = array( - "\nHeader set X-Frame-Options SAMEORIGIN\n", - ); - $marker = "WpSecurityPlugin"; +function wp_security_add_htaccess_rules($rules = null) +{ + if (!$rules) { + $rules = WPSP_HTACCESS_BLOCKS; + } $htaccess_path = ABSPATH . '.htaccess'; if (file_exists($htaccess_path)) { - insert_with_markers($htaccess_path, $marker, $blocks); + insert_with_markers($htaccess_path, WPSP_HTACCESS_MARKER, $rules); } } +function wp_security_get_plugin_version() +{ + $plugin_data = get_plugin_data(__FILE__); + return $plugin_data['Version']; +} + + /** * Check WP version. */ -if ( version_compare( get_bloginfo( 'version' ), '4.4', '>=' ) ) { - - add_action( 'wp', 'wp_security_sar_remove_x_pingback_header_44', 9999 ); - - /** - * Remove X-Pingback from Header for WP 4.4+. - */ - function wp_security_sar_remove_x_pingback_header_44() { - header_remove( 'X-Pingback' ); - } -} elseif ( version_compare( get_bloginfo( 'version' ), '4.4', '<' ) ) { - - add_filter( 'wp_headers', 'wp_security_sar_remove_x_pingback_header' ); - - /** - * Remove X-Pingback from Header for older WP versions. - * - * @param array $headers Array with current headers. - */ - function wp_security_sar_remove_x_pingback_header( $headers ) { - unset( $headers['X-Pingback'] ); - return $headers; - } +if (version_compare(get_bloginfo('version'), '4.4', '>=')) { + + add_action('wp', 'wp_security_sar_remove_x_pingback_header_44', 9999); + + /** + * Remove X-Pingback from Header for WP 4.4+. + */ + function wp_security_sar_remove_x_pingback_header_44() + { + header_remove('X-Pingback'); + } +} elseif (version_compare(get_bloginfo('version'), '4.4', '<')) { + + add_filter('wp_headers', 'wp_security_sar_remove_x_pingback_header'); + + /** + * Remove X-Pingback from Header for older WP versions. + * + * @param array $headers Array with current headers. + */ + function wp_security_sar_remove_x_pingback_header($headers) + { + unset($headers['X-Pingback']); + return $headers; + } } From c289b4c87a0363cfa6dcf73ba61892af46f2815f Mon Sep 17 00:00:00 2001 From: Pablo Hinojosa Date: Wed, 4 Jun 2025 13:37:12 +0200 Subject: [PATCH 4/9] fix: More URLs to .htaccess refs: #NHH-953 --- index.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/index.php b/index.php index 54e0394..bd3d7c0 100644 --- a/index.php +++ b/index.php @@ -2,7 +2,7 @@ /** * Plugin Name: POLA-CDK - WP Security * Description: Improves security of WordPress - * Version: 1.0.2 + * Version: 1.0.3 * Author: Pola Network * Author URI: https://github.com/Codeko/wp-security */ @@ -14,6 +14,10 @@ const WPSP_HTACCESS_MARKER = "WpSecurityPlugin"; const WPSP_HTACCESS_BLOCKS = array( "\nHeader set X-Frame-Options SAMEORIGIN\n", + "RewriteEngine On\nRewriteCond %{REQUEST_URI} ^/wp-cron.php\nRewriteRule ^(.*)$ - [L,R=404]", + "RewriteEngine On\nRewriteCond %{REQUEST_URI} ^/.git\nRewriteRule ^(.*)$ - [L,R=404]", + "RewriteEngine On\nRewriteCond %{REQUEST_URI} ^/readme.html\nRewriteRule ^(.*)$ - [L,R=404]", + "RewriteEngine On\nRewriteCond %{REQUEST_URI} ^/xmlrpc.php\nRewriteRule ^(.*)$ - [L,R=404]", ); @@ -41,7 +45,7 @@ function wp_security_plugin_loaded() function wp_security_plugin_deactivate() { - wp_security_add_htaccess_rules(["# WP Security plugin deactivated", "# this block can be safely removed"]); + wp_security_add_htaccess_rules(["# WP Security plugin is deactivated", "# this block can be safely removed"]); } add_action("deactivate_plugin", "wp_security_plugin_deactivate", 10, 1); From 5d86bb032b98c1de983542d09f5826a09694beea Mon Sep 17 00:00:00 2001 From: Pablo Hinojosa Date: Wed, 4 Jun 2025 13:38:07 +0200 Subject: [PATCH 5/9] =?UTF-8?q?feat:=20hide=20informati=C3=B3n=20from=20lo?= =?UTF-8?q?gin=20erros?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit refs: #NHH-953 --- index.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/index.php b/index.php index bd3d7c0..2289e28 100644 --- a/index.php +++ b/index.php @@ -95,6 +95,15 @@ function wp_security_secure_cookie() @ini_set('session.use_strict_mode', 1); } +function wp_security_login_error_message( $message ) { + if ( strpos( $message, "ERROR:" ) !== false ) { + $message = "Incorrect username or password."; + } + return $message; +} +add_filter( 'login_errors', 'wp_security_login_error_message' ); + + function wp_security_disable_feed() { global $wp_query; From f4ca36b97a6609ca803ec0ecd5cea96ee2e6be79 Mon Sep 17 00:00:00 2001 From: Pablo Hinojosa Date: Wed, 4 Jun 2025 13:39:05 +0200 Subject: [PATCH 6/9] feat: hide list users on REST API refs: #NHH-953 --- index.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/index.php b/index.php index 2289e28..cd91622 100644 --- a/index.php +++ b/index.php @@ -103,6 +103,18 @@ function wp_security_login_error_message( $message ) { } add_filter( 'login_errors', 'wp_security_login_error_message' ); +function wp_security_hide_users_list( $errors ) { + + $path = ltrim( $GLOBALS['wp']->query_vars['rest_route'], '/' ); + + if ( strpos( $path, 'wp/v2/users' ) !== false ) { + return new WP_Error( 'rest_no_route', "No route was found matching the URL and request method.", array( 'status' => 404 ) ); + } + + return $errors; +} +add_filter( 'rest_authentication_errors','wp_security_hide_users_list'); + function wp_security_disable_feed() { From 37f239def89bf6148b14171451fd46bcf4aa888c Mon Sep 17 00:00:00 2001 From: Pablo Hinojosa Date: Thu, 5 Jun 2025 07:37:55 +0200 Subject: [PATCH 7/9] feat: Check HTTP "Server" header Show admin alert if the header may provide version information refs: #NHH-953 --- index.php | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/index.php b/index.php index cd91622..1e6e417 100644 --- a/index.php +++ b/index.php @@ -171,6 +171,26 @@ function wp_security_get_plugin_version() return $plugin_data['Version']; } +function wp_security_admin_notice() { + file_get_contents(site_url()); + $server_header = ""; + foreach ($http_response_header as $key => $value) { + if (substr(strtolower($value), 0, 7) == "server:") { + $server_header = $value; + } + } + if (strlen($server_header) > 9) { + ?> +
+

POLA-CDK - WP Security information:

+

+ . +

+
+ Date: Thu, 5 Jun 2025 07:43:36 +0200 Subject: [PATCH 8/9] fix: HTTP "Server" header can be to 14 characters "Server: Apache" or "Server: Nginx" is valid refs: #NHH-953 --- index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.php b/index.php index 1e6e417..5d8be8b 100644 --- a/index.php +++ b/index.php @@ -179,7 +179,7 @@ function wp_security_admin_notice() { $server_header = $value; } } - if (strlen($server_header) > 9) { + if (strlen($server_header) > 14) { ?>

POLA-CDK - WP Security information:

From 7092c4246f35e881c82eb234c3f32c1e9efcc8a2 Mon Sep 17 00:00:00 2001 From: Pablo Hinojosa Date: Thu, 5 Jun 2025 07:49:07 +0200 Subject: [PATCH 9/9] refactor: Increment version number refs: #NHH-953 --- index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.php b/index.php index 5d8be8b..62ed2b9 100644 --- a/index.php +++ b/index.php @@ -2,7 +2,7 @@ /** * Plugin Name: POLA-CDK - WP Security * Description: Improves security of WordPress - * Version: 1.0.3 + * Version: 1.1.0 * Author: Pola Network * Author URI: https://github.com/Codeko/wp-security */