[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fZczywrvtRNRmqbOv7YriVrTzNf-SSqo9yETymWRP-kU":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":22,"research_verified":23,"research_rounds_completed":24,"research_plan":25,"research_summary":26,"research_vulnerable_code":27,"research_fix_diff":28,"research_exploit_outline":29,"research_model_used":30,"research_started_at":31,"research_completed_at":32,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":23,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":23,"source_links":33},"CVE-2025-12129","cubewp-all-in-one-dynamic-content-framework-unauthenticated-information-exposure","CubeWP – All-in-One Dynamic Content Framework \u003C= 1.1.27 - Unauthenticated Information Exposure","The CubeWP – All-in-One Dynamic Content Framework plugin for WordPress is vulnerable to Information Exposure in all versions up to, and including, 1.1.27 via the \u002Fcubewp-posts\u002Fv1\u002Fquery-new and \u002Fcubewp-posts\u002Fv1\u002Fquery REST API endpoints due to insufficient restrictions on which posts can be included. This makes it possible for unauthenticated attackers to extract data from password protected, private, or draft posts that they should not have access to.","cubewp-framework",null,"\u003C=1.1.27","1.1.28","medium",5.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:L\u002FI:N\u002FA:N","Exposure of Sensitive Information to an Unauthorized Actor","2026-01-16 19:16:27","2026-01-17 07:27:37",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F2006dc4c-ec1a-45ab-94a3-1f86d80e70ca?source=api-prod",1,[],"researched",false,3,"# Research Plan: CVE-2025-12129 - CubeWP Unauthenticated Information Exposure\n\n## 1. Vulnerability Summary\nThe **CubeWP – All-in-One Dynamic Content Framework** plugin (versions \u003C= 1.1.27) contains an information exposure vulnerability via its REST API. The endpoints `\u002Fcubewp-posts\u002Fv1\u002Fquery-new` and `\u002Fcubewp-posts\u002Fv1\u002Fquery` do not sufficiently restrict the `post_status` parameter or validate the caller's permissions to view non-public content. This allows unauthenticated users to query and retrieve the contents of private, draft, and password-protected posts by manipulating query arguments passed to the underlying `WP_Query` or `get_posts` calls.\n\n## 2. Attack Vector Analysis\n*   **Endpoints:** \n    *   `\u002Fwp-json\u002Fcubewp-posts\u002Fv1\u002Fquery`\n    *   `\u002Fwp-json\u002Fcubewp-posts\u002Fv1\u002Fquery-new`\n*   **HTTP Method:** Primarily `GET`, but potentially `POST` depending on implementation.\n*   **Authentication:** None (Unauthenticated).\n*   **Vulnerable Parameters:** Query arguments such as `post_status`, `post_type`, `p` (Post ID), and `name` (Slug).\n*   **Preconditions:** The plugin must be active. Sensitive content (drafts, private posts) must exist in the database.\n\n## 3. Code Flow (Inferred)\n1.  **Registration:** The plugin registers REST routes in a class (likely related to posts or frontend queries) using `register_rest_route` during the `rest_api_init` hook.\n2.  **Permission Check:** The `permission_callback` for these routes is likely set to `__return_true` or fails to verify if the user has the `edit_posts` capability when requesting non-public statuses.\n3.  **Data Processing:** The controller function associated with the route retrieves user-supplied parameters from the `WP_REST_Request` object.\n4.  **Sinking into Query:** These parameters are passed into a `WP_Query` instance. If the `post_status` parameter is not explicitly forced to `publish`, or if the user-supplied `post_status` is honored without capability checks, `WP_Query` will return the requested sensitive posts.\n5.  **Response:** The resulting post objects (including `post_content`) are returned as a JSON response.\n\n## 4. Nonce Acquisition Strategy\nREST API endpoints in WordPress often require a `wp_rest` nonce for authenticated sessions, but \"unauthenticated\" vulnerabilities typically imply the `permission_callback` allows access without one, or the nonce is publicly exposed.\n\n1.  **Check for Public Nonce:** Navigate to the homepage and check for localized scripts.\n    *   Target Variable (Inferred): `window.cubewp_params` or `window.cwp_query_vars`.\n    *   Target Key: `nonce`.\n2.  **Manual Extraction:**\n    *   Action: `browser_navigate(\"http:\u002F\u002Flocalhost:8888\")`\n    *   Action: `browser_eval(\"window.cubewp_params?.nonce || window.cubewp_core?.nonce\")`\n3.  **Bypass Check:** If the `permission_callback` is `__return_true`, the `X-WP-Nonce` header may not be required at all for the GET request.\n\n## 5. Exploitation Strategy\nThe goal is to extract the content of a post that is not publicly visible.\n\n1.  **Step 1: Discover Post IDs.** Since we are unauthenticated, we can try to brute-force post IDs using the `p` parameter.\n2.  **Step 2: Craft Payload for Private Posts.**\n    *   URL: `\u002Fwp-json\u002Fcubewp-posts\u002Fv1\u002Fquery?post_status=private`\n    *   Alternatively: `\u002Fwp-json\u002Fcubewp-posts\u002Fv1\u002Fquery?p=[ID]&post_status=any`\n3.  **Step 3: Craft Payload for Drafts.**\n    *   URL: `\u002Fwp-json\u002Fcubewp-posts\u002Fv1\u002Fquery-new?post_status=draft`\n4.  **Request Details:**\n    *   **Method:** `GET`\n    *   **Headers:** `Content-Type: application\u002Fjson`\n    *   **Tool:** `http_request`\n\n## 6. Test Data Setup\nTo confirm the vulnerability, we need non-public content:\n\n1.  **Private Post:**\n    *   `wp post create --post_type=post --post_title='Secret Private Post' --post_content='This is a sensitive private post content.' --post_status=private`\n2.  **Draft Post:**\n    *   `wp post create --post_type=post --post_title='Confidential Draft' --post_content='This is a sensitive draft content.' --post_status=draft`\n3.  **Password Protected Post:**\n    *   `wp post create --post_type=post --post_title='Locked Post' --post_content='Hidden behind password.' --post_status=publish --post_password='password123'`\n\nRecord the IDs returned by these commands.\n\n## 7. Expected Results\n*   **Request:** `GET \u002Fwp-json\u002Fcubewp-posts\u002Fv1\u002Fquery?p=[PRIVATE_ID]&post_status=private`\n*   **Response Status:** `200 OK`\n*   **Response Body:** JSON containing the object for the private post, specifically verifying the `post_content` or `post_excerpt` fields match the \"sensitive\" content created in Step 6.\n*   **Fail Case:** A `403 Forbidden` or a `200 OK` with an empty result set (indicating proper filtering).\n\n## 8. Verification Steps\n1.  **Verify via CLI:** Confirm the post exists and has the correct status.\n    *   `wp post get [ID] --field=post_status`\n2.  **Compare Output:** Compare the `post_content` returned in the HTTP response to the output of:\n    *   `wp post get [ID] --field=post_content`\n3.  **Unauthenticated Check:** Ensure the `http_request` tool is used without any session cookies or `Authorization` headers to confirm unauthenticated access.\n\n## 9. Alternative Approaches\nIf the `query` parameter names are different (e.g., the plugin uses custom mapping):\n1.  **Examine Source:** Locate the function handling the REST route. Look for code accessing `$request->get_params()` or `$_GET`.\n2.  **Try `post_type` override:** Attempt to query `attachment` or other internal types that might contain sensitive data.\n3.  **Try `query-new` endpoint:** If `\u002Fquery` is restricted, `\u002Fquery-new` might use a newer, less-tested code path.\n4.  **Fuzz status:** Try `post_status[]=private&post_status[]=draft` to see if array inputs bypass simple string checks.","The CubeWP Framework plugin for WordPress is vulnerable to unauthenticated information exposure via the \u002Fcubewp-posts\u002Fv1\u002Fquery and \u002Fcubewp-posts\u002Fv1\u002Fquery-new REST API endpoints. Due to a lack of permission checks and insufficient restriction of query parameters, unauthenticated users can access private, draft, and password-protected post content by manipulating the post_status argument.","\u002F\u002F Inferred registration in CubeWP REST API controller\nregister_rest_route('cubewp-posts\u002Fv1', '\u002Fquery', array(\n    'methods'             => 'GET',\n    'callback'            => array($this, 'handle_post_query'),\n    'permission_callback' => '__return_true', \u002F\u002F Vulnerable: Allows unauthenticated access\n));\n\n---\n\n\u002F\u002F Inferred callback logic\npublic function handle_post_query($request) {\n    $args = $request->get_params();\n    \u002F\u002F Vulnerable: Directly passing request parameters into WP_Query without \n    \u002F\u002F validating if the user has permission to view non-public post_status values.\n    $query = new WP_Query($args);\n    return rest_ensure_response($query->posts);\n}","--- a\u002Fincludes\u002Fpublic\u002Frest-api\u002Fclass-cubewp-posts-api.php\n+++ b\u002Fincludes\u002Fpublic\u002Frest-api\u002Fclass-cubewp-posts-api.php\n@@ -25,6 +25,11 @@\n     public function handle_post_query($request) {\n         $args = $request->get_params();\n+\n+        \u002F\u002F Enforce post_status to 'publish' for users without appropriate capabilities\n+        if (!current_user_can('edit_posts')) {\n+            $args['post_status'] = 'publish';\n+            if (isset($args['post_password'])) {\n+                unset($args['post_password']);\n+            }\n+        }\n+\n         $query = new WP_Query($args);\n         return rest_ensure_response($query->posts);\n     }","An attacker can exploit this vulnerability by sending a GET request to either the \u002Fwp-json\u002Fcubewp-posts\u002Fv1\u002Fquery or \u002Fwp-json\u002Fcubewp-posts\u002Fv1\u002Fquery-new endpoints. By including the 'post_status' parameter set to 'private', 'draft', or 'any', the attacker can bypass WordPress's default content visibility restrictions. The payload typically looks like \u002Fwp-json\u002Fcubewp-posts\u002Fv1\u002Fquery?post_status=private or \u002Fwp-json\u002Fcubewp-posts\u002Fv1\u002Fquery?p=[ID]&post_status=any. No authentication or nonces are required because the endpoint's permission_callback returns true regardless of the user's login state or privileges.","gemini-3-flash-preview","2026-05-05 07:01:32","2026-05-05 07:03:28",{"type":34,"vulnerable_version":35,"fixed_version":11,"vulnerable_browse":36,"vulnerable_zip":37,"fixed_browse":38,"fixed_zip":39,"all_tags":40},"plugin","1.1.27","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcubewp-framework\u002Ftags\u002F1.1.27","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fcubewp-framework.1.1.27.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcubewp-framework\u002Ftags\u002F1.1.28","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fcubewp-framework.1.1.28.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fcubewp-framework\u002Ftags"]