PluginProbe
Patchstack – WordPress & Plugins Security / 2.1.20
Patchstack – WordPress & Plugins Security v2.1.20
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 +32 -131 2.3.72.1.20 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.20
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.20';
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;
@@ -169,15 +169,8 @@
169 169 $this->basename = plugin_basename( __FILE__ );
170 170 $this->url = plugin_dir_url( __FILE__ );
171 171 $names = explode( '/', $this->basename );
172 172 $this->name = $names[0];
173 -
174 - // Define WP_CLI command.
175 - if ( defined( 'WP_CLI' ) && WP_CLI && method_exists('\WP_CLI', 'add_command')) {
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 - }
180 173 }
181 174
182 175 /**
183 176 * Call the constructor of all the Patchstack related classes.
@@ -185,9 +178,9 @@
185 178 * @return void
186 179 */
187 180 public function plugin_classes() {
188 181 // Define the array of the classes.
189 - foreach ( [
182 + foreach ( array(
190 183 'admin_options' => 'P_Admin_Options',
191 184 'cron' => 'P_Cron',
192 185 'api' => 'P_Api',
193 186 'login' => 'P_Login',
@@ -197,20 +190,20 @@
197 190 'hacker_log' => 'P_Hacker_Log',
198 191 'upload' => 'P_Upload',
199 192 'rules' => 'P_Rules',
200 193 'hide_login' => 'P_Hide_Login',
194 + 'listener' => 'P_Listener',
201 195 'event_log' => 'P_Event_Log',
202 196 'activation' => 'P_Activation',
203 - 'listener' => 'P_Listener',
204 197 'multisite' => 'P_Multisite',
198 + 'notice' => 'P_Cookie_Notice',
205 199 'admin_ajax' => 'P_Admin_Ajax',
206 200 'admin_general' => 'P_Admin_General',
207 201 'admin_menu' => 'P_Admin_Menu',
208 - ] as $var => $class ) {
202 + ) as $var => $class ) {
209 203 $this->$var = new $class( $this );
210 204 }
211 205
212 - // Load firewall base functionality.
213 206 $this->firewall_base = new P_Firewall( true, $this, true );
214 207 }
215 208
216 209 /**
@@ -223,86 +216,8 @@
223 216 $this->activation->activate( $this );
224 217 }
225 218
226 219 /**
227 - * Connects the Patchstack plugin to the API with the license id and secret key.
228 - *
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.
251 - */
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. Additional information:\n" . $result['body'] );
264 - return;
265 - }
266 -
267 - \WP_CLI::success( 'The Patchstack plugin has been successfully connected.' );
268 - }
269 -
270 - /**
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 220 * Deactivate the plugin.
306 221 *
307 222 * @return void
308 223 */
@@ -311,23 +226,24 @@
311 226 $this->activation->deactivate();
312 227 }
313 228
314 229 /**
315 - * Load translated strings for the plugin.
230 + * Boot Patchstack and its classes.
316 231 *
317 232 * @return void
318 233 */
319 - public function load_textdomain () {
320 - load_plugin_textdomain( 'patchstack', false, dirname( $this->basename ) . '/languages/' );
234 + public function hooks() {
235 + add_action( 'init', array( $this, 'init' ), ~PHP_INT_MAX );
321 236 }
322 237
323 238 /**
324 - * Boot Patchstack.
239 + * Boot Patchstack
325 240 *
326 241 * @return void
327 242 */
328 243 public function init() {
329 - add_action( 'init', [ $this, 'load_textdomain' ] );
244 + // Load translated strings for plugin.
245 + load_plugin_textdomain( 'patchstack', false, dirname( $this->basename ) . '/languages/' );
330 246
331 247 // Initialize plugin classes.
332 248 $this->plugin_classes();
333 249
@@ -338,9 +254,9 @@
338 254 if ( get_option( 'patchstack_api_token', '' ) == '' && get_option( 'patchstack_license_expiry', '' ) == '' ) {
339 255 $this->api->update_license_status();
340 256 }
341 257
342 - // Run firewall if not disabled and license activated.
258 + // Determine if the license is activated and not expired.
343 259 if ( get_option( 'patchstack_license_activated', 0 ) == 1 && get_option( 'patchstack_basic_firewall', 0 ) == 1 && get_option( 'patchstack_license_free', 0 ) == 0 ) {
344 260 $this->firewall = new P_Firewall( true, $this );
345 261 }
346 262 }
@@ -395,35 +311,22 @@
395 311 * @return void
396 312 */
397 313 function patchstack_uninstall() {
398 314 // 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_%'" );
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' );
316 + foreach ( $options as $option ) {
317 + delete_option( $option );
401 318
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 319 if ( is_multisite() ) {
414 - delete_site_option( $option->option_name );
320 + delete_site_option( $option );
415 321 }
416 322 }
417 323
418 - // Drop all tables.
324 + // Drop all Patchstack tables.
419 325 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 - }
326 + $tables = array( 'patchstack_user_log', 'patchstack_visitor_log', 'patchstack_firewall_log', 'patchstack_file_hashes', 'patchstack_logic', 'patchstack_ip', 'patchstack_event_log' );
327 + foreach ( $tables as $table ) {
328 + $wpdb->query( 'DROP TABLE IF EXISTS ' . $wpdb->prefix . $table );
426 329 }
427 330 }
428 331 }
429 332
@@ -437,13 +340,11 @@
437 340 return patchstack::get_instance();
438 341 }
439 342 }
440 343
441 -if ( ! has_action( 'plugins_loaded', [ patchstack(), 'init' ] ) ) {
442 - // Kick it off.
443 - add_action( 'plugins_loaded', [ patchstack(), 'init' ] );
344 +// Kick it off.
345 +add_action( 'plugins_loaded', array( patchstack(), 'hooks' ) );
444 346
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 -}
347 +// Activation and deactivation hooks.
348 +register_activation_hook( __FILE__, array( patchstack(), 'activate' ) );
349 +register_deactivation_hook( __FILE__, array( patchstack(), 'deactivate' ) );
350 +register_uninstall_hook( __FILE__, 'patchstack_uninstall' );