PluginProbe
Patchstack – WordPress & Plugins Security / 2.2.5
Patchstack – WordPress & Plugins Security v2.2.5
2.3.7 trunk 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 2.1.15 2.1.16 2.1.17 2.1.18 2.1.19 2.1.2 2.1.20 2.1.21 2.1.22 2.1.23 2.1.24 2.1.25 2.1.3 2.1.4 2.1.5 2.1.6 All 49 releases
← All changes | includes/admin/ajax.php +47 -19 2.1.112.2.5 View file →
@@ -19,13 +19,16 @@
19 19 public function __construct( $core ) {
20 20 parent::__construct( $core );
21 21 if ( isset( $_POST['PatchstackNonce'] ) && current_user_can( 'manage_options' ) && wp_verify_nonce( $_POST['PatchstackNonce'], 'patchstack-nonce' ) ) {
22 22 // Log tables actions.
23 - add_action( 'wp_ajax_users_log_table', array( $this, 'users_log_table' ) );
24 - add_action( 'wp_ajax_firewall_log_table', array( $this, 'firewall_log_table' ) );
23 + add_action( 'wp_ajax_patchstack_users_log_table', [ $this, 'users_log_table' ] );
24 + add_action( 'wp_ajax_patchstack_firewall_log_table', [ $this, 'firewall_log_table' ] );
25 25
26 26 // License related actions.
27 - add_action( 'wp_ajax_activate_license', array( $this, 'activate_license' ) );
27 + add_action( 'wp_ajax_patchstack_activate_license', [ $this, 'activate_license' ] );
28 +
29 + // Hide login related actions.
30 + add_action( 'wp_ajax_patchstack_send_new_url_email', [ $this, 'send_new_url_email' ] );
28 31 }
29 32 }
30 33
31 34 /**
@@ -41,15 +44,15 @@
41 44 // Pull all entries, given parameters.
42 45 global $wpdb;
43 46 $entries = $wpdb->get_results(
44 47 $wpdb->prepare(
45 - "SELECT a.id, a.ip, a.flag, a.method, a.log_date, case when a.referer IS NULL or a.referer = '' then a.request_uri else a.referer end as referer, a.fid, b.description
48 + "SELECT a.id, a.ip, a.flag, a.method, a.log_date, a.request_uri as referer, a.fid, b.description
46 49 FROM " . $wpdb->prefix . 'patchstack_firewall_log AS a
47 50 LEFT JOIN ' . $wpdb->prefix . 'patchstack_logic AS b ON b.id = a.fid
48 51 ORDER BY a.id DESC
49 52 LIMIT %d, %d
50 53 ',
51 - array( wp_filter_nohtml_kses( $_POST['start'] ), wp_filter_nohtml_kses( $_POST['length'] ) )
54 + [ wp_filter_nohtml_kses( $_POST['start'] ), wp_filter_nohtml_kses( $_POST['length'] ) ]
52 55 )
53 56 );
54 57
55 58 // Get total amount of rows.
@@ -54,20 +57,22 @@
54 57
55 58 // Get total amount of rows.
56 59 $count = $wpdb->get_var( 'SELECT COUNT(id) FROM ' . $wpdb->prefix . 'patchstack_firewall_log' );
57 60 $firewall_rules = json_decode( get_option( 'patchstack_firewall_rules', '' ), true );
61 + $firewall_rules_v3 = json_decode( get_option( 'patchstack_firewall_rules_v3', [] ), true );
62 + $firewall_rules = array_merge($firewall_rules, $firewall_rules_v3);
58 63
59 64 // Modify data if necessary.
60 - $list = array();
65 + $list = [];
61 66 foreach ( $entries as $entry ) {
62 67 foreach ( $entry as $key => $value ) {
63 - if ( ! in_array( $key, array( 'referer' ) ) ) {
68 + if ( ! in_array( $key, [ 'referer' ] ) ) {
64 69 $entry->$key = sanitize_textarea_field( $value );
65 70 }
66 71 }
67 72
68 73 // Attempt to find the block reason.
69 - $reason = $wpdb->get_var( $wpdb->prepare( 'SELECT cname FROM ' . $wpdb->prefix . 'patchstack_logic WHERE id = %d LIMIT 1', array( $entry->fid ) ) );
74 + $reason = $wpdb->get_var( $wpdb->prepare( 'SELECT cname FROM ' . $wpdb->prefix . 'patchstack_logic WHERE id = %d LIMIT 1', [ $entry->fid ] ) );
70 75 if ( $reason ) {
71 76 $entry->fid = $reason;
72 77 } elseif ( $firewall_rules != '' ) {
73 78 foreach ( $firewall_rules as $rule ) {
@@ -84,13 +89,13 @@
84 89 }
85 90
86 91 // Return output.
87 92 wp_send_json(
88 - array(
93 + [
89 94 'data' => $list,
90 95 'recordsFiltered' => $count,
91 96 'recordsTotal' => $count
92 - )
97 + ]
93 98 );
94 99 }
95 100
96 101 /**
@@ -105,13 +110,13 @@
105 110
106 111 // Determine if searching?
107 112 global $wpdb;
108 113 $searching = false;
109 - $likes = array();
114 + $likes = [];
110 115 if ( isset( $_POST['search'], $_POST['search']['value'] ) && $_POST['search']['value'] != '' ) {
111 116 $val = wp_filter_nohtml_kses( $_POST['search']['value'] );
112 117 $searching = true;
113 - $columns = array( 'author', 'ip', 'object', 'object_name', 'action' );
118 + $columns = [ 'author', 'ip', 'object', 'object_name', 'action' ];
114 119 $search = 'WHERE 1=2 ';
115 120 foreach ( $columns as $column ) {
116 121 array_push( $likes, '%' . $wpdb->esc_like( $val ) . '%' );
117 122 $search .= 'OR ' . $column . ' LIKE %s';
@@ -124,9 +129,9 @@
124 129 FROM ' . $wpdb->prefix . 'patchstack_event_log ' . ( $searching ? $search : '' ) . '
125 130 ORDER BY id DESC
126 131 LIMIT %d, %d
127 132 ',
128 - array_merge( $likes, array( wp_filter_nohtml_kses( $_POST['start'] ), wp_filter_nohtml_kses( $_POST['length'] ) ) )
133 + array_merge( $likes, [ wp_filter_nohtml_kses( $_POST['start'] ), wp_filter_nohtml_kses( $_POST['length'] ) ] )
129 134 )
130 135 );
131 136
132 137 $count = $wpdb->get_var( $wpdb->prepare( 'SELECT COUNT(id) FROM ' . $wpdb->prefix . 'patchstack_event_log ' . ( $searching ? $search : '' ), $likes ) );
@@ -131,9 +136,9 @@
131 136
132 137 $count = $wpdb->get_var( $wpdb->prepare( 'SELECT COUNT(id) FROM ' . $wpdb->prefix . 'patchstack_event_log ' . ( $searching ? $search : '' ), $likes ) );
133 138
134 139 // Modify data if necessary.
135 - $list = array();
140 + $list = [];
136 141 foreach ( $logs as $log ) {
137 142 $list[] = $log;
138 143 }
139 144
@@ -138,13 +143,13 @@
138 143 }
139 144
140 145 // Return output.
141 146 wp_send_json(
142 - array(
147 + [
143 148 'data' => $list,
144 149 'recordsFiltered' => $count,
145 150 'recordsTotal' => $count
146 - )
151 + ]
147 152 );
148 153 }
149 154
150 155 /**
@@ -152,18 +157,41 @@
152 157 *
153 158 * @return void
154 159 */
155 160 public function activate_license() {
156 - if ( ! isset( $_POST['clientid'], $_POST['secretkey'] ) || !ctype_digit( $_POST['clientid'] ) ) {
157 - return;
161 + if ( ! isset( $_POST['key'] ) || strpos( $_POST['key'], '-' ) === false) {
162 + wp_send_json(
163 + [
164 + 'result' => 'error',
165 + 'error_message' => 'An invalid API key was provided.'
166 + ]
167 + );
158 168 }
159 169
170 + // Since we have the keys combined into one now, split them up here.
171 + $split = explode('-', $_POST['key']);
172 + $secretkey = $split[0];
173 + $clientid = $split[1];
174 +
160 175 // Test the new keys.
161 176 update_option( 'patchstack_api_token', '' );
162 - $results = $this->plugin->activation->alter_license( wp_filter_nohtml_kses( $_POST['clientid'] ), wp_filter_nohtml_kses( $_POST['secretkey'] ), 'activate' );
177 + $results = $this->plugin->activation->alter_license( wp_filter_nohtml_kses( $clientid ), wp_filter_nohtml_kses( $secretkey ), 'activate' );
163 178 if ( $results ) {
164 179 $response = $this->plugin->api->update_license_status();
165 180 $results['response'] = $response;
166 181 wp_send_json( $results );
167 182 }
183 + }
184 +
185 + /**
186 + * Send an email to the current logged in user that contains the new admin page URL.
187 + *
188 + * @return void
189 + */
190 + public function send_new_url_email() {
191 + global $current_user;
192 + $subject = __( 'New Login URL', 'patchstack' );
193 + $message = '<br /><br />Your login page is now here: <strong> <a href="' . get_site_url() . '/' . get_site_option( 'patchstack_rename_wp_login' ) . '">' . get_site_url() . '/' . get_site_option( 'patchstack_rename_wp_login' ) . '</strong></a>';
194 + $email_sent = wp_mail( $current_user->user_email, $subject, $message );
195 + die( $email_sent ? 'success' : 'fail' );
168 196 }
169 197 }