CVE-2026-7638

App Builder <= 5.5.10 - Insecure Direct Object Reference to Authenticated (Subscriber+) Arbitrary User Avatar Modification via 'user_id' Parameter

mediumAuthorization Bypass Through User-Controlled Key
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The App Builder – Create Native Android & iOS Apps On The Flight plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to and including 5.6.0. This is due to missing authorization validation in the `upload_avatar()` function, which accepts an attacker-controlled `user_id` parameter from the POST request body and uses it to update user meta without verifying that the authenticated requester owns or has permission to modify the target account. This makes it possible for authenticated attackers, with Subscriber-level access and above, to overwrite the profile avatar of any arbitrary user on the site, including administrators, by supplying a target `user_id` in the request body to the `/wp-json/app-builder/v1/upload-avatar` endpoint.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=5.6.0
PublishedMay 1, 2026
Last updatedMay 2, 2026
Affected pluginapp-builder
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-7638 ## 1. Vulnerability Summary The **App Builder** plugin (<= 5.6.0) for WordPress contains an Insecure Direct Object Reference (IDOR) vulnerability in its REST API implementation. The function `upload_avatar()` handles requests to the `/wp-json/app-builder…

Show full research plan

Exploitation Research Plan - CVE-2026-7638

1. Vulnerability Summary

The App Builder plugin (<= 5.6.0) for WordPress contains an Insecure Direct Object Reference (IDOR) vulnerability in its REST API implementation. The function upload_avatar() handles requests to the /wp-json/app-builder/v1/upload-avatar endpoint but fails to perform an authorization check to ensure the authenticated user has permission to modify the target user_id. Consequently, any authenticated user (Subscriber level and above) can change the profile avatar of any other user, including administrators, by specifying the target's ID in the request.

2. Attack Vector Analysis

  • Endpoint: /wp-json/app-builder/v1/upload-avatar
  • Method: POST
  • Authentication: Required (Subscriber or higher).
  • Vulnerable Parameter: user_id (passed in the POST body).
  • Payload: An image file (multipart/form-data) or an attachment ID, along with the target user_id.
  • Preconditions: The attacker must have valid credentials for a Subscriber-level account.

3. Code Flow (Inferred from Description)

  1. Route Registration: During rest_api_init, the plugin registers the route:
    register_rest_route('app-builder/v1', '/upload-avatar', [
        'methods' => 'POST',
        'callback' => 'upload_avatar', // Likely a method in a controller class
        'permission_callback' => 'is_user_logged_in' // VULNERABLE: Only checks if logged in, not permissions
    ]);
    
  2. Handler Execution: The upload_avatar($request) function is called.
  3. Parameter Extraction: The function retrieves the target user ID from the request:
    $user_id = $request->get_param('user_id'); 
    
  4. Sink (Missing Check): Without verifying if the current user ID matches $user_id or if the current user is an administrator, the function processes the upload:
    // Missing: if (get_current_user_id() != $user_id && !current_user_can('edit_users')) { return error; }
    // Logic to handle file upload and update user meta
    update_user_meta($user_id, 'app_builder_user_avatar', $avatar_url); // Example meta key
    

4. Nonce Acquisition Strategy

The WordPress REST API requires a nonce for authenticated requests to prevent CSRF. This nonce is typically tied to the wp_rest action.

  1. Login: Authenticate as a Subscriber user.
  2. Access Admin Context: Navigate to wp-admin/ or a page where the plugin is active.
  3. Extract Nonce: Use the browser_eval tool to extract the nonce from the global wpApiSettings object provided by WordPress core.
    • Script: browser_eval("window.wpApiSettings?.nonce")
  4. Alternative (if standard REST nonce is blocked): Check for localized scripts specific to App Builder by searching for wp_localize_script in the plugin source (e.g., app_builder_settings).

5. Exploitation Strategy

  1. Login: Perform a login request as a Subscriber.
  2. Obtain Nonce: Extract the X-WP-Nonce from the wpApiSettings via a browser session.
  3. Identify Target: Target user_id = 1 (the default administrator).
  4. Construct Request:
    • URL: http://localhost:8080/wp-json/app-builder/v1/upload-avatar
    • Headers:
      • X-WP-Nonce: [EXTRACTED_NONCE]
      • Content-Type: multipart/form-data
    • Body:
      • user_id: 1
      • avatar: (A small valid image file, e.g., exploit.png)
  5. Execute: Send the request using the http_request tool.

