Changeset 3470719
- Timestamp:
- 02/26/2026 10:24:02 PM (4 weeks ago)
- Location:
- security-hardener
- Files:
-
- 5 added
- 2 edited
-
assets/blueprint.json (added)
-
tags/0.8 (added)
-
tags/0.8/readme.txt (added)
-
tags/0.8/security-hardener.php (added)
-
tags/0.8/uninstall.php (added)
-
trunk/readme.txt (modified) (3 diffs)
-
trunk/security-hardener.php (modified) (11 diffs)
Legend:
- Unmodified
- Added
- Removed
-
security-hardener/trunk/readme.txt
r3466602 r3470719 5 5 Tested up to: 6.9 6 6 Requires PHP: 8.0 7 Stable tag: 0. 77 Stable tag: 0.8 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 53 53 > ⚠️ **Important:** Always test security settings in a staging environment first. Some features may affect third-party integrations or plugins. 54 54 55 **Privacy:** This plugin does not send data to external services , does not create custom database tables, and only uses WordPress transients for temporary login attempt tracking.55 **Privacy:** This plugin does not send data to external services and does not create custom database tables. It stores plugin settings and a security event log in the WordPress options table, and uses transients for temporary login attempt tracking. All data is deleted on uninstall. 56 56 57 57 == Installation == … … 160 160 161 161 == Changelog == 162 163 = 0.8 - 2026-02-26 = 164 * Improved: Moved define_security_constants() from plugins_loaded hook to the constructor, ensuring DISALLOW_FILE_EDIT and DISALLOW_FILE_MODS are defined as early as possible in the WordPress lifecycle 165 * Improved: Expanded @param docblock for render_checkbox_field() to document all $args keys 166 * Added: WordPress Playground blueprint (assets/blueprints/blueprint.json) enabling live plugin preview directly from the WordPress.org plugin directory 167 * Fixed: Plugin header description updated to remove REST API restriction option removed in 0.5 168 * Fixed: Removed stale phpcs:ignore comment in show_admin_notices() — nonce verification is now correctly documented inline 169 * Fixed: Wrapped login block error message with wp_kses_post() for consistent output escaping 170 * Fixed: Added esc_url() and esc_html__() to add_settings_link() sprintf output 171 * Fixed: Removed redundant get_client_ip() call in log_security_event() — IP resolved once per event 172 * Fixed: Added autoload=false to wpsh_security_logs option — logs are only needed on the settings page, not loaded on every request 162 173 163 174 = 0.7 - 2026-02-21 = -
security-hardener/trunk/security-hardener.php
r3466602 r3470719 3 3 Plugin Name: Security Hardener 4 4 Plugin URI: https://wordpress.org/plugins/security-hardener/ 5 Description: Basic hardening: secure headers, disable XML-RPC/pingbacks, hide version, block user enumeration, login errors, IP-based rate limiting, and optional restriction of the REST API.6 Version: 0. 75 Description: Basic hardening: secure headers, disable XML-RPC/pingbacks, hide version, block user enumeration, generic login errors, and IP-based rate limiting. 6 Version: 0.8 7 7 Requires at least: 6.0 8 8 Tested up to: 6.9 … … 20 20 21 21 // Plugin constants 22 define( 'WPSH_VERSION', '0. 7' );22 define( 'WPSH_VERSION', '0.8' ); 23 23 define( 'WPSH_FILE', __FILE__ ); 24 24 define( 'WPSH_DIR', plugin_dir_path( __FILE__ ) ); … … 71 71 $this->options = $this->get_options(); 72 72 73 // Define security constants as early as possible 74 $this->define_security_constants(); 75 73 76 // Activation/Deactivation hooks 74 77 register_activation_hook( WPSH_FILE, array( $this, 'activate' ) ); … … 83 86 */ 84 87 public function init() { 85 // Define security constants early86 $this->define_security_constants();87 88 88 // Security headers 89 89 add_action( 'send_headers', array( $this, 'send_security_headers' ) ); … … 457 457 return new WP_Error( 458 458 'too_many_attempts', 459 '<strong>' . esc_html__( 'Error:', 'security-hardener' ) . '</strong> ' . sprintf( 460 /* translators: %d: number of minutes */ 461 esc_html__( 'Too many failed login attempts. Please try again in %d minutes.', 'security-hardener' ), 462 $minutes 459 wp_kses_post( 460 '<strong>' . esc_html__( 'Error:', 'security-hardener' ) . '</strong> ' . sprintf( 461 /* translators: %d: number of minutes */ 462 esc_html__( 'Too many failed login attempts. Please try again in %d minutes.', 'security-hardener' ), 463 $minutes 464 ) 463 465 ) 464 466 ); … … 638 640 $logs = get_option( 'wpsh_security_logs', array() ); 639 641 642 // Resolve IP once to avoid calling get_client_ip() twice 643 $ip = $this->get_client_ip(); 644 640 645 // Add new log entry 641 646 $logs[] = array( … … 643 648 'type' => $event_type, 644 649 'message' => $message, 645 'ip' => $ this->get_client_ip(),650 'ip' => $ip, 646 651 'user_agent' => isset( $_SERVER['HTTP_USER_AGENT'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : '', 647 652 ); … … 652 657 } 653 658 654 update_option( 'wpsh_security_logs', $logs ); 659 // autoload=false: logs are only needed on the settings page, not on every request 660 update_option( 'wpsh_security_logs', $logs, false ); 655 661 } 656 662 … … 831 837 * Render checkbox field 832 838 * 833 * @param array $args Field arguments. 839 * @param array $args { 840 * Field arguments. 841 * 842 * @type string $field_id Option key in the stored options array. 843 * @type string $description Optional description shown beside the checkbox. 844 * } 834 845 */ 835 846 public function render_checkbox_field( $args ) { … … 1042 1053 public function show_admin_notices() { 1043 1054 // Clear logs action - verify nonce to prevent CSRF 1044 // phpcs:ignore WordPress.Security.NonceVerification.Recommended 1045 if ( isset( $_GET['action'] ) && 'clear_logs' === $_GET['action'] && current_user_can( 'manage_options' ) ) { 1055 if ( isset( $_GET['action'] ) && 'clear_logs' === $_GET['action'] && current_user_can( 'manage_options' ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- nonce is verified on the next line 1046 1056 if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'wpsh_clear_logs' ) ) { 1047 1057 wp_die( esc_html__( 'Security check failed.', 'security-hardener' ) ); … … 1153 1163 $settings_link = sprintf( 1154 1164 '<a href="%s">%s</a>', 1155 admin_url( 'options-general.php?page=security-hardener'),1156 __( 'Settings', 'security-hardener' )1165 esc_url( admin_url( 'options-general.php?page=security-hardener' ) ), 1166 esc_html__( 'Settings', 'security-hardener' ) 1157 1167 ); 1158 1168 array_unshift( $links, $settings_link );
Note: See TracChangeset
for help on using the changeset viewer.