PluginProbe
Patchstack – WordPress & Plugins Security / 2.2.8
Patchstack – WordPress & Plugins Security v2.2.8
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 +64 -22 2.1.232.2.8 View file →
@@ -1,10 +1,11 @@
1 1 <?php
2 2 /**
3 3 * Plugin Name: Patchstack Security
4 - * Plugin URI: https://patchstack.com
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
5 6 * Description: Patchstack identifies security vulnerabilities in WordPress plugins, themes, and core.
6 - * Version: 2.1.23
7 + * Version: 2.2.8
7 8 * Author: Patchstack
8 9 * License: GPLv3
9 10 * Text Domain: patchstack
10 11 * Domain Path: /languages
@@ -32,9 +33,9 @@
32 33
33 34 // Set up our filename.
34 35 $file_name = strtolower( str_replace( '_', '-', substr( $class_name, strlen( 'P_' ) ) ) );
35 36 $dir = trailingslashit( dirname( __FILE__ ) ) . 'includes/';
36 - $target = array( $dir . $file_name . '.php', $dir . 'admin/' . str_replace( 'admin-', '', $file_name ) . '.php' );
37 + $target = [ $dir . $file_name . '.php', $dir . 'admin/' . str_replace( 'admin-', '', $file_name ) . '.php' ];
37 38
38 39 // Attempt each target and load if it exists.
39 40 foreach ( $target as $file ) {
40 41 if ( file_exists( $file ) ) {
@@ -57,9 +58,9 @@
57 58 * The plugin version.
58 59 *
59 60 * @var string
60 61 */
61 - const VERSION = '2.1.23';
62 + const VERSION = '2.2.8';
62 63
63 64 /**
64 65 * API URL of Patchstack to communicate with.
65 66 *
@@ -113,9 +114,9 @@
113 114 * Detailed activation error messages.
114 115 *
115 116 * @var array
116 117 */
117 - protected $activation_errors = array();
118 + protected $activation_errors = [];
118 119
119 120 /**
120 121 * Singleton instance of plugin.
121 122 *
@@ -169,8 +170,13 @@
169 170 $this->basename = plugin_basename( __FILE__ );
170 171 $this->url = plugin_dir_url( __FILE__ );
171 172 $names = explode( '/', $this->basename );
172 173 $this->name = $names[0];
174 +
175 + // Define WP_CLI command.
176 + if ( defined( 'WP_CLI' ) && WP_CLI && method_exists('\WP_CLI', 'add_command')) {
177 + \WP_CLI::add_command( 'patchstack activate', [ $this, 'cli_activate' ] );
178 + }
173 179 }
174 180
175 181 /**
176 182 * Call the constructor of all the Patchstack related classes.
@@ -178,9 +184,9 @@
178 184 * @return void
179 185 */
180 186 public function plugin_classes() {
181 187 // Define the array of the classes.
182 - foreach ( array(
188 + foreach ( [
183 189 'admin_options' => 'P_Admin_Options',
184 190 'cron' => 'P_Cron',
185 191 'api' => 'P_Api',
186 192 'login' => 'P_Login',
@@ -198,12 +204,13 @@
198 204 'notice' => 'P_Cookie_Notice',
199 205 'admin_ajax' => 'P_Admin_Ajax',
200 206 'admin_general' => 'P_Admin_General',
201 207 'admin_menu' => 'P_Admin_Menu',
202 - ) as $var => $class ) {
208 + ] as $var => $class ) {
203 209 $this->$var = new $class( $this );
204 210 }
205 211
212 + // Load firewall base functionality.
206 213 $this->firewall_base = new P_Firewall( true, $this, true );
207 214 }
208 215
209 216 /**
@@ -216,28 +223,63 @@
216 223 $this->activation->activate( $this );
217 224 }
218 225
219 226 /**
220 - * Deactivate the plugin.
227 + * Connects the Patchstack plugin to the API with the license id and secret key.
221 228 *
222 - * @return void
229 + * Returns an error if the connection was not successful.
230 + *
231 + * ## OPTIONS
232 + *
233 + * [<id>]
234 + * : The API client id.
235 + *
236 + * [<secret>]
237 + * : The API secret key.
238 + *
239 + * <secret-id>
240 + * : The API client id and secret key merged together, found in the App. E.g. 2b072e8b60402e30d481df351fc08183906254e0-123456
241 + *
242 + * ## EXAMPLES
243 + *
244 + * $ wp patchstack activate 123456 2b072e8b60402e30d481df351fc08183906254e0
245 + * 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.
223 251 */
224 - public function deactivate() {
225 - $this->plugin_classes();
226 - $this->activation->deactivate();
252 + 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 + }
260 +
261 + $result = $this->activation->alter_license( $id, $secret, 'activate' );
262 + 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.' );
264 + return;
265 + }
266 +
267 + \WP_CLI::success( 'The Patchstack plugin has been successfully connected.' );
227 268 }
228 269
229 270 /**
230 - * Boot Patchstack and its classes.
271 + * Deactivate the plugin.
231 272 *
232 273 * @return void
233 274 */
234 - public function hooks() {
235 - add_action( 'init', array( $this, 'init' ), ~PHP_INT_MAX );
275 + public function deactivate() {
276 + $this->plugin_classes();
277 + $this->activation->deactivate();
236 278 }
237 279
238 280 /**
239 - * Boot Patchstack
281 + * Boot Patchstack.
240 282 *
241 283 * @return void
242 284 */
243 285 public function init() {
@@ -254,9 +296,9 @@
254 296 if ( get_option( 'patchstack_api_token', '' ) == '' && get_option( 'patchstack_license_expiry', '' ) == '' ) {
255 297 $this->api->update_license_status();
256 298 }
257 299
258 - // Determine if the license is activated and not expired.
300 + // Run firewall if not disabled and license activated.
259 301 if ( get_option( 'patchstack_license_activated', 0 ) == 1 && get_option( 'patchstack_basic_firewall', 0 ) == 1 && get_option( 'patchstack_license_free', 0 ) == 0 ) {
260 302 $this->firewall = new P_Firewall( true, $this );
261 303 }
262 304 }
@@ -311,9 +353,9 @@
311 353 * @return void
312 354 */
313 355 function patchstack_uninstall() {
314 356 // Delete most of the Patchstack options.
315 - $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' );
357 + $options = [ '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' ];
316 358 foreach ( $options as $option ) {
317 359 delete_option( $option );
318 360
319 361 if ( is_multisite() ) {
@@ -322,9 +364,9 @@
322 364 }
323 365
324 366 // Drop all Patchstack tables.
325 367 global $wpdb;
326 - $tables = array( 'patchstack_user_log', 'patchstack_visitor_log', 'patchstack_firewall_log', 'patchstack_file_hashes', 'patchstack_logic', 'patchstack_ip', 'patchstack_event_log' );
368 + $tables = [ 'patchstack_user_log', 'patchstack_visitor_log', 'patchstack_firewall_log', 'patchstack_file_hashes', 'patchstack_logic', 'patchstack_ip', 'patchstack_event_log' ];
327 369 foreach ( $tables as $table ) {
328 370 $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . $table );
329 371 }
330 372 }
@@ -341,10 +383,10 @@
341 383 }
342 384 }
343 385
344 386 // Kick it off.
345 -add_action( 'plugins_loaded', array( patchstack(), 'hooks' ) );
387 +add_action( 'plugins_loaded', [ patchstack(), 'init' ] );
346 388
347 389 // Activation and deactivation hooks.
348 -register_activation_hook( __FILE__, array( patchstack(), 'activate' ) );
349 -register_deactivation_hook( __FILE__, array( patchstack(), 'deactivate' ) );
390 +register_activation_hook( __FILE__, [ patchstack(), 'activate' ] );
391 +register_deactivation_hook( __FILE__, [ patchstack(), 'deactivate' ] );
350 392 register_uninstall_hook( __FILE__, 'patchstack_uninstall' );