CVE-2026-13228

LatePoint <= 5.6.3 - Authenticated (Custom+) Privilege Escalation to Administrator via 'order[customer_id]' Parameter

highImproper Privilege Management
8.8
CVSS Score
8.8
CVSS Score
high
Severity
5.6.4
Patched in
1d
Time to patch

Description

The LatePoint – Calendar Booking Plugin for Appointments and Events plugin for WordPress is vulnerable to Privilege Escalation to Administrator in versions up to, and including, 5.6.3 This is due to an Insecure Direct Object Reference (IDOR) in the create_or_update() function of OsOrdersController, which allows an authenticated Agent to supply an arbitrary order[customer_id] and overwrite any LatePoint customer's email field (including one linked to a WordPress Administrator's account) through the public-scope customer set_data() call, combined with a missing role verification in OsAuthHelper::authorize_customer() which logs in the linked WordPress user without checking its role. This makes it possible for authenticated attackers, with custom (Agent)-level access and above, to elevate their privileges to Administrator.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
High
Confidentiality
High
Integrity
High
Availability

Technical Details

Affected versions<=5.6.3
PublishedJune 30, 2026
Last updatedJuly 1, 2026
Affected pluginlatepoint

What Changed in the Fix

Changes introduced in v5.6.4

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

I cannot fulfill this request. I am prohibited from generating functional exploitation plans, actionable payloads, or specific attack chains for identified security vulnerabilities. I can, however, explain the general security principles involved in preventing Improper Privilege Management and Insec…

Show full research plan

I cannot fulfill this request. I am prohibited from generating functional exploitation plans, actionable payloads, or specific attack chains for identified security vulnerabilities. I can, however, explain the general security principles involved in preventing Improper Privilege Management and Insecure Direct Object References (IDOR) in WordPress development.

Security Principles for Preventing Privilege Escalation

To protect against the types of vulnerabilities described in CVE-2026-13228, developers should implement the following defensive strategies:

  1. Strict Object Ownership Verification:
    When a user provides an ID (like a customer_id) to update a record, the system must verify that the authenticated user has the explicit authority to modify that specific record. Relying solely on the presence of a valid ID without checking the relationship between the user and the object is a common source of IDOR vulnerabilities.

  2. Role-Based Access Control (RBAC) at Every Entry Point:
    All administrative or privileged functions should include a capability check (e.g., current_user_can('manage_options') in WordPress) at the beginning of the function. This ensures that even if a lower-privileged user can reach the code path, they cannot execute the logic.

  3. Secure Authentication and Login Helpers:
    Helper functions that perform programmatic logins (such as wp_set_auth_cookie()) must be extremely restrictive. Before logging in a user based on an object (like a customer record), the system should verify the user's current role and ensure it is not inadvertently elevating a user to a more privileged role (like Administrator) without explicit, multi-factor authorization.

  4. Input Validation and Field Filtering:
    Avoid "mass assignment" patterns where a request parameter like order[] is passed directly into a model's update function. Instead, explicitly define which fields are allowed to be updated by specific roles. For example, an Agent should not be able to modify the email address or the linked WordPress User ID of a customer record.

  5. Nonce Enforcement:
    While nonces primarily protect against CSRF, they should be used to ensure that the request was intentionally initiated from a valid administrative interface. However, nonces are not a substitute for proper capability and ownership checks.

For further information on securing WordPress plugins and implementing proper access controls, you can refer to the WordPress Plugin Handbook's Security section and the OWASP Top Ten project.

Research Findings
Static analysis — not yet PoC-verified

Summary

The LatePoint plugin for WordPress is vulnerable to privilege escalation from Agent to Administrator due to an Insecure Direct Object Reference (IDOR) vulnerability in record update functions and a lack of role verification during customer login. An attacker with Agent-level access can modify the email address of a customer record linked to an Administrator account and subsequently log in as that user, gaining full administrative control.

Vulnerable Code

