3D viewer – Embed 3D Models <= 1.8.5 - Missing Authorization
Description
The 3D viewer – Embed 3D Models plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.8.5. This makes it possible for authenticated attackers, with contributor-level access and above, to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:NTechnical Details
What Changed in the Fix
Changes introduced in v1.8.6
Source Code
WordPress.org SVN# Detailed Exploitation Research Plan: CVE-2026-40729 ## 1. Vulnerability Summary The **3D Viewer – Display Interactive 3D Models** plugin (versions <= 1.8.5) contains a missing authorization vulnerability within its AJAX handlers. Specifically, the function `bp3d_pipe_checker` (and potentially oth…
Show full research plan
Detailed Exploitation Research Plan: CVE-2026-40729
1. Vulnerability Summary
The 3D Viewer – Display Interactive 3D Models plugin (versions <= 1.8.5) contains a missing authorization vulnerability within its AJAX handlers. Specifically, the function bp3d_pipe_checker (and potentially others like dismiss_product_edit_notice) is registered for authenticated users via the wp_ajax_ hook but fails to perform any capability check (e.g., current_user_can()). This allows any authenticated user, including those with Contributor roles, to execute these functions. While the immediate impact of bp3d_pipe_checker is low, the pattern of missing authorization across the plugin's AJAX interface allows for unauthorized state modification or information disclosure of plugin internals.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
bp3d_pipe_checker - Method: GET or POST (the code uses
$_GETfor the nonce but does not specify for the action, standardadmin-ajax.phpbehavior applies). - Parameter:
_wpnonce(the nonce value). - Required Role: Contributor or higher.
- Preconditions: The plugin must be active. The attacker must be logged in as a Contributor.
3. Code Flow
- Registration: In
3d-viewer-block/plugin.php, the classTDVB3DViewerBlockregisters the AJAX action:add_action('wp_ajax_bp3d_pipe_checker', [$this, 'bp3d_pipe_checker']); - Exposure: In
3d-viewer-block/inc/block.php, theonInitmethod localizes a script and creates a nonce with the action string'wp_ajax':
This localization is sent to the browser whenever the Block Editor is loaded by a user with editing capabilities (Contributor+).wp_localize_script( 'tdvb-td-viewer-editor-script', 'bp3dBlock', [ 'nonce' => wp_create_nonce( 'wp_ajax' ), 'ajaxURL' => admin_url( 'admin-ajax.php' ) ] ); - Trigger: An attacker sends a request to
admin-ajax.php?action=bp3d_pipe_checker&_wpnonce=[NONCE]. - Execution: The
bp3d_pipe_checkerfunction in3d-viewer-block/plugin.phpis invoked:function bp3d_pipe_checker() { $nonce = sanitize_text_field(wp_unslash($_GET['_wpnonce'] ?? '')); if (!wp_verify_nonce($nonce, 'wp_ajax')) { // Nonce check only wp_send_json_error(); } wp_send_json_success(['isPipe' => false]); // No capability check here! } - Vulnerability: Since there is no
current_user_can()check beforewp_send_json_success, the action completes for any authenticated user.
4. Nonce Acquisition Strategy
The nonce is generated with the action 'wp_ajax' and passed to the JavaScript object bp3dBlock under the key nonce.
- Step 1: Log in as a Contributor.
- Step 2: Navigate to the "Add New Post" page (
/wp-admin/post-new.php). This loads the Gutenberg editor. - Step 3: Use the
browser_evaltool to extract the nonce from the global scope.- Command:
browser_eval("window.bp3dBlock?.nonce")
- Command:
- Alternative: If the script is not enqueued by default, create a post and insert a "3D Viewer" block, then refresh the editor.
5. Exploitation Strategy
Perform an unauthorized AJAX call to confirm the missing capability check.
- Login: Authenticate as
contributor. - Nonce Retrieval: Use the strategy in Section 4.
- HTTP Request (via
http_requesttool):- URL:
http://[TARGET]/wp-admin/admin-ajax.php?action=bp3d_pipe_checker&_wpnonce=[EXTRACTED_NONCE] - Method: GET
- Headers: Use cookies from the contributor session.
- URL:
- Second Exploitation (Notice Dismissal):
- According to
build/admin.js, there is an actiondismiss_product_edit_notice. - Request:
- URL:
http://[TARGET]/wp-admin/admin-ajax.php - Method: POST
- Body:
action=dismiss_product_edit_notice&security=[EXTRACTED_NONCE](Note: This action might require a different nonce found in.bp3dv_woocommerce_admin_noticedataset if the genericwp_ajaxnonce fails).
- URL:
- According to
6. Test Data Setup
- User: Create a user with the role
contributor. - Plugin Configuration: Ensure the plugin is activated.
- Content: No specific 3D models are required to trigger the authorization bypass on the AJAX endpoints.
7. Expected Results
- Success Condition: The server returns a HTTP 200 with a JSON body:
{"success":true,"data":{"isPipe":false}}. - Failure Condition (Fixed): If the plugin were patched, it would return a HTTP 403 or
{"success":false}because the user lacks themanage_options(or similar) capability.
8. Verification Steps
Summary
The 3D Viewer – Embed 3D Models plugin for WordPress is vulnerable to unauthorized access because it fails to perform capability checks on its AJAX handlers. This allows authenticated users with Contributor-level access to execute actions like bp3d_pipe_checker by obtaining a valid nonce from the WordPress post editor.
Vulnerable Code
// 3d-viewer-block/plugin.php add_action('wp_ajax_bp3d_pipe_checker', [$this, 'bp3d_pipe_checker']); // line 17 // ... function bp3d_pipe_checker() // line 43 { $nonce = sanitize_text_field(wp_unslash($_GET['_wpnonce'] ?? '')); if (!wp_verify_nonce($nonce, 'wp_ajax')) { wp_send_json_error(); } wp_send_json_success([ 'isPipe' => false ]); } --- // 3d-viewer-block/inc/block.php function onInit(){ // line 19 // ... wp_localize_script( 'tdvb-td-viewer-editor-script', 'bp3dBlock', [ 'nonce' => wp_create_nonce( 'wp_ajax' ), 'ajaxURL' => admin_url( 'admin-ajax.php' ) ] ); // line 26 }
Security Fix
@@ -30,10 +30,10 @@ wp_set_script_translations( 'tdvb-td-viewer-editor-script', 'model-viewer', plugin_dir_path( __FILE__ ) . 'languages' ); // Translate - wp_localize_script( 'tdvb-td-viewer-editor-script', 'bp3dBlock', [ - 'nonce' => wp_create_nonce( 'wp_ajax' ), - 'ajaxURL' => admin_url( 'admin-ajax.php' ) - ] ); + // wp_localize_script( 'tdvb-td-viewer-editor-script', 'bp3dBlock', [ + // 'nonce' => wp_create_nonce( 'wp_ajax' ), + // 'ajaxURL' => admin_url( 'admin-ajax.php' ) + // ] ); } function render( $attributes ){ @@ -50,7 +51,7 @@ } wp_send_json_success([ - 'isPipe' => false + 'isPipe' => true ]); }
Exploit Outline
1. Authenticate as a user with Contributor-level privileges (or higher). 2. Navigate to the post editor (e.g., /wp-admin/post-new.php) to load the Gutenberg block editor assets. 3. Extract the security nonce from the global JavaScript object 'bp3dBlock.nonce', which is localized into the page for any user with editing permissions. 4. Construct an AJAX request to /wp-admin/admin-ajax.php using the extracted nonce and the action parameter 'bp3d_pipe_checker'. 5. Submit the request (GET or POST) and observe that the server executes the handler without any capability verification (such as current_user_can), returning a successful JSON response.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.