PluginProbe
Patchstack – WordPress & Plugins Security / 2.1.25
Patchstack – WordPress & Plugins Security v2.1.25
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 | patchstack.php +38 -101 trunk2.1.25 View file →
@@ -1,16 +1,15 @@
1 1 <?php
2 2 /**
3 3 * Plugin Name: Patchstack Security
4 - * Plugin URI: https://patchstack.com/?utm_medium=wp&utm_source=dashboard&utm_campaign=patchstack%20plugin
5 - * Author URI: https://patchstack.com/?utm_medium=wp&utm_source=dashboard&utm_campaign=patchstack%20plugin
4 + * Plugin URI: https://patchstack.com
6 5 * Description: Patchstack identifies security vulnerabilities in WordPress plugins, themes, and core.
7 - * Version: 2.3.7
6 + * Version: 2.1.25
8 7 * Author: Patchstack
9 8 * License: GPLv3
10 9 * Text Domain: patchstack
11 10 * Domain Path: /languages
12 - * Requires at least: 5.2
11 + * Requires at least: 4.4
13 12 * Requires PHP: 5.6
14 13 */
15 14
16 15 // Do not allow the file to be called directly.
@@ -33,9 +32,9 @@
33 32
34 33 // Set up our filename.
35 34 $file_name = strtolower( str_replace( '_', '-', substr( $class_name, strlen( 'P_' ) ) ) );
36 35 $dir = trailingslashit( dirname( __FILE__ ) ) . 'includes/';
37 - $target = [ $dir . $file_name . '.php', $dir . 'admin/' . str_replace( 'admin-', '', $file_name ) . '.php' ];
36 + $target = array( $dir . $file_name . '.php', $dir . 'admin/' . str_replace( 'admin-', '', $file_name ) . '.php' );
38 37
39 38 // Attempt each target and load if it exists.
40 39 foreach ( $target as $file ) {
41 40 if ( file_exists( $file ) ) {
@@ -58,9 +57,9 @@
58 57 * The plugin version.
59 58 *
60 59 * @var string
61 60 */
62 - const VERSION = '2.3.7';
61 + const VERSION = '2.1.25';
63 62
64 63 /**
65 64 * API URL of Patchstack to communicate with.
66 65 *
@@ -114,9 +113,9 @@
114 113 * Detailed activation error messages.
115 114 *
116 115 * @var array
117 116 */
118 - protected $activation_errors = [];
117 + protected $activation_errors = array();
119 118
120 119 /**
121 120 * Singleton instance of plugin.
122 121 *
@@ -143,8 +142,9 @@
143 142 protected $hide_login;
144 143 protected $listener;
145 144 protected $event_log;
146 145 protected $multisite;
146 + protected $notice;
147 147 protected $admin_ajax;
148 148 protected $admin_general;
149 149 protected $admin_menu;
150 150 protected $admin_options;
@@ -173,10 +173,8 @@
173 173
174 174 // Define WP_CLI command.
175 175 if ( defined( 'WP_CLI' ) && WP_CLI && method_exists('\WP_CLI', 'add_command')) {
176 176 \WP_CLI::add_command( 'patchstack activate', [ $this, 'cli_activate' ] );
177 - \WP_CLI::add_command( 'patchstack deactivate', [ $this, 'cli_deactivate' ] );
178 - \WP_CLI::add_command( 'patchstack status', [ $this, 'cli_status' ] );
179 177 }
180 178 }
181 179
182 180 /**
@@ -185,9 +183,9 @@
185 183 * @return void
186 184 */
187 185 public function plugin_classes() {
188 186 // Define the array of the classes.
189 - foreach ( [
187 + foreach ( array(
190 188 'admin_options' => 'P_Admin_Options',
191 189 'cron' => 'P_Cron',
192 190 'api' => 'P_Api',
193 191 'login' => 'P_Login',
@@ -197,20 +195,20 @@
197 195 'hacker_log' => 'P_Hacker_Log',
198 196 'upload' => 'P_Upload',
199 197 'rules' => 'P_Rules',
200 198 'hide_login' => 'P_Hide_Login',
199 + 'listener' => 'P_Listener',
201 200 'event_log' => 'P_Event_Log',
202 201 'activation' => 'P_Activation',
203 - 'listener' => 'P_Listener',
204 202 'multisite' => 'P_Multisite',
203 + 'notice' => 'P_Cookie_Notice',
205 204 'admin_ajax' => 'P_Admin_Ajax',
206 205 'admin_general' => 'P_Admin_General',
207 206 'admin_menu' => 'P_Admin_Menu',
208 - ] as $var => $class ) {
207 + ) as $var => $class ) {
209 208 $this->$var = new $class( $this );
210 209 }
211 210
212 - // Load firewall base functionality.
213 211 $this->firewall_base = new P_Firewall( true, $this, true );
214 212 }
215 213
216 214 /**
@@ -229,39 +227,26 @@
229 227 * Returns an error if the connection was not successful.
230 228 *
231 229 * ## OPTIONS
232 230 *
233 - * [<id>]
231 + * <id>
234 232 * : The API client id.
235 - *
236 - * [<secret>]
233 + *
234 + * <secret>
237 235 * : The API secret key.
238 236 *
239 - * <secret-id>
240 - * : The API client id and secret key merged together, found in the App. E.g. 2b072e8b60402e30d481df351fc08183906254e0-123456
241 - *
242 237 * ## EXAMPLES
243 238 *
244 239 * $ wp patchstack activate 123456 2b072e8b60402e30d481df351fc08183906254e0
245 240 * Success: The Patchstack plugin has been successfully connected.
246 - *
247 - * or
248 - *
249 - * $ wp patchstack activate 2b072e8b60402e30d481df351fc08183906254e0-123456
250 - * Success: The Patchstack plugin has been successfully connected.
251 241 */
252 242 public function cli_activate( $args ) {
253 - // Handle both ways to activate the plugin.
254 - if ( count( $args ) === 1 && strpos( $args[0], '-' ) !== false ) {
255 - list( $secret, $id ) = explode( '-', $args[0] );
256 - } else {
257 - $id = isset( $args[0] ) ? trim( $args[0] ) : '';
258 - $secret = isset( $args[1] ) ? trim( $args[1] ) : '';
259 - }
243 + $id = isset( $args[0] ) ? trim( $args[0] ) : '';
244 + $secret = isset( $args[1] ) ? trim( $args[1] ) : '';
260 245
261 246 $result = $this->activation->alter_license( $id, $secret, 'activate' );
262 247 if ( $result['result'] == 'error' ) {
263 - \WP_CLI::error( "The Patchstack plugin could not be connected. Make sure the id and secret key are valid and that api.patchstack.com is not blocked. Additional information:\n" . $result['body'] );
248 + \WP_CLI::error( 'The Patchstack plugin could not be connected. Make sure the id and secret key are valid and that api.patchstack.com is not blocked.' );
264 249 return;
265 250 }
266 251
267 252 \WP_CLI::success( 'The Patchstack plugin has been successfully connected.' );
@@ -267,42 +252,8 @@
267 252 \WP_CLI::success( 'The Patchstack plugin has been successfully connected.' );
268 253 }
269 254
270 255 /**
271 - * Disconnects the Patchstack plugin from the API and removes the API key.
272 - *
273 - * ## EXAMPLES
274 - *
275 - * $ wp patchstack deactivate
276 - * Success: The Patchstack plugin has been successfully disconnected.
277 - */
278 - public function cli_deactivate() {
279 - $this->activation->deactivate();
280 - $this->activation->alter_license( '', '', 'deactivate' );
281 -
282 - \WP_CLI::success( 'The Patchstack plugin has been successfully disconnected.' );
283 - }
284 -
285 - /**
286 - * Gets the current API connection status from the Patchstack plugin.
287 - *
288 - * ## EXAMPLES
289 - *
290 - * $ wp patchstack status
291 - * Success: The Patchstack plugin is currently connected to the API.
292 - *
293 - * $ wp patchstack status
294 - * Warning: The Patchstack plugin is not connected to the API.
295 - */
296 - public function cli_status() {
297 - if ( $this->api->is_connected() ) {
298 - \WP_CLI::success( __( 'The Patchstack plugin is currently connected to the API.', 'patchstack' ) );
299 - } else {
300 - \WP_CLI::warning( __( 'The Patchstack plugin is not connected to the API.', 'patchstack' ) );
301 - }
302 - }
303 -
304 - /**
305 256 * Deactivate the plugin.
306 257 *
307 258 * @return void
308 259 */
@@ -311,23 +262,24 @@
311 262 $this->activation->deactivate();
312 263 }
313 264
314 265 /**
315 - * Load translated strings for the plugin.
266 + * Boot Patchstack and its classes.
316 267 *
317 268 * @return void
318 269 */
319 - public function load_textdomain () {
320 - load_plugin_textdomain( 'patchstack', false, dirname( $this->basename ) . '/languages/' );
270 + public function hooks() {
271 + add_action( 'init', array( $this, 'init' ), ~PHP_INT_MAX );
321 272 }
322 273
323 274 /**
324 - * Boot Patchstack.
275 + * Boot Patchstack
325 276 *
326 277 * @return void
327 278 */
328 279 public function init() {
329 - add_action( 'init', [ $this, 'load_textdomain' ] );
280 + // Load translated strings for plugin.
281 + load_plugin_textdomain( 'patchstack', false, dirname( $this->basename ) . '/languages/' );
330 282
331 283 // Initialize plugin classes.
332 284 $this->plugin_classes();
333 285
@@ -338,9 +290,9 @@
338 290 if ( get_option( 'patchstack_api_token', '' ) == '' && get_option( 'patchstack_license_expiry', '' ) == '' ) {
339 291 $this->api->update_license_status();
340 292 }
341 293
342 - // Run firewall if not disabled and license activated.
294 + // Determine if the license is activated and not expired.
343 295 if ( get_option( 'patchstack_license_activated', 0 ) == 1 && get_option( 'patchstack_basic_firewall', 0 ) == 1 && get_option( 'patchstack_license_free', 0 ) == 0 ) {
344 296 $this->firewall = new P_Firewall( true, $this );
345 297 }
346 298 }
@@ -395,35 +347,22 @@
395 347 * @return void
396 348 */
397 349 function patchstack_uninstall() {
398 350 // Delete most of the Patchstack options.
399 - global $wpdb;
400 - $options = $wpdb->get_results( "SELECT option_name FROM $wpdb->options WHERE option_name LIKE 'patchstack_%'" );
351 + $options = array( 'patchstack_eventlog_lastid', 'patchstack_api_token', 'patchstack_dashboardlock', 'patchstack_pluginedit', 'patchstack_move_logs', 'patchstack_userenum', 'patchstack_basicscanblock', 'patchstack_hidewpcontent', 'patchstack_hidewpversionk', 'patchstack_prevent_default_file_access', 'patchstack_basic_firewall', 'patchstack_known_blacklist', 'patchstack_block_debug_log_access', 'patchstack_block_fake_bots', 'patchstack_index_views', 'patchstack_proxy_comment_posting', 'patchstack_bad_query_strings', 'patchstack_advanced_character_string_filter', 'patchstack_advanced_blacklist_firewall', 'patchstack_forbid_rfi', 'patchstack_image_hotlinking', 'patchstack_add_security_headers', 'patchstack_firewall_log_lastid', 'patchstack_user_log_lastid', 'patchstack_captcha_public_key', 'patchstack_captcha_private_key', 'patchstack_scan_interval', 'patchstack_scan_day', 'patchstack_scan_time', 'patchstack_hackers_log', 'patchstack_users_log', 'patchstack_visitors_log', 'external_updates-webarx', 'patchstack_wp_stats', 'patchstack_captcha_login_form', 'patchstack_license_activated', 'patchstack_license_expiry', 'patchstack_software_data_hash', 'patchstack_mv_wp_login', 'patchstack_rename_wp_login', 'patchstack_googledrive_backup_is_running', 'patchstack_googledrive_upload_state', 'patchstack_googledrive_access_token', 'patchstack_googledrive_refresh_token', 'patchstack_cron_offset', 'patchstack_htaccess_rules_hash' );
352 + foreach ( $options as $option ) {
353 + delete_option( $option );
401 354
402 - // Few options we want to keep.
403 - $keep = ['patchstack_hits_last_30', 'patchstack_hits_all_time', 'patchstack_clientid', 'patchstack_secretkey', 'patchstack_secretkey_nonce', 'patchstack_api_token'];
404 -
405 - // Delete everything else.
406 - foreach( $options as $option ) {
407 - if ( in_array( $option->option_name, $keep ) || stripos( $option->option_name, 'patchstack_captcha_' ) !== false ) {
408 - continue;
409 - }
410 -
411 - delete_option( $option->option_name );
412 -
413 355 if ( is_multisite() ) {
414 - delete_site_option( $option->option_name );
356 + delete_site_option( $option );
415 357 }
416 358 }
417 359
418 - // Drop all tables.
360 + // Drop all Patchstack tables.
419 361 global $wpdb;
420 - $prefixes = ['patchstack_', 'webarx_'];
421 - foreach ( $prefixes as $prefix ) {
422 - $tables = [ 'user_log', 'visitor_log', 'firewall_log', 'file_hashes', 'logic', 'ip', 'event_log' ];
423 - foreach ( $tables as $table ) {
424 - $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . $prefix . $table );
425 - }
362 + $tables = array( 'patchstack_user_log', 'patchstack_visitor_log', 'patchstack_firewall_log', 'patchstack_file_hashes', 'patchstack_logic', 'patchstack_ip', 'patchstack_event_log' );
363 + foreach ( $tables as $table ) {
364 + $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . $table );
426 365 }
427 366 }
428 367 }
429 368
@@ -437,13 +376,11 @@
437 376 return patchstack::get_instance();
438 377 }
439 378 }
440 379
441 -if ( ! has_action( 'plugins_loaded', [ patchstack(), 'init' ] ) ) {
442 - // Kick it off.
443 - add_action( 'plugins_loaded', [ patchstack(), 'init' ] );
380 +// Kick it off.
381 +add_action( 'plugins_loaded', array( patchstack(), 'hooks' ) );
444 382
445 - // Activation and deactivation hooks.
446 - register_activation_hook( __FILE__, [ patchstack(), 'activate' ] );
447 - register_deactivation_hook( __FILE__, [ patchstack(), 'deactivate' ] );
448 - register_uninstall_hook( __FILE__, 'patchstack_uninstall' );
449 -}
383 +// Activation and deactivation hooks.
384 +register_activation_hook( __FILE__, array( patchstack(), 'activate' ) );
385 +register_deactivation_hook( __FILE__, array( patchstack(), 'deactivate' ) );
386 +register_uninstall_hook( __FILE__, 'patchstack_uninstall' );