6. Test Data Setup

  1. Users:
    • Ensure an administrator exists (usually ID 1).
    • Create a Subscriber user: wp user create attacker attacker@example.com --role=subscriber --user_pass=password123.
  2. Plugin: Ensure "App Builder" is active.
  3. File: Prepare a dummy image file avatar.jpg in the environment.

7. Expected Results

  • The server should return a 200 OK or 201 Created response.
  • The response body may contain the URL of the new avatar.
  • The administrator's user meta (specifically the one used by App Builder for avatars) will be updated to point to the attacker's uploaded file.

8. Verification Steps

  1. Check User Meta via CLI:
    • Run: wp user meta list 1
    • Look for keys related to avatar or app-builder (e.g., app_builder_avatar).
  2. Confirm Value Change:
    • Verify that the meta value for the admin (ID 1) now matches the path of the file uploaded by the subscriber.
    • Command: wp user meta get 1 [META_KEY]

9. Alternative Approaches

  • JSON Payload: If multipart/form-data fails, attempt a raw JSON POST if the plugin accepts an attachment ID or URL:
    {
      "user_id": 1,
      "avatar": "http://attacker.com/malicious-avatar.png"
    }
    
  • Direct Parameter Injection: If the route is processed differently, try passing user_id as a query parameter: /wp-json/app-builder/v1/upload-avatar?user_id=1.
  • Meta Key Guessing: If the specific meta key is unknown, use wp user meta list 1 before and after the exploit to identify which key changed.
Research Findings
Static analysis — not yet PoC-verified

Summary

The App Builder plugin for WordPress is vulnerable to an Insecure Direct Object Reference (IDOR) in its REST API avatar upload functionality. Authenticated users with Subscriber-level access can overwrite the profile avatar of any user, including administrators, by specifying a target user_id in a request to the /wp-json/app-builder/v1/upload-avatar endpoint without proper authorization checks.

Vulnerable Code

// Inferred from research plan as source files were not provided
// Path: app-builder/includes/class-app-builder-rest-api.php (or similar)

register_rest_route('app-builder/v1', '/upload-avatar', [
    'methods' => 'POST',
    'callback' => 'upload_avatar',
    'permission_callback' => 'is_user_logged_in' // VULNERABLE: Only checks if user is logged in
]);

---

public function upload_avatar($request) {
    $user_id = $request->get_param('user_id'); // ID is taken directly from user input
    
    // Missing validation: if (get_current_user_id() != $user_id && !current_user_can('edit_users')) { ... }
    
    $avatar_url = $this->handle_upload($request);
    update_user_meta($user_id, 'app_builder_user_avatar', $avatar_url);
    return new WP_REST_Response(['success' => true, 'url' => $avatar_url], 200);
}

Security Fix

--- a/app-builder/includes/class-app-builder-rest-api.php
+++ b/app-builder/includes/class-app-builder-rest-api.php
@@ -10,7 +10,14 @@
         register_rest_route('app-builder/v1', '/upload-avatar', [
             'methods' => 'POST',
             'callback' => [$this, 'upload_avatar'],
-            'permission_callback' => 'is_user_logged_in'
+            'permission_callback' => function($request) {
+                if (!is_user_logged_in()) return false;
+                $user_id = $request->get_param('user_id');
+                if (get_current_user_id() == $user_id || current_user_can('edit_users')) {
+                    return true;
+                }
+                return new WP_Error('rest_forbidden', __('You do not have permission to edit this user.'), ['status' => 403]);
+            }
         ]);
     }

Exploit Outline

1. Login to the WordPress site as a user with Subscriber-level permissions. 2. Obtain a valid WordPress REST API nonce (X-WP-Nonce) from the front-end (e.g., via the window.wpApiSettings.nonce object). 3. Prepare a POST request to /wp-json/app-builder/v1/upload-avatar using multipart/form-data content type. 4. In the request body, set the 'user_id' parameter to the ID of the target user (e.g., '1' for the primary administrator). 5. Attach a valid image file to the request (e.g., 'avatar' field). 6. Send the request; the plugin will process the upload and update the user_meta for the specified 'user_id' to point to the attacker's uploaded image, effectively changing the target's profile picture.

Check if your site is affected.

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