Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/booking-package/index.php
+++ b/booking-package/index.php
@@ -3,7 +3,7 @@
Plugin Name: Booking Package
Plugin URI: https://saasproject.net/plans/
Description: Booking Package is a high-performance booking calendar system that anyone can easily use.
-Version: 1.7.16
+Version: 1.7.17
Author: SAASPROJECT Booking Package
Author URI: https://saasproject.net/
License: GPL2
@@ -255,6 +255,8 @@
add_filter('login_headerurl', array($this, 'login_headerurl'));
add_filter('login_headertext', array($this, 'login_headertext'));
add_action('wp_print_footer_scripts', array($this, 'add_footer_scripts'), 5);
+ add_action('admin_post_booking-package-activate-subscription', array($this, 'activatePaidSubscription'));
+ add_action('admin_post_nopriv_booking-package-activate-subscription', array($this, 'activatePaidSubscription'));
if (is_admin() === false) {
@@ -333,12 +335,6 @@
}
- if (isset($_POST['mode']) && $_POST['mode'] == 'booking-package-activate-subscription') {
-
- add_action('init', array($this, 'activatePaidSubscription'));
-
- }
-
if (isset($_GET['mode']) && isset($_GET['unique']) && $_GET['mode'] == 'booking-package-update-paid-subscription') {
add_action('init', array($this, 'updatePaidSubscription'));
@@ -2151,6 +2147,19 @@
'booking-package-script-Booking_app-js' => plugin_dir_url( __FILE__ ) . 'js/Booking_app.js' . '?ver=' . $this->plugin_version . '&date=' . $pluginDate,
'booking-package-script-Reservation_manage-js' => plugin_dir_url( __FILE__ ) . 'js/Reservation_manage.js' . '?ver=' . $this->plugin_version . '&date=' . $pluginDate,
);
+ /**
+ $files = array(
+ 'booking-package-script-Error-js' => plugin_dir_url( __FILE__ ) . 'js/Error.js' . '?ver=' . $this->get_plugin_asset_version('js/Error.js'),
+ 'booking-package-script-i18n-js' => plugin_dir_url( __FILE__ ) . 'js/i18n.js' . '?ver=' . $this->get_plugin_asset_version('js/i18n.js'),
+ 'booking-package-script-XMLHttp-js' => plugin_dir_url( __FILE__ ) . 'js/XMLHttp.js' . '?ver=' . $this->get_plugin_asset_version('js/XMLHttp.js'),
+ 'booking-package-script-Input-js' => plugin_dir_url( __FILE__ ) . 'js/Input.js' . '?ver=' . $this->get_plugin_asset_version('js/Input.js'),
+ 'booking-package-script-Calendar-js' => plugin_dir_url( __FILE__ ) . 'js/Calendar.js' . '?ver=' . $this->get_plugin_asset_version('js/Calendar.js'),
+ 'booking-package-script-Hotel-js' => plugin_dir_url( __FILE__ ) . 'js/Hotel.js' . '?ver=' . $this->get_plugin_asset_version('js/Hotel.js'),
+ 'booking-package-script-Member-js' => plugin_dir_url( __FILE__ ) . 'js/Member.js' . '?ver=' . $this->get_plugin_asset_version('js/Member.js'),
+ 'booking-package-script-Booking_app-js' => plugin_dir_url( __FILE__ ) . 'js/Booking_app.js' . '?ver=' . $this->get_plugin_asset_version('js/Booking_app.js'),
+ 'booking-package-script-Reservation_manage-js' => plugin_dir_url( __FILE__ ) . 'js/Reservation_manage.js' . '?ver=' . $this->get_plugin_asset_version('js/Reservation_manage.js'),
+ );
+ **/
if ($this->front_end_js === true) {
@@ -4428,7 +4437,12 @@
public function selectedMode(){
- $response = array('status' => 'error', 'mode' => $_POST['mode']);
+ $response = array('status' => 'error', 'mode' => sanitize_text_field($_POST['mode']) );
+ if (is_user_logged_in() === false || (current_user_can('edit_others_posts') === false && current_user_can('booking_package_manager') === false && current_user_can('booking_package_editor') === false) ) {
+
+ return $response;
+
+ }
$setting = $this->setting;
@@ -5283,10 +5297,14 @@
public function activatePaidSubscription() {
- $setting = $this->setting;
- $setting->lookingForSubscription( sanitize_text_field($_POST['customer_id_for_subscriptions']), sanitize_text_field($_POST['subscriptions_id_for_subscriptions']) );
- header('Location: ' . admin_url("admin.php?page=" . $this->plugin_name . "_setting_page" . "&tab=subscriptionLink"));
- die();
+ if (isset($_POST['mode']) && $_POST['mode'] == 'booking-package-activate-subscription' && isset($_POST['customer_id_for_subscriptions']) && isset($_POST['subscriptions_id_for_subscriptions'])) {
+
+ $setting = $this->setting;
+ $setting->lookingForSubscription( sanitize_text_field($_POST['customer_id_for_subscriptions']), sanitize_text_field($_POST['subscriptions_id_for_subscriptions']) );
+ header('Location: ' . admin_url("admin.php?page=" . $this->plugin_name . "_setting_page" . "&tab=subscriptionLink"));
+ die();
+
+ }
}
--- a/booking-package/lib/CreditCard.php
+++ b/booking-package/lib/CreditCard.php
@@ -13,6 +13,8 @@
public $prefix = null;
+ public $request_timeout = 30;
+
public function __construct($pluginName, $prefix){
$this->pluginName = $pluginName;
@@ -64,6 +66,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => $params,
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($secret . ':')
@@ -108,6 +111,7 @@
$args = array(
'method' => 'GET',
+ 'timeout' => $this->request_timeout,
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($secret . ':')
)
@@ -158,6 +162,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => $params,
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($secret . ':')
@@ -202,6 +207,7 @@
$args = array(
'method' => 'GET',
+ 'timeout' => $this->request_timeout,
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($secret . ':')
)
@@ -247,6 +253,7 @@
$args = array(
'method' => 'DELETE',
+ 'timeout' => $this->request_timeout,
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($secret . ':')
)
@@ -276,6 +283,7 @@
$args = array(
'method' => 'DELETE',
+ 'timeout' => $this->request_timeout,
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($secret . ':')
)
@@ -401,6 +409,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => $params,
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($secret . ':')
@@ -424,6 +433,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => http_build_query($params),
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($secret . ':')
@@ -446,6 +456,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => $params,
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($secret . ':')
@@ -477,6 +488,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => $params,
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($secret . ':')
@@ -497,6 +509,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => $params,
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($secret . ':')
@@ -515,6 +528,7 @@
$params = array();
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
/**'body' => $params, **/
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($secret . ':')
@@ -551,6 +565,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => $params,
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($secret . ':')
@@ -696,6 +711,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => $params,
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($public_key . ':' . $secret)
@@ -741,6 +757,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'headers' => array(
'content-type' => 'application/json',
'Authorization' => 'Bearer ' . $token
@@ -793,6 +810,7 @@
$args = array(
'method' => 'PATCH',
+ 'timeout' => $this->request_timeout,
'body' => json_encode($params),
'headers' => array(
'content-type' => 'application/json',
@@ -840,6 +858,7 @@
$args = array(
'method' => 'GET',
+ 'timeout' => $this->request_timeout,
'headers' => array(
'content-type' => 'application/json',
'Authorization' => 'Bearer ' . $token
@@ -885,6 +904,7 @@
$args = array(
'method' => 'PATCH',
+ 'timeout' => $this->request_timeout,
'body' => json_encode($params),
'headers' => array(
'content-type' => 'application/json',
@@ -934,6 +954,7 @@
$args = array(
'method' => 'GET',
+ 'timeout' => $this->request_timeout,
'headers' => array(
'content-type' => 'application/json',
'Authorization' => 'Bearer ' . $token
@@ -967,6 +988,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
/**'body' => json_encode($params),**/
'headers' => array(
'content-type' => 'application/json',
@@ -1017,6 +1039,7 @@
$args = array(
'method' => 'GET',
+ 'timeout' => $this->request_timeout,
/** 'body' => $params, **/
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($secret . ':')
@@ -1061,6 +1084,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
/** 'body' => $params, **/
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($secret . ':')
@@ -1089,6 +1113,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => $params,
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($secret . ':')
--- a/booking-package/lib/Schedule.php
+++ b/booking-package/lib/Schedule.php
@@ -31,6 +31,8 @@
public $payWithPayPay = 0;
+ public $request_timeout = 30;
+
public function __construct($prefix, $pluginName, $currencies, $userRoleName = 'booking_package_user'){
global $wpdb;
@@ -569,8 +571,21 @@
}
public function createUser($administrator = 0, $accountKey = null) {
+
+ if (intval($administrator) === 1) {
+
+ if (is_user_logged_in() === false || ( current_user_can('edit_users') === false && current_user_can('booking_package_manager') === false && current_user_can('booking_package_editor') === false) ) {
+
+ return array(
+ 'status' => 'error',
+ 'error_messages' => 'Permission denied: You do not have authorization to create a user.'
+ );
+
+ }
+
+ }
- if ($administrator == 0) {
+ if (intval($administrator) === 0) {
if (!isset($_POST['googleReCaptchaToken'])) {
@@ -626,14 +641,15 @@
}
-
+ $s_user_login = sanitize_user($_POST['user_login']);
+ $s_user_email = sanitize_email($_POST['user_email']);
$response = array("status" => "success", "activation" => $activation);
- #$user_login = username_exists($_POST['user_login']);
+ #$user_login = username_exists($s_user_login);
$user_pass = trim($_POST['user_pass']);
$userdata = array(
- 'user_login' => $_POST['user_login'],
+ 'user_login' => sanitize_user($s_user_login),
'user_pass' => $user_pass,
- 'user_email' => $_POST['user_email'],
+ 'user_email' => $s_user_email,
'role' => $this->userRoleName,
);
@@ -663,17 +679,17 @@
}
update_user_meta($user_id, 'show_admin_bar_front', 'false');
- $hash = wp_hash(sanitize_text_field($_POST['user_email']).sanitize_text_field($_POST['user_login']).date('U'));
+ $hash = wp_hash(sanitize_text_field($s_user_email).sanitize_text_field($s_user_login).date('U'));
$response['user_id'] = $user_id;
- $response['user_login'] = esc_html($_POST['user_login']);
- $response['user_email'] = esc_html($_POST['user_email']);
+ $response['user_login'] = esc_html($s_user_login);
+ $response['user_email'] = esc_html($s_user_email);
$response['profile'] = $customUserFields;
- $this->add_user($user_id, $_POST['user_login'], $_POST['user_email'], $activation, $hash);
+ $this->add_user($user_id, $s_user_login, $s_user_email, $activation, $hash);
if ($activation == 1) {
$userdata = array(
- 'user_login' => $_POST['user_login'],
+ 'user_login' => $s_user_login,
'user_password' => $user_pass,
'remember' => true
);
@@ -693,22 +709,11 @@
} else {
- $uri = $_POST['permalink']."?mode=activation&k=".$hash."&u=".sanitize_text_field($_POST['user_login']);
+ $uri = $_POST['permalink'] . "?mode=activation&k=" . $hash . "&u=" . $s_user_login;
$subject = get_option($this->prefix."subject_email_for_member", "No title");
$body = get_option($this->prefix."body_email_for_member", "No message");
- /**
- if (preg_match('/([activation_url])/', $body, $matches)) {
-
- $body = preg_replace('/([activation_url])/', $uri, $body);
-
- } else {
-
- $body = $uri."n".$body;
-
- }
- **/
$body = str_replace('[activation_url]', $uri, $body);
- $this->sendMail(sanitize_text_field($_POST['user_email']), $subject, $body, 'text', $accountKey);
+ $this->sendMail($s_user_email, $subject, $body, 'text', $accountKey);
}
@@ -809,23 +814,42 @@
$response = array("status" => "error");
$userId = 0;
- $currentUser = wp_get_current_user();
- if ($administrator === 0 && $currentUser->user_login !== sanitize_text_field($_POST['user_login'])) {
+ if (is_user_logged_in() === false) {
- $response['error_messages'] = 'Error';
+ $response['error_messages'] = 'Unauthorized: You must be logged in.';
return $response;
}
+ $currentUser = wp_get_current_user();
$user = get_user_by('login', sanitize_text_field($_POST['user_login']));
if ($user === false) {
return $response;
- } else {
+ }
+
+ $userId = $user->ID;
+ $userOldEmail = $user->user_email;
+
+ if ( user_can( $userId, 'manage_options' ) && current_user_can( 'manage_options' ) === false ) {
+
+ $response['error_messages'] = 'Permission denied: You cannot edit an administrator account.';
+ return $response;
+
+ }
+
+ if ($currentUser->ID !== $userId && current_user_can('edit_users') === false) {
- $userId = $user->ID;
- $userOldEmail = $user->user_email;
+ $response['error_messages'] = 'Permission denied: You cannot edit this user.';
+ return $response;
+
+ }
+
+ if ($administrator === 0 && $currentUser->user_login !== sanitize_text_field($_POST['user_login'])) {
+
+ $response['error_messages'] = 'Error';
+ return $response;
}
@@ -849,7 +873,7 @@
$userdata = array('ID' => $userId);
if (isset($_POST['user_email'])) {
- $userdata['user_email'] = $_POST['user_email'];
+ $userdata['user_email'] = sanitize_text_field($_POST['user_email']);
$hash = wp_hash(sanitize_text_field($_POST['user_email']) . sanitize_text_field($_POST['user_login']) . date('U'));
} else {
@@ -1800,15 +1824,25 @@
require_once( ABSPATH.'wp-admin/includes/user.php' );
$reality = false;
$userId = 0;
+
+ if (is_user_logged_in() === false) {
+
+ $response['error_messages'] = 'Unauthorized: You must be logged in.';
+ return $response;
+
+ }
+
+ $currentUser = wp_get_current_user();
+
if (intval($administrator) == 1) {
$user = get_user_by('login', sanitize_text_field($_POST['user_login']));
if ($user !== false) {
$reality = true;
+ $userId = $user->ID;
}
- $userId = $user->ID;
} else {
@@ -1821,6 +1855,22 @@
}
+
+ if (user_can( $userId, 'manage_options' ) && current_user_can( 'manage_options' ) === false) {
+
+ $response['error_messages'] = 'Permission denied: You cannot delete an administrator account.';
+ return $response;
+
+ }
+
+ if ($currentUser->ID !== $userId && current_user_can( 'delete_users' ) === false) {
+
+ $response['error_messages'] = 'Permission denied: You cannot delete this user.';
+ return $response;
+
+ }
+
+
if ($reality === true) {
$response = array("status" => "success", "userId" => $userId);
@@ -2116,6 +2166,7 @@
$product = $products[$index];
$args = array(
'method' => 'GET',
+ 'timeout' => $this->request_timeout,
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($secret . ':')
)
@@ -9380,6 +9431,7 @@
$secretKey = get_option($this->prefix . "hCaptcha_Secret_key", "0");
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => array(
'secret' => $secretKey,
'response' => $token
@@ -9472,6 +9524,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => $event,
);
$json = wp_remote_request('https://recaptchaenterprise.googleapis.com/v1/projects/' . $projectId . '/assessments?key=' . $apiKey, $args);
@@ -9528,6 +9581,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => array(
'secret' => $secretKey,
'response' => $googleReCaptchaToken
@@ -14812,6 +14866,7 @@
);
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => json_encode($params),
'headers' => array(
'content-type' => 'application/json',
@@ -14876,6 +14931,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => $params,
'headers' => array(
'Authorization' => 'Basic ' . base64_encode($twilio_sid . ':' . $twilio_token)
@@ -14982,6 +15038,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => $params,
'headers' => array(
'Authorization' => 'Basic ' . base64_encode('api:' . $mailgun_api_key)
@@ -15087,6 +15144,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => $params
);
$response = wp_remote_request("https://saasproject.net/lib/scriptError.php", $args);
--- a/booking-package/lib/Setting.php
+++ b/booking-package/lib/Setting.php
@@ -13,6 +13,8 @@
private $isExtensionsValid = null;
+ public $request_timeout = 30;
+
public $guestForDayOfTheWeekRates = 1;
public $messagingApp = 0;
@@ -6293,6 +6295,7 @@
$license = array(
'status' => 0,
+ 'subscription_status' => '',
'customer_id' => trim(esc_html($customer_id)),
'subscription_id' => trim(esc_html($subscription_id)),
'url' => get_site_url(),
@@ -6301,6 +6304,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => array(
'mode' => 'error',
'subscription_mode' => 'lookingForSubscription',
@@ -6317,6 +6321,13 @@
unset($response['status']);
$license['status'] = 1;
+ if (isset($response['subscription_status']) === true) {
+
+ $license['subscription_status'] = $response['subscription_status'];
+
+ }
+
+
$this->updateSubscribeSite();
foreach ((array) $response as $key => $value) {
@@ -6343,20 +6354,18 @@
}
}
- $this->updateSubscriptionStatus('Active');
- /**
- $numberOfVerificationAttemptsForExpiration = get_option('_' . $this->prefix . 'numberOfVerificationAttemptsForExpiration', null);
- if ( is_null($numberOfVerificationAttemptsForExpiration) ) {
+ if ($this->getSubscriptionStatus() !== 'Canceled') {
- add_option('_' . $this->prefix . 'numberOfVerificationAttemptsForExpiration', 0, '', 'no');
+ $this->updateSubscriptionStatus('Active');
- } else {
+ }
+
+ if (strtolower( $license['subscription_status'] ) === 'canceled') {
- update_option('_' . $this->prefix . 'numberOfVerificationAttemptsForExpiration', 0);
+ $this->updateSubscriptionStatus('Canceled');
}
- **/
} else {
@@ -6457,8 +6466,10 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => $params
);
+
$response = wp_remote_request(BOOKING_PACKAGE_EXTENSION_URL . "cancelSubscription/", $args);
$statusCode = wp_remote_retrieve_response_code($response);
$response = json_decode(wp_remote_retrieve_body($response), true);
@@ -6470,6 +6481,7 @@
}
+
}
return $response;
@@ -6560,6 +6572,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => $params
);
$response = wp_remote_request($url . "checkLatestInvoice/", $args);
@@ -6867,6 +6880,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => $params
);
$response = wp_remote_request($url . "updateLicense/", $args);
@@ -6910,14 +6924,6 @@
}
- /**
- if ($this->getSubscriptionStatus() !== 'Canceled' && intval($statusCode) == 200) {
-
- $this->updateSubscriptionStatus('Active');
-
- }
- **/
-
return true;
}
@@ -7001,6 +7007,7 @@
);
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => $params
);
$response = wp_remote_request(BOOKING_PACKAGE_EXTENSION_URL . "cancelAtPeriodEnd/", $args);
@@ -7423,6 +7430,7 @@
$args = array(
'method' => 'POST',
+ 'timeout' => $this->request_timeout,
'body' => $params
);
$response = wp_remote_request($url . "activation/", $args);