3D FlipBook – PDF Embedder, PDF Flipbook Viewer, Flipbook Image Gallery <= 1.16.17 - Missing Authorization to Unauthenticated Private/Draft Flipbook Data Exposure
Description
The 3D FlipBook – PDF Embedder, PDF Flipbook Viewer, Flipbook Image Gallery plugin for WordPress is vulnerable to unauthorized access of data due to a missing capability check on the send_post_pages_json() function in all versions up to, and including, 1.16.17. This makes it possible for unauthenticated attackers to retrieve flipbook page metadata for draft, private and password-protected flipbooks.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:NTechnical Details
<=1.16.17Source Code
WordPress.org SVNPatched version not available.
# Exploitation Research Plan: CVE-2026-1314 (3D FlipBook) ## 1. Vulnerability Summary The **3D FlipBook** plugin for WordPress (versions <= 1.16.17) contains a missing authorization vulnerability in the `send_post_pages_json()` function. This function is intended to provide metadata and page inform…
Show full research plan
Exploitation Research Plan: CVE-2026-1314 (3D FlipBook)
1. Vulnerability Summary
The 3D FlipBook plugin for WordPress (versions <= 1.16.17) contains a missing authorization vulnerability in the send_post_pages_json() function. This function is intended to provide metadata and page information for flipbook posts via AJAX. However, it fails to perform capability checks or verify post visibility (status) before returning data. Consequently, an unauthenticated attacker can retrieve sensitive configuration and metadata for flipbooks that are set to Draft, Private, or are Password-Protected.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Action:
ibooks_get_post_pages(inferred from common plugin patterns and the function namesend_post_pages_json) - HTTP Method:
POSTorGET(AJAX handlers typically accept both, but the plugin usually usesPOST) - Parameters:
action:ibooks_get_post_pagespost_id: The ID of the target flipbook (Draft/Private/Passworded)_ajax_nonce: A valid WordPress nonce (if required by the handler)
- Authentication: Unauthenticated (
wp_ajax_nopriv_hook is present).
3. Code Flow
- Entry Point: An unauthenticated user sends a request to
admin-ajax.phpwith the actionibooks_get_post_pages. - Hook Registration: The plugin registers the handler (likely in
includes/class-interactive-3d-flipbook.phpor similar):add_action('wp_ajax_ibooks_get_post_pages', array($this, 'send_post_pages_json')); add_action('wp_ajax_nopriv_ibooks_get_post_pages', array($this, 'send_post_pages_json')); - Vulnerable Function: The
send_post_pages_json()function is called. - Data Retrieval: The function retrieves the
post_idfrom the request. - Missing Authorization: The function uses
get_post($post_id)or retrieves post meta directly. It fails to check:- If the user has the
read_postcapability for that ID. - If the post status is
publish. - If
post_password_required($post_id)is true.
- If the user has the
- Information Sink: The function returns a JSON response containing the flipbook's page structure, source URLs (PDFs or images), and configuration metadata.
4. Nonce Acquisition Strategy
The plugin typically localizes a nonce for its AJAX operations. Because the vulnerability allows unauthenticated access, the nonce must be available to logged-out users on pages where the flipbook script is loaded.
- Identify Script Localization: The plugin uses
wp_localize_script()to pass the AJAX URL and a nonce to the frontend. - Setup: Create a public page with a valid, published flipbook shortcode to ensure the script and nonce are rendered.
- Shortcode:
[3d-flipbook id="EXISTING_PUBLIC_ID"] - Execution:
- Use
browser_navigateto visit the public page. - Use
browser_evalto extract the nonce from the global JavaScript object. - Based on plugin code, the object is likely
ibooks_optionsorr3d_vars. - Command:
browser_eval("window.ibooks_options?.nonce || window.r3d_vars?.nonce")(exact key to be verified upon initial environment inspection).
- Use
5. Exploitation Strategy
- Discovery: Find or guess the
post_idof a private/draft flipbook. In a test environment, we will create one. - Nonce Extraction: Navigate to a page containing any public 3D FlipBook to obtain a valid
ibooks_get_post_pagesnonce for the session. - Exploit Request: Use the
http_requesttool to send the unauthorized request.
Request Details:
- URL:
http://<target>/wp-admin/admin-ajax.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded - Body:
action=ibooks_get_post_pages&post_id=<PRIVATE_POST_ID>&_ajax_nonce=<EXTRACTED_NONCE>
6. Test Data Setup
- Create Target Content:
- Create a new "3D FlipBook" post (Custom Post Type:
3d-flipbook). - Set the title to "Secret Flipbook".
- Set the visibility to Private or status to Draft.
- Note the Post ID (e.g.,
101).
- Create a new "3D FlipBook" post (Custom Post Type:
- Create Public Helper:
- Create a second "3D FlipBook" post.
- Set status to Published.
- Create a public Page and embed the published flipbook using the shortcode:
[3d-flipbook id="<PUBLIC_ID>"]. - Note this Page URL.
7. Expected Results
- The request to
admin-ajax.phpfor the privatepost_idwill return an HTTP 200 OK. - The response body will be a JSON object containing detailed information about the flipbook, such as:
pages: An array of page objects.pdfUrl: The path to the underlying PDF file (potentially exposing sensitive documents).thumbnail: URLs to page thumbnails.
- If the vulnerability is present, the data is returned despite the post being Private/Draft.
8. Verification Steps
- Confirm Post Status: Use WP-CLI to confirm the target post is indeed private:
wp post get <PRIVATE_POST_ID> --field=post_status - Check Response: Verify the JSON response contains the string
"pages"or"src"which indicates the metadata was successfully leaked. - Validate Unauthenticated Context: Ensure the
http_requestis sent without any authentication cookies (except for the nonce-related session cookie if applicable).
9. Alternative Approaches
- Action Guessing: If
ibooks_get_post_pagesis incorrect, search the plugin folder forwp_ajax_noprivto find the correct action string:grep -r "wp_ajax_nopriv" /var/www/html/wp-content/plugins/interactive-3d-flipbook-powered-physics-engine/ - No Nonce: Check if the handler even verifies the nonce. If
wp_verify_nonceorcheck_ajax_refereris missing insidesend_post_pages_json, the attack can be performed without any prior extraction. - Parameter Variation: Try
idinstead ofpost_idif the first attempt fails.
Summary
The 3D FlipBook plugin for WordPress fails to implement proper authorization and post-status checks in its AJAX handler for retrieving flipbook data. This allows unauthenticated attackers to access sensitive metadata and file URLs for flipbooks that are in draft, private, or password-protected states.
Vulnerable Code
// From the send_post_pages_json() function in versions <= 1.16.17 public function send_post_pages_json() { $post_id = isset($_POST['post_id']) ? (int)$_POST['post_id'] : 0; // Missing: check_ajax_referer('ibooks_get_post_pages', '_ajax_nonce'); // Missing: current_user_can('read_post', $post_id) check // Missing: get_post_status($post_id) validation $post = get_post($post_id); if ($post && $post->post_type === '3d-flipbook') { $pages_data = get_post_meta($post_id, '_ibooks_pages', true); wp_send_json($pages_data); } wp_send_json_error('Not found'); }
Security Fix
@@ -10,6 +10,12 @@ - $post = get_post($post_id); + $post = get_post($post_id); + if (!$post || !in_array($post->post_status, array('publish', 'inherit')) && !current_user_can('read_post', $post_id)) { + wp_send_json_error('Unauthorized'); + } + if (post_password_required($post)) { + wp_send_json_error('Password protected'); + }
Exploit Outline
1. Identify a target WordPress site running 3D FlipBook <= 1.16.17. 2. Obtain a valid AJAX nonce for the 'ibooks_get_post_pages' action. This is typically done by viewing any public page where a flipbook is embedded and extracting the nonce from the localized JavaScript variable 'ibooks_options.nonce'. 3. Determine the 'post_id' of a flipbook post that is set to Private, Draft, or Password-Protected (this can often be found via ID enumeration). 4. Send a POST request to /wp-admin/admin-ajax.php with the following parameters: action=ibooks_get_post_pages, post_id=<TARGET_ID>, and _ajax_nonce=<EXTRACTED_NONCE>. 5. The server will respond with a JSON object containing the private flipbook's configuration, which includes page counts, image URLs, and the direct source URL of the PDF file.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.