PluginProbe
Patchstack – WordPress & Plugins Security / 2.2.3
Patchstack – WordPress & Plugins Security v2.2.3
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/upload.php +63 -28 2.1.162.2.3 View file →
@@ -25,17 +25,18 @@
25 25 $this->upload_software();
26 26 }
27 27
28 28 // Register the actions.
29 - add_action( 'patchstack_send_software_data', array( $this, 'upload_software' ) );
30 - add_action( 'patchstack_send_hacker_logs', array( $this, 'upload_firewall_logs' ) );
31 - add_action( 'patchstack_send_event_logs', array( $this, 'upload_activity_logs' ) );
29 + add_action( 'patchstack_send_software_data', [ $this, 'upload_software' ] );
30 + add_action( 'patchstack_send_hacker_logs', [ $this, 'upload_firewall_logs' ] );
31 + add_action( 'patchstack_send_event_logs', [ $this, 'upload_activity_logs' ] );
32 32
33 33 // In case a plugin or upgrade has been performed, re-synchronize with the app.
34 - add_action( 'activated_plugin', array( $this, 'upload_software' ) );
35 - add_action( 'deactivated_plugin', array( $this, 'upload_software' ) );
36 - add_action( 'upgrader_process_complete', array( $this, 'upload_software' ) );
37 - add_action( '_core_updated_successfully', array( &$this, 'upload_software' ) );
34 + add_action( 'activated_plugin', [ $this, 'upload_software' ] );
35 + add_action( 'deactivated_plugin', [ $this, 'upload_software' ] );
36 + add_action( 'deleted_plugin', [ $this, 'upload_software' ] );
37 + add_action( 'upgrader_process_complete', [ $this, 'upload_software' ] );
38 + add_action( '_core_updated_successfully', [ &$this, 'upload_software' ] );
38 39 }
39 40
40 41 /**
41 42 * Synchronize the software data with our API.
@@ -46,14 +47,14 @@
46 47 public function upload_software() {
47 48 // Get the software data and hash.
48 49 $data = $this->get_software_data();
49 50 $hash = sha1( json_encode( $data ) );
50 - if ( ! defined( 'DOING_CRON' ) && ! isset( $_POST['webarx_secret'] ) && get_option( 'patchstack_software_data_hash', false ) === $hash ) {
51 + if ( ! defined( 'DOING_CRON' ) && ! isset( $_POST['webarx_secret'] ) && get_option( 'patchstack_software_data_hash', false ) === $hash && ! is_admin() ) {
51 52 return;
52 53 }
53 54
54 55 // Synchronize the software list with the API.
55 - $results = $this->plugin->api->upload_software( array( 'software' => json_encode( $data ) ) );
56 + $results = $this->plugin->api->upload_software( [ 'software' => json_encode( $data ) ] );
56 57 if ( isset( $results['success'] ) ) {
57 58 update_option( 'patchstack_software_data_hash', $hash );
58 59
59 60 // The result will also contain a list of all vulnerable plugins on the site that is returned by the API.
@@ -58,13 +59,28 @@
58 59
59 60 // The result will also contain a list of all vulnerable plugins on the site that is returned by the API.
60 61 // If the auto update setting is enabled for vulnerable plugins, perform the update once the 15 minute
61 62 // scheduled task "patchstack_update_plugins" is executed.
62 - $update = get_site_option( 'patchstack_auto_update', array() );
63 + $update = get_site_option( 'patchstack_auto_update', [] );
63 64 if ( isset( $results['vulnerable'] ) && is_array( $update ) && in_array( 'vulnerable', $update ) ) {
64 65 update_site_option( 'patchstack_vulnerable_plugins', $results['vulnerable'] );
65 66 }
66 67
68 + // If we have vulnerable plugins, determine if we had them before and if not, pull latest firewall rules.
69 + if ( isset( $results['vulnerable'] ) && count( $results['vulnerable'] ) > 0 ) {
70 + $prev = get_site_option( 'patchstack_latest_vulnerable', [] );
71 + foreach ( $results['vulnerable'] as $vuln ) {
72 + if ( ! in_array ( $vuln, $prev ) ) {
73 + do_action( 'patchstack_post_dynamic_firewall_rules' );
74 + break;
75 + }
76 + }
77 +
78 + update_site_option( 'patchstack_latest_vulnerable', $results['vulnerable'] );
79 + } else {
80 + update_site_option( 'patchstack_latest_vulnerable', [] );
81 + }
82 +
67 83 return $results;
68 84 }
69 85
70 86 return;
@@ -85,9 +101,9 @@
85 101 return;
86 102 }
87 103
88 104 // Construct the array to be uploaded to our API.
89 - $logs = array();
105 + $logs = [];
90 106 foreach ( $items as $item ) {
91 107
92 108 // Entries that we don't want to store on the API side.
93 109 if ( stripos( $item->request_uri, 'wp-comments-post' ) !== false ) {
@@ -94,9 +110,9 @@
94 110 continue;
95 111 }
96 112
97 113 // Push to entries to be uploaded.
98 - $logs[] = array(
114 + $logs[] = [
99 115 'ip' => $item->ip,
100 116 'fid' => $item->fid,
101 117 'request_uri' => $item->request_uri,
102 118 'user_agent' => $item->user_agent,
@@ -102,18 +118,18 @@
102 118 'user_agent' => $item->user_agent,
103 119 'method' => $item->method,
104 120 'log_date' => $item->log_date,
105 121 'post_data' => $item->post_data,
106 - );
122 + ];
107 123 }
108 124
109 125 // JSON encode the logs and upload.
110 126 $logs = json_encode( $logs );
111 127 $results = $this->plugin->api->upload_firewall_logs(
112 - array(
128 + [
113 129 'logs' => $logs,
114 130 'type' => 'firewall',
115 - )
131 + ]
116 132 );
117 133 if ( isset( $results['errors'] ) ) {
118 134 return;
119 135 }
@@ -141,9 +157,9 @@
141 157 }
142 158
143 159 // Do we have data to upload?
144 160 $lastid = get_option( 'patchstack_eventlog_lastid', 0 );
145 - $items = $wpdb->get_results( $wpdb->prepare( 'SELECT author, ip, object, object_id, object_name, action, date FROM ' . $wpdb->prefix . 'patchstack_event_log WHERE id > %d' . $where . 'ORDER BY id', array( $lastid ) ) );
161 + $items = $wpdb->get_results( $wpdb->prepare( 'SELECT author, ip, object, object_id, object_name, action, date FROM ' . $wpdb->prefix . 'patchstack_event_log WHERE id > %d' . $where . 'ORDER BY id', [ $lastid ] ) );
146 162 if ( $wpdb->num_rows == 0 ) {
147 163 return;
148 164 }
149 165
@@ -148,9 +164,9 @@
148 164 }
149 165
150 166 // Send to the API.
151 167 $logs = json_encode( $items );
152 - $results = $this->plugin->api->upload_activity_logs( array( 'logs' => $logs ) );
168 + $results = $this->plugin->api->upload_activity_logs( [ 'logs' => $logs ] );
153 169 if ( isset( $results['errors'] ) ) {
154 170 return;
155 171 }
156 172
@@ -186,9 +202,9 @@
186 202 // Fetch list of plugins.
187 203 $all_plugin = get_plugins();
188 204 $installed_plugins = array_keys( $all_plugin );
189 205 $updatable_plugins = get_plugin_updates();
190 - $software_list = array();
206 + $software_list = [];
191 207
192 208 foreach ( $installed_plugins as $plugin ) {
193 209 if ( ! file_exists( WP_PLUGIN_DIR . '/' . $plugin ) ) {
194 210 continue;
@@ -199,16 +215,24 @@
199 215 $plugin_name = empty( $plugin_data['Name'] ) ? '' : $plugin_data['Name'];
200 216 $plugin_version = empty( $plugin_data['Version'] ) ? '' : $plugin_data['Version'];
201 217
202 218 if ( ! empty( $plugin_name ) && ! empty( $plugin_version ) ) {
203 - $software_list[] = array(
219 +
220 + // Determine the active state.
221 + if ( isset( $_GET['action'], $_GET['plugin'] ) && $_GET['action'] == 'deactivate' && $_GET['plugin'] == $plugin) {
222 + $active = 0;
223 + } else {
224 + $active = (int) is_plugin_active( $plugin );
225 + }
226 +
227 + $software_list[] = [
204 228 'sw_type' => 'plugin',
205 229 'sw_name' => $plugin_name,
206 230 'sw_cur_ver' => $plugin_version,
207 231 'sw_new_ver' => $new_version,
208 232 'sw_key' => $plugin,
209 - 'sw_active' => is_plugin_active( $plugin ),
210 - );
233 + 'sw_active' => $active
234 + ];
211 235 }
212 236 }
213 237
214 238 // Fetch list of themes.
@@ -223,15 +247,15 @@
223 247 $theme_name = $themes_data->get( 'Name' );
224 248 $theme_version = $themes_data->get( 'Version' );
225 249
226 250 if ( ! empty( $theme_name ) && ! empty( $theme_version ) ) {
227 - $software_list[] = array(
251 + $software_list[] = [
228 252 'sw_type' => 'theme',
229 253 'sw_name' => $theme_name,
230 254 'sw_cur_ver' => $theme_version,
231 255 'sw_new_ver' => $theme_new_version,
232 256 'sw_key' => $theme_key,
233 - );
257 + ];
234 258 }
235 259 }
236 260
237 261 // Fetch WordPress version.
@@ -237,22 +261,33 @@
237 261 // Fetch WordPress version.
238 262 global $wp_version;
239 263 $core_updates = get_core_updates();
240 264 $new_wp_version = ( ! empty( $core_updates ) && $core_updates[0]->response == 'upgrade' ) ? $core_updates[0]->version : '';
241 - $software_list[] = array(
265 + $software_list[] = [
242 266 'sw_type' => 'wordpress',
243 267 'sw_name' => 'WordPress',
244 268 'sw_cur_ver' => $wp_version,
245 269 'sw_new_ver' => $new_wp_version,
246 - );
270 + ];
247 271
248 272 // Fetch PHP version.
249 - $software_list[] = array(
273 + $software_list[] = [
250 274 'sw_type' => 'php',
251 275 'sw_name' => 'PHP',
252 - 'sw_cur_ver' => substr( phpversion(), 0, 5 ),
276 + 'sw_cur_ver' => phpversion(),
253 277 'sw_new_ver' => '',
254 - );
278 + ];
279 +
280 + // Fetch database server version.
281 + global $wpdb;
282 + if ( ! is_null( $wpdb ) ) {
283 + $software_list[] = [
284 + 'sw_type' => 'database',
285 + 'sw_name' => 'Database',
286 + 'sw_cur_ver' => $wpdb->get_var( 'SELECT VERSION()' ),
287 + 'sw_new_ver' => ''
288 + ];
289 + }
255 290
256 291 return $software_list;
257 292 }
258 293 }