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