App Builder <= 5.5.10 - Insecure Direct Object Reference to Authenticated (Subscriber+) Arbitrary User Avatar Modification via 'user_id' Parameter
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:NTechnical Details
# 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)
- 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 ]); - Handler Execution: The
upload_avatar($request)function is called. - Parameter Extraction: The function retrieves the target user ID from the request:
$user_id = $request->get_param('user_id'); - Sink (Missing Check): Without verifying if the current user ID matches
$user_idor 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.
- Login: Authenticate as a Subscriber user.
- Access Admin Context: Navigate to
wp-admin/or a page where the plugin is active. - Extract Nonce: Use the
browser_evaltool to extract the nonce from the globalwpApiSettingsobject provided by WordPress core.- Script:
browser_eval("window.wpApiSettings?.nonce")
- Script:
- Alternative (if standard REST nonce is blocked): Check for localized scripts specific to App Builder by searching for
wp_localize_scriptin the plugin source (e.g.,app_builder_settings).
5. Exploitation Strategy
- Login: Perform a login request as a Subscriber.
- Obtain Nonce: Extract the
X-WP-Noncefrom thewpApiSettingsvia a browser session. - Identify Target: Target
user_id = 1(the default administrator). - 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:1avatar: (A small valid image file, e.g.,exploit.png)
- URL:
- Execute: Send the request using the
http_requesttool.
6. Test Data Setup
- Users:
- Ensure an administrator exists (usually ID 1).
- Create a Subscriber user:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password123.
- Plugin: Ensure "App Builder" is active.
- File: Prepare a dummy image file
avatar.jpgin the environment.
7. Expected Results
- The server should return a
200 OKor201 Createdresponse. - 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
- Check User Meta via CLI:
- Run:
wp user meta list 1 - Look for keys related to
avatarorapp-builder(e.g.,app_builder_avatar).
- Run:
- 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-datafails, 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_idas 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 1before and after the exploit to identify which key changed.
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
@@ -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.