siteguard-admin-filter.php
1 month ago
siteguard-base.php
1 month ago
siteguard-captcha.php
1 month ago
siteguard-config.php
11 months ago
siteguard-disable-author-query.php
2 weeks ago
siteguard-disable-pingback.php
1 month ago
siteguard-disable-xmlrpc.php
1 month ago
siteguard-htaccess.php
2 weeks ago
siteguard-login-alert.php
1 month ago
siteguard-login-history.php
1 month ago
siteguard-login-lock.php
1 month ago
siteguard-rename-login.php
1 week ago
siteguard-updates-notify.php
1 month ago
siteguard-waf-exclude-rule.php
1 month ago
siteguard-admin-filter.php
156 lines
| 1 | <?php |
| 2 | |
| 3 | class SiteGuard_AdminFilter extends SiteGuard_Base { |
| 4 | public static $htaccess_mark = '#==== SITEGUARD_ADMIN_FILTER_SETTINGS'; |
| 5 | function __construct() { |
| 6 | define( 'SITEGUARD_TABLE_LOGIN', 'siteguard_login' ); |
| 7 | add_action( 'wp_login', array( $this, 'handler_wp_login' ), 1, 2 ); |
| 8 | add_action( 'init', array( $this, 'enforce_admin_filter' ), 0 ); |
| 9 | } |
| 10 | |
| 11 | static function get_mark() { |
| 12 | return self::$htaccess_mark; |
| 13 | } |
| 14 | |
| 15 | function init() { |
| 16 | global $wpdb, $siteguard_config; |
| 17 | $table_name = $wpdb->prefix . SITEGUARD_TABLE_LOGIN; |
| 18 | $sql = 'CREATE TABLE ' . $table_name . " ( |
| 19 | ip_address varchar(40) NOT NULL DEFAULT '', |
| 20 | status INT NOT NULL DEFAULT 0, |
| 21 | count INT NOT NULL DEFAULT 0, |
| 22 | last_login_time datetime, |
| 23 | UNIQUE KEY ip_address (ip_address) |
| 24 | ) |
| 25 | CHARACTER SET 'utf8';"; |
| 26 | require_once ABSPATH . 'wp-admin/includes/upgrade.php'; |
| 27 | dbDelta( $sql ); |
| 28 | |
| 29 | $siteguard_config->set( 'admin_filter_exclude_path', 'admin-ajax.php,load-styles.php,load-scripts.php,site-health.php' ); |
| 30 | $siteguard_config->set( 'admin_filter_enable', '0' ); |
| 31 | $siteguard_config->update(); |
| 32 | } |
| 33 | |
| 34 | function handler_wp_login( $login, $current_user ) { |
| 35 | global $siteguard_config; |
| 36 | if ( '' == $current_user->user_login ) { |
| 37 | return; |
| 38 | } |
| 39 | if ( 1 == $siteguard_config->get( 'admin_filter_enable' ) ) { |
| 40 | $this->feature_on( $this->get_ip() ); |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | function cvt_exclude( $exclude ) { |
| 45 | return str_replace( ',', '|', $exclude ); |
| 46 | } |
| 47 | |
| 48 | function cvt_status_for_1_2_5( $ip_address ) { |
| 49 | global $wpdb; |
| 50 | $table_name = $wpdb->prefix . SITEGUARD_TABLE_LOGIN; |
| 51 | $wpdb->update( $table_name, array( 'status' => 0 ), array( 'ip_address' => $ip_address ) ); |
| 52 | } |
| 53 | |
| 54 | private function cleanup_and_upsert_success_ip( $ip_address ) { |
| 55 | global $wpdb; |
| 56 | $table_name = $wpdb->prefix . SITEGUARD_TABLE_LOGIN; |
| 57 | |
| 58 | $wpdb->query( |
| 59 | $wpdb->prepare( |
| 60 | "DELETE FROM $table_name WHERE status = %d AND last_login_time < (SYSDATE() - INTERVAL 1 DAY)", |
| 61 | SITEGUARD_LOGIN_SUCCESS |
| 62 | ) |
| 63 | ); |
| 64 | |
| 65 | // upsert |
| 66 | $now_str = current_time( 'mysql' ); |
| 67 | $data = array( |
| 68 | 'ip_address' => $ip_address, |
| 69 | 'status' => SITEGUARD_LOGIN_SUCCESS, |
| 70 | 'count' => 0, |
| 71 | 'last_login_time' => $now_str, |
| 72 | ); |
| 73 | $exists = $wpdb->get_var( |
| 74 | $wpdb->prepare( |
| 75 | "SELECT 1 FROM $table_name WHERE ip_address = %s LIMIT 1", |
| 76 | $ip_address |
| 77 | ) |
| 78 | ); |
| 79 | if ( $exists ) { |
| 80 | $wpdb->update( $table_name, $data, array( 'ip_address' => $ip_address ) ); |
| 81 | } else { |
| 82 | $wpdb->insert( $table_name, $data ); |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | function feature_on( $ip_address ) { |
| 87 | $this->cleanup_and_upsert_success_ip( $ip_address ); |
| 88 | return true; |
| 89 | } |
| 90 | |
| 91 | static function feature_off() { |
| 92 | return true; |
| 93 | } |
| 94 | |
| 95 | function enforce_admin_filter() { |
| 96 | global $wpdb, $siteguard_config; |
| 97 | |
| 98 | if ( '1' != $siteguard_config->get( 'admin_filter_enable' ) ) { |
| 99 | return; |
| 100 | } |
| 101 | |
| 102 | $req_path = isset( $_SERVER['REQUEST_URI'] ) ? parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH ) : ''; |
| 103 | if ( ! is_string( $req_path ) ) { |
| 104 | return; |
| 105 | } |
| 106 | $req_path = untrailingslashit( $req_path ); |
| 107 | $site_path = untrailingslashit( parse_url( site_url(), PHP_URL_PATH ) ?: '' ); |
| 108 | $admin_prefix = $site_path . '/wp-admin'; |
| 109 | if ( 0 !== strpos( $req_path, $admin_prefix ) ) { |
| 110 | return; |
| 111 | } |
| 112 | |
| 113 | $exclude = (string) $siteguard_config->get( 'admin_filter_exclude_path' ); |
| 114 | $parts = array_filter( array_map( 'trim', explode( ',', $exclude ) ) ); |
| 115 | if ( ! empty( $parts ) ) { |
| 116 | $escaped = array_map( |
| 117 | function ( $p ) { |
| 118 | return preg_quote( $p, '#' ); |
| 119 | }, |
| 120 | $parts |
| 121 | ); |
| 122 | $regex = '#^' . preg_quote( $admin_prefix, '#' ) . '/(?:' . implode( '|', $escaped ) . ')(?:$|/|\?)#i'; |
| 123 | if ( preg_match( $regex, $req_path ) ) { |
| 124 | return; |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | if ( is_user_logged_in() ) { |
| 129 | return; |
| 130 | } |
| 131 | |
| 132 | $ip = $this->get_ip(); |
| 133 | |
| 134 | $server_ip = $this->get_server_ip(); |
| 135 | if ( $ip === '127.0.0.1' || $ip === '::1' || ( $server_ip !== false && $ip === $server_ip ) ) { |
| 136 | return; |
| 137 | } |
| 138 | |
| 139 | $table = $wpdb->prefix . SITEGUARD_TABLE_LOGIN; |
| 140 | $ok = $wpdb->get_var( |
| 141 | $wpdb->prepare( |
| 142 | "SELECT 1 FROM $table WHERE ip_address = %s AND status = %d AND last_login_time >= (SYSDATE() - INTERVAL 1 DAY) LIMIT 1", |
| 143 | $ip, |
| 144 | SITEGUARD_LOGIN_SUCCESS |
| 145 | ) |
| 146 | ); |
| 147 | if ( $ok ) { |
| 148 | return; |
| 149 | } |
| 150 | |
| 151 | status_header( 404 ); |
| 152 | nocache_headers(); |
| 153 | exit; |
| 154 | } |
| 155 | } |
| 156 |