Skip to content

Commit d25e82e

Browse files
authored
Merge pull request #5 from udx/develop-alexey
Improve security while processing AJAX requests in Admin Panel
2 parents cf967cf + 36e5bab commit d25e82e

File tree

5 files changed

+34
-22
lines changed

5 files changed

+34
-22
lines changed

changes.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
### 1.2.3
2+
3+
* Improve security while processing AJAX requests in Admin Panel.
4+
15
### 1.2.2
26

37
* Remove dependency from `udx/lib-utility`.

gruntfile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Build Plugin.
33
*
44
* @author potanin@UD
5-
* @version 1.2.2
5+
* @version 1.2.3
66
* @param grunt
77
*/
88
module.exports = function( grunt ) {

lib/classes/class-bootstrap.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class Bootstrap extends Scaffold {
1818
/**
1919
*
2020
*/
21-
public static $version = '1.2.2';
21+
public static $version = '1.2.3';
2222

2323
/**
2424
*

lib/classes/class-update-checker.php

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -349,115 +349,116 @@ public function check_response_for_errors( $response ) {
349349

350350
$plugins = get_plugins();
351351
$name = isset( $plugins[$this->name] ) ? $plugins[$this->name]['Name'] : $this->name;
352+
$nonce = wp_create_nonce( 'ud_api_dismiss' );
352353

353354
if ( isset( $response->errors['no_key'] ) && $response->errors['no_key'] == 'no_key' && isset( $response->errors['no_subscription'] ) && $response->errors['no_subscription'] == 'no_subscription' ) {
354355

355356
$no_key_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_no_key', '' );
356357
$show_no_key_error = $this->check_dismiss_time( $no_key_dismissed );
357358
if( $show_no_key_error ) {
358-
$this->errors[] = sprintf( __( 'A license key for %s could not be found. Maybe you forgot to enter a license key when setting up %s, or the key was deactivated in your account. You can reactivate or purchase a license key from your account <a href="%s" target="_blank">Licences</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_no_key" href="#">dismiss</a>.', $this->text_domain ), $name, $name, $this->renew_license_url, sanitize_key( $name ) );
359+
$this->errors[] = sprintf( __( 'A license key for %s could not be found. Maybe you forgot to enter a license key when setting up %s, or the key was deactivated in your account. You can reactivate or purchase a license key from your account <a href="%s" target="_blank">Licences</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_no_key" data-nonce="%s" href="#">dismiss</a>.', $this->text_domain ), $name, $name, $this->renew_license_url, sanitize_key( $name ), $nonce );
359360
}
360361

361362
$no_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_no_subscription', '' );
362363
$show_no_subscription_error = $this->check_dismiss_time( $no_subscription_dismissed );
363364
if( $show_no_subscription_error ) {
364-
$this->errors[] = sprintf( __( 'A subscription for %s could not be found. You can purchase a subscription from your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_no_subscription" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) );
365+
$this->errors[] = sprintf( __( 'A subscription for %s could not be found. You can purchase a subscription from your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_no_subscription" data-nonce="%s" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce );
365366
}
366367

367368
} else if ( isset( $response->errors['exp_license'] ) && $response->errors['exp_license'] == 'exp_license' ) {
368369

369370
$exp_license_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_exp_license', '' );
370371
$show_exp_license_error = $this->check_dismiss_time( $exp_license_dismissed );
371372
if( $show_exp_license_error ) {
372-
$this->errors[] = sprintf( __( 'The license key for %s has expired. You can reactivate or get a license key from your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_exp_license" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) );
373+
$this->errors[] = sprintf( __( 'The license key for %s has expired. You can reactivate or get a license key from your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_exp_license" data-nonce="%s" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce );
373374
}
374375

375376
} else if ( isset( $response->errors['hold_subscription'] ) && $response->errors['hold_subscription'] == 'hold_subscription' ) {
376377

377378
$hold_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_hold_subscription', '' );
378379
$show_hold_subscription_error = $this->check_dismiss_time( $hold_subscription_dismissed );
379380
if( $show_hold_subscription_error ) {
380-
$this->errors[] = sprintf( __( 'The subscription for %s is on-hold. You can reactivate the subscription from your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_hold_subscription" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) );
381+
$this->errors[] = sprintf( __( 'The subscription for %s is on-hold. You can reactivate the subscription from your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_hold_subscription" data-nonce="%s" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce );
381382
}
382383

383384
} else if ( isset( $response->errors['cancelled_subscription'] ) && $response->errors['cancelled_subscription'] == 'cancelled_subscription' ) {
384385

385386
$cancelled_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_cancelled_subscription', '' );
386387
$show_cancelled_subscription_error = $this->check_dismiss_time( $cancelled_subscription_dismissed );
387388
if( $show_cancelled_subscription_error ) {
388-
$this->errors[] = sprintf( __( 'The subscription for %s has been cancelled. You can renew the subscription from your account <a href="%s" target="_blank">dashboard</a>. A new license key will be emailed to you after your order has been completed. <a class="dismiss-error dismiss" data-key="dismissed_error_%s_cancelled_subscription" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) );
389+
$this->errors[] = sprintf( __( 'The subscription for %s has been cancelled. You can renew the subscription from your account <a href="%s" target="_blank">dashboard</a>. A new license key will be emailed to you after your order has been completed. <a class="dismiss-error dismiss" data-key="dismissed_error_%s_cancelled_subscription" data-nonce="%s" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce );
389390
}
390391

391392
} else if ( isset( $response->errors['exp_subscription'] ) && $response->errors['exp_subscription'] == 'exp_subscription' ) {
392393

393394
$exp_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_exp_subscription', '' );
394395
$show_exp_subscription_error = $this->check_dismiss_time( $exp_subscription_dismissed );
395396
if( $show_exp_subscription_error ) {
396-
$this->errors[] = sprintf( __( 'The subscription for %s has expired. You can reactivate the subscription from your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_exp_subscription" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) ) ;
397+
$this->errors[] = sprintf( __( 'The subscription for %s has expired. You can reactivate the subscription from your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_exp_subscription" data-nonce="%s" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ) ;
397398
}
398399

399400
} else if ( isset( $response->errors['suspended_subscription'] ) && $response->errors['suspended_subscription'] == 'suspended_subscription' ) {
400401

401402
$suspended_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_suspended_subscription', '' );
402403
$show_suspended_subscription_error = $this->check_dismiss_time( $suspended_subscription_dismissed );
403404
if( $show_suspended_subscription_error ) {
404-
$this->errors[] = sprintf( __( 'The subscription for %s has been suspended. You can reactivate the subscription from your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_suspended_subscription" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) ) ;
405+
$this->errors[] = sprintf( __( 'The subscription for %s has been suspended. You can reactivate the subscription from your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_suspended_subscription" data-nonce="%s" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ) ;
405406
}
406407

407408
} else if ( isset( $response->errors['pending_subscription'] ) && $response->errors['pending_subscription'] == 'pending_subscription' ) {
408409

409410
$pending_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_pending_subscription', '' );
410411
$show_pending_subscription_error = $this->check_dismiss_time( $pending_subscription_dismissed );
411412
if( $show_pending_subscription_error ) {
412-
$this->errors[] = sprintf( __( 'The subscription for %s is still pending. You can check on the status of the subscription from your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_pending_subscription" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) ) ;
413+
$this->errors[] = sprintf( __( 'The subscription for %s is still pending. You can check on the status of the subscription from your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_pending_subscription" data-nonce="%s" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ) ;
413414
}
414415

415416
} else if ( isset( $response->errors['trash_subscription'] ) && $response->errors['trash_subscription'] == 'trash_subscription' ) {
416417

417418
$trash_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_trash_subscription', '' );
418419
$show_trash_subscription_error = $this->check_dismiss_time( $trash_subscription_dismissed );
419420
if( $show_trash_subscription_error ) {
420-
$this->errors[] = sprintf( __( 'The subscription for %s has been placed in the trash and will be deleted soon. You can get a new subscription from your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_trash_subscription" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) ) ;
421+
$this->errors[] = sprintf( __( 'The subscription for %s has been placed in the trash and will be deleted soon. You can get a new subscription from your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_trash_subscription" data-nonce="%s" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ) ;
421422
}
422423

423424
} else if ( isset( $response->errors['no_subscription'] ) && $response->errors['no_subscription'] == 'no_subscription' ) {
424425

425426
$no_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_no_subscription', '' );
426427
$show_no_subscription_error = $this->check_dismiss_time( $no_subscription_dismissed );
427428
if( $show_no_subscription_error ) {
428-
$this->errors[] = sprintf( __( 'A subscription for %s could not be found. You can get a subscription from your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_no_subscription" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) );
429+
$this->errors[] = sprintf( __( 'A subscription for %s could not be found. You can get a subscription from your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_no_subscription" data-nonce="%s" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce );
429430
}
430431

431432
} else if ( isset( $response->errors['no_activation'] ) && $response->errors['no_activation'] == 'no_activation' ) {
432433

433434
$no_activation_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_no_activation', '' );
434435
$show_no_activation_error = $this->check_dismiss_time( $no_activation_dismissed );
435436
if( $show_no_activation_error ) {
436-
$this->errors[] = sprintf( __( '%s has not been activated. Go to the settings page and enter the license key and license email to activate %s. <a class="dismiss-error dismiss" data-key="dismissed_error_%s_no_activation" href="#">dismiss</a>.', $this->text_domain ), $name, $name, sanitize_key( $name ) ) ;
437+
$this->errors[] = sprintf( __( '%s has not been activated. Go to the settings page and enter the license key and license email to activate %s. <a class="dismiss-error dismiss" data-key="dismissed_error_%s_no_activation" data-nonce="%s" href="#">dismiss</a>.', $this->text_domain ), $name, $name, sanitize_key( $name ), $nonce ) ;
437438
}
438439

439440
} else if ( isset( $response->errors['no_key'] ) && $response->errors['no_key'] == 'no_key' ) {
440441

441442
$no_key_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_no_key', '' );
442443
$show_no_key_error = $this->check_dismiss_time( $no_key_dismissed );
443444
if( $show_no_key_error ) {
444-
$this->errors[] = sprintf( __( 'A license key for %s could not be found. Maybe you forgot to enter a license key when setting up %s, or the key was deactivated in your account. You can reactivate or get a license key from your account <a href="%s" target="_blank">Licences</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_no_key" href="#">dismiss</a>.', $this->text_domain ), $name, $name, $this->renew_license_url, sanitize_key( $name ) );
445+
$this->errors[] = sprintf( __( 'A license key for %s could not be found. Maybe you forgot to enter a license key when setting up %s, or the key was deactivated in your account. You can reactivate or get a license key from your account <a href="%s" target="_blank">Licences</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_no_key" data-nonce="%s" href="#">dismiss</a>.', $this->text_domain ), $name, $name, $this->renew_license_url, sanitize_key( $name ), $nonce );
445446
}
446447

447448
} else if ( isset( $response->errors['download_revoked'] ) && $response->errors['download_revoked'] == 'download_revoked' ) {
448449

449450
$download_revoked_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_download_revoked', '' );
450451
$show_download_revoked_error = $this->check_dismiss_time( $download_revoked_dismissed );
451452
if( $show_download_revoked_error ) {
452-
$this->errors[] = sprintf( __( 'Download permission for %s has been revoked possibly due to a license key or subscription expiring. You can reactivate or get a license key from your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_download_revoked" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) ) ;
453+
$this->errors[] = sprintf( __( 'Download permission for %s has been revoked possibly due to a license key or subscription expiring. You can reactivate or get a license key from your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_download_revoked" data-nonce="%s" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ) ;
453454
}
454455

455456
} else if ( isset( $response->errors['switched_subscription'] ) && $response->errors['switched_subscription'] == 'switched_subscription' ) {
456457

457458
$switched_subscription_dismissed = get_option( 'dismissed_error_' . sanitize_key( $name ) . '_switched_subscription', '' );
458459
$show_switched_subscription_error = $this->check_dismiss_time( $switched_subscription_dismissed );
459460
if( $show_switched_subscription_error ) {
460-
$this->errors[] = sprintf( __( 'You changed the subscription for %s, so you will need to enter your new API License Key in the settings page. The License Key should have arrived in your email inbox, if not you can get it by logging into your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_switched_subscription" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ) ) ;
461+
$this->errors[] = sprintf( __( 'You changed the subscription for %s, so you will need to enter your new API License Key in the settings page. The License Key should have arrived in your email inbox, if not you can get it by logging into your account <a href="%s" target="_blank">dashboard</a> | <a class="dismiss-error dismiss" data-key="dismissed_error_%s_switched_subscription" data-nonce="%s" href="#">dismiss</a>.', $this->text_domain ), $name, $this->renew_license_url, sanitize_key( $name ), $nonce ) ;
461462
}
462463

463464
}
@@ -499,6 +500,7 @@ public function print_scripts() {
499500
var data = {
500501
action: 'ud_api_dismiss',
501502
key: _this.data('key'),
503+
_ajax_nonce: _this.data('nonce'),
502504
}
503505

504506
jQuery.post( "<?php echo admin_url( 'admin-ajax.php' ); ?>", data, function ( result_data ) {
@@ -541,21 +543,27 @@ public function check_dismiss_time( $time = '' ) {
541543
* @throws \Exception
542544
*/
543545
public function dismiss_notices(){
546+
check_ajax_referer('ud_api_dismiss');
547+
544548
$response = array(
545549
'success' => '0',
546550
'error' => __( 'There was an error in request.', $this->text_domain ),
547551
);
552+
548553
$error = false;
549554

550-
if( empty($_POST['key']) ) {
551-
$response['error'] = __( 'Invalid key', $this->text_domain );
555+
$option_key = isset($_POST['key']) ? sanitize_key($_POST['key']) : '';
556+
557+
if ( strpos($option_key, 'dismissed_') !== 0 ) {
558+
$response['error'] = __( 'Invalid key', $this->domain );
552559
$error = true;
553560
}
554-
555-
if ( ! $error && update_option( ( $_POST['key'] ), time() ) ) {
561+
562+
if ( !$error && update_option( $option_key, time() ) ) {
556563
$response['success'] = '1';
564+
$response['error'] = null;
557565
}
558-
566+
559567
wp_send_json( $response );
560568
}
561569

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "lib-ud-api-client",
3-
"version": "1.2.2",
3+
"version": "1.2.3",
44
"description": "UD Client for WooCommerce API Manager",
55
"repository": {
66
"type": "git",

0 commit comments

Comments
 (0)