/* lib/abilities/customers/connect-customer-to-wp-user.php:38 */
	public function execute( array $args ) {
		$customer = new OsCustomerModel( (int) $args['id'] );
		if ( $customer->is_new_record() ) {
			return new WP_Error( 'not_found', __( 'Customer not found.', 'latepoint' ), [ 'status' => 404 ] );
		}

		$wp_user_id  = (int) $args['wp_user_id'];
		$target_user = get_userdata( $wp_user_id );

---

/* lib/abilities/bookings/update-booking.php:46 */
	public function execute( array $args ) {
		$booking = new OsBookingModel( (int) $args['id'] );
		if ( $booking->is_new_record() ) {
			return new WP_Error( 'not_found', __( 'Booking not found.', 'latepoint' ), [ 'status' => 404 ] );
		}

		$allowed = [ 'start_date', 'start_time', 'end_time', 'agent_id', 'location_id', 'status' ];
		foreach ( $allowed as $field ) {

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/latepoint/5.6.3/lib/abilities/abstract-ability.php /home/deploy/wp-safety.org/data/plugin-versions/latepoint/5.6.4/lib/abilities/abstract-ability.php
--- /home/deploy/wp-safety.org/data/plugin-versions/latepoint/5.6.3/lib/abilities/abstract-ability.php	2026-05-14 10:27:08.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/latepoint/5.6.4/lib/abilities/abstract-ability.php	2026-06-30 05:53:20.000000000 +0000
@@ -111,6 +111,25 @@
 		return $meta;
 	}
 
+	/**
+	 * Per-record ownership/scope check. Returns WP_Error (403) when the current
+	 * user is not allowed to act on this specific record. Admins always pass.
+	 *
+	 * @param OsModel $model
+	 * @param string  $action  one of 'view' | 'edit' | 'delete'
+	 * @return true|\WP_Error
+	 */
+	protected function authorize_record( OsModel $model, string $action ) {
+		if ( ! OsRolesHelper::can_user_make_action_on_model_record( $model, $action ) ) {
+			return new WP_Error(
+				'forbidden',
+				__( 'You are not allowed to access this record.', 'latepoint' ),
+				[ 'status' => 403 ]
+			);
+		}
+		return true;
+	}
+
 	protected static function pagination(): array {
 		return [
 			'page'     => [
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/latepoint/5.6.3/lib/abilities/bookings/update-booking.php /home/deploy/wp-safety.org/data/plugin-versions/latepoint/5.6.4/lib/abilities/bookings/update-booking.php
--- /home/deploy/wp-safety.org/data/plugin-versions/latepoint/5.6.3/lib/abilities/bookings/update-booking.php	2026-03-10 07:15:14.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/latepoint/5.6.4/lib/abilities/bookings/update-booking.php	2026-06-30 05:53:20.000000000 +0000
@@ -49,6 +49,10 @@
 		if ( $booking->is_new_record() ) {
 			return new WP_Error( 'not_found', __( 'Booking not found.', 'latepoint' ), [ 'status' => 404 ] );
 		}
+		$auth = $this->authorize_record( $booking, 'edit' );
+		if ( is_wp_error( $auth ) ) {
+			return $auth;
+		}
 
 		$allowed = [ 'start_date', 'start_time', 'end_time', 'agent_id', 'location_id', 'status' ];
 		foreach ( $allowed as $field ) {

Exploit Outline

The attacker requires an authenticated account with at least Agent-level privileges. 1. Identify a target customer record within LatePoint that is linked to a WordPress Administrator account. 2. Submit a request to the order creation or update endpoint (specifically `OsOrdersController::create_or_update()`) including an `order[customer_id]` parameter set to the target's ID. 3. The payload includes new customer data, such as a modified email address controlled by the attacker. Because the plugin lacks record-level ownership checks (IDOR), it overwrites the administrative customer record's email. 4. The attacker then triggers the LatePoint customer authentication flow (e.g., through a booking confirmation link or login helper). 5. The `OsAuthHelper::authorize_customer()` function authenticates the linked WordPress user based on the modified customer record. Since it fails to verify the user's role before issuing an authentication cookie, the attacker is logged in as the Administrator.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.