mirror of
https://gitlab.com/ArkHost/WP-Security-Pack.git
synced 2026-07-23 23:45:51 +02:00
v1.0
This commit is contained in:
@@ -31,6 +31,7 @@ class WPSP_Admin {
|
|||||||
add_action( 'wp_ajax_wpsp_clear_logs', array( $this, 'ajax_clear_logs' ) );
|
add_action( 'wp_ajax_wpsp_clear_logs', array( $this, 'ajax_clear_logs' ) );
|
||||||
add_action( 'wp_ajax_wpsp_export_logs', array( $this, 'ajax_export_logs' ) );
|
add_action( 'wp_ajax_wpsp_export_logs', array( $this, 'ajax_export_logs' ) );
|
||||||
add_action( 'wp_ajax_wpsp_whitelist_ip', array( $this, 'ajax_whitelist_ip' ) );
|
add_action( 'wp_ajax_wpsp_whitelist_ip', array( $this, 'ajax_whitelist_ip' ) );
|
||||||
|
add_action( 'wp_ajax_wpsp_unblock_ip', array( $this, 'ajax_unblock_ip' ) );
|
||||||
add_action( 'wp_ajax_wpsp_clear_lockouts', array( $this, 'ajax_clear_lockouts' ) );
|
add_action( 'wp_ajax_wpsp_clear_lockouts', array( $this, 'ajax_clear_lockouts' ) );
|
||||||
add_action( 'wp_ajax_wpsp_run_file_scan', array( $this, 'ajax_run_file_scan' ) );
|
add_action( 'wp_ajax_wpsp_run_file_scan', array( $this, 'ajax_run_file_scan' ) );
|
||||||
add_action( 'wp_ajax_wpsp_run_malware_scan', array( $this, 'ajax_run_malware_scan' ) );
|
add_action( 'wp_ajax_wpsp_run_malware_scan', array( $this, 'ajax_run_malware_scan' ) );
|
||||||
@@ -3018,6 +3019,30 @@ class WPSP_Admin {
|
|||||||
wp_send_json_success( array( 'csv' => implode( "\n", $csv_lines ) ) );
|
wp_send_json_success( array( 'csv' => implode( "\n", $csv_lines ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AJAX: Unblock a single IP.
|
||||||
|
*/
|
||||||
|
public function ajax_unblock_ip() {
|
||||||
|
check_ajax_referer( 'wpsp_admin' );
|
||||||
|
|
||||||
|
if ( ! current_user_can( 'manage_options' ) ) {
|
||||||
|
wp_send_json_error( array( 'message' => __( 'Permission denied.', 'wp-security-pack' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$ip = isset( $_POST['ip'] ) ? sanitize_text_field( wp_unslash( $_POST['ip'] ) ) : '';
|
||||||
|
|
||||||
|
if ( empty( $ip ) || ! filter_var( $ip, FILTER_VALIDATE_IP ) ) {
|
||||||
|
wp_send_json_error( array( 'message' => __( 'Invalid IP address.', 'wp-security-pack' ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$ip_control = wpsp()->get_component( 'ip_control' );
|
||||||
|
if ( $ip_control ) {
|
||||||
|
$ip_control->unblock_ip( $ip );
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_send_json_success();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AJAX: Clear all lockouts.
|
* AJAX: Clear all lockouts.
|
||||||
*/
|
*/
|
||||||
+49
-14
@@ -38,7 +38,6 @@ class WPSP_Login_Protection {
|
|||||||
// Priority 10 runs BEFORE WordPress's authenticate (priority 20) to block locked-out IPs early.
|
// Priority 10 runs BEFORE WordPress's authenticate (priority 20) to block locked-out IPs early.
|
||||||
add_filter( 'authenticate', array( $this, 'check_lockout' ), 10, 3 );
|
add_filter( 'authenticate', array( $this, 'check_lockout' ), 10, 3 );
|
||||||
|
|
||||||
|
|
||||||
// Successful login tracking.
|
// Successful login tracking.
|
||||||
add_action( 'wp_login', array( $this, 'handle_successful_login' ), 10, 2 );
|
add_action( 'wp_login', array( $this, 'handle_successful_login' ), 10, 2 );
|
||||||
|
|
||||||
@@ -46,7 +45,29 @@ class WPSP_Login_Protection {
|
|||||||
// This runs on login_init which fires before the login form is displayed.
|
// This runs on login_init which fires before the login form is displayed.
|
||||||
add_action( 'login_init', array( $this, 'block_locked_out_on_login_page' ), 1 );
|
add_action( 'login_init', array( $this, 'block_locked_out_on_login_page' ), 1 );
|
||||||
|
|
||||||
|
// Honeypot field.
|
||||||
|
// NOTE: Must be registered BEFORE handle_custom_login_slug_early() which
|
||||||
|
// may load wp-login.php and exit, preventing any later hook registrations.
|
||||||
|
if ( WP_Security_Pack::get_setting( 'honeypot_enabled', true ) ) {
|
||||||
|
add_action( 'login_form', array( $this, 'add_honeypot_field' ) );
|
||||||
|
add_action( 'register_form', array( $this, 'add_honeypot_field' ) );
|
||||||
|
add_filter( 'authenticate', array( $this, 'check_honeypot' ), 1, 3 );
|
||||||
|
add_filter( 'registration_errors', array( $this, 'check_honeypot_registration' ), 10, 3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide login error messages (prevents username enumeration).
|
||||||
|
// NOTE: Must be registered BEFORE handle_custom_login_slug_early() which
|
||||||
|
// may load wp-login.php and exit, preventing any later hook registrations.
|
||||||
|
if ( WP_Security_Pack::get_setting( 'hide_login_errors', true ) ) {
|
||||||
|
// Replace specific auth errors at the source (runs after WP's authenticate at priority 20).
|
||||||
|
add_filter( 'authenticate', array( $this, 'genericize_auth_error' ), PHP_INT_MAX, 3 );
|
||||||
|
// Also filter the rendered error string as a safety net.
|
||||||
|
add_filter( 'login_errors', array( $this, 'hide_login_errors' ), PHP_INT_MAX );
|
||||||
|
}
|
||||||
|
|
||||||
// Custom login URL - must run very early before WordPress processes the request.
|
// Custom login URL - must run very early before WordPress processes the request.
|
||||||
|
// WARNING: handle_custom_login_slug_early() may require wp-login.php and exit.
|
||||||
|
// All login-related hooks MUST be registered above this point.
|
||||||
if ( WP_Security_Pack::get_setting( 'login_rename_enabled', false ) ) {
|
if ( WP_Security_Pack::get_setting( 'login_rename_enabled', false ) ) {
|
||||||
$this->custom_login_slug = WP_Security_Pack::get_setting( 'login_custom_url', '' );
|
$this->custom_login_slug = WP_Security_Pack::get_setting( 'login_custom_url', '' );
|
||||||
if ( ! empty( $this->custom_login_slug ) ) {
|
if ( ! empty( $this->custom_login_slug ) ) {
|
||||||
@@ -67,19 +88,6 @@ class WPSP_Login_Protection {
|
|||||||
$this->block_wp_admin_early();
|
$this->block_wp_admin_early();
|
||||||
add_action( 'init', array( $this, 'hide_wp_admin' ), 1 );
|
add_action( 'init', array( $this, 'hide_wp_admin' ), 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Honeypot field.
|
|
||||||
if ( WP_Security_Pack::get_setting( 'honeypot_enabled', true ) ) {
|
|
||||||
add_action( 'login_form', array( $this, 'add_honeypot_field' ) );
|
|
||||||
add_action( 'register_form', array( $this, 'add_honeypot_field' ) );
|
|
||||||
add_filter( 'authenticate', array( $this, 'check_honeypot' ), 1, 3 );
|
|
||||||
add_filter( 'registration_errors', array( $this, 'check_honeypot_registration' ), 10, 3 );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hide login error messages (prevents username enumeration).
|
|
||||||
if ( WP_Security_Pack::get_setting( 'hide_login_errors', true ) ) {
|
|
||||||
add_filter( 'login_errors', array( $this, 'hide_login_errors' ) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -358,6 +366,33 @@ class WPSP_Login_Protection {
|
|||||||
return __( 'Invalid username or password.', 'wp-security-pack' );
|
return __( 'Invalid username or password.', 'wp-security-pack' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace specific authentication errors with a generic message.
|
||||||
|
*
|
||||||
|
* Runs at very late priority on the authenticate filter to catch WordPress's
|
||||||
|
* own specific error messages (invalid_username, incorrect_password, etc.)
|
||||||
|
* and replace them before they reach the login page rendering.
|
||||||
|
*
|
||||||
|
* @param WP_User|WP_Error|null $user User object or error.
|
||||||
|
* @param string $username Username.
|
||||||
|
* @param string $password Password.
|
||||||
|
* @return WP_User|WP_Error|null
|
||||||
|
*/
|
||||||
|
public function genericize_auth_error( $user, $username, $password ) {
|
||||||
|
if ( is_wp_error( $user ) ) {
|
||||||
|
$specific_codes = array( 'invalid_username', 'invalid_email', 'incorrect_password', 'invalidcombo' );
|
||||||
|
|
||||||
|
if ( in_array( $user->get_error_code(), $specific_codes, true ) ) {
|
||||||
|
return new WP_Error(
|
||||||
|
'authentication_failed',
|
||||||
|
__( 'Invalid username or password.', 'wp-security-pack' )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if IP is locked out before authentication.
|
* Check if IP is locked out before authentication.
|
||||||
*
|
*
|
||||||
|
Before Width: | Height: | Size: 667 KiB After Width: | Height: | Size: 667 KiB |
Reference in New Issue
Block a user