[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fccClx78TbdorZMwOvYi-rzq-MouAsAgIw2hEUdKcZL4":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":29,"research_verified":30,"research_rounds_completed":31,"research_plan":32,"research_summary":9,"research_vulnerable_code":9,"research_fix_diff":9,"research_exploit_outline":9,"research_model_used":33,"research_started_at":34,"research_completed_at":35,"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":30,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":30,"source_links":36},"CVE-2025-69347","subscription-for-woocommerce-wordpress-recurring-payments-plugin-authenticated-customer-insecure-direct-object-reference","Subscription for WooCommerce – WordPress Recurring Payments Plugin \u003C= 1.8.10 - Authenticated (Customer+) Insecure Direct Object Reference","The Subscription for WooCommerce – WordPress Recurring Payments Plugin plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 1.8.10 due to missing validation on a user controlled key. This makes it possible for authenticated attackers, with Custom-level access and above, to perform an unauthorized action.","subscription",null,"\u003C=1.8.10","1.8.11","medium",4.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Authorization Bypass Through User-Controlled Key","2026-03-05 00:00:00","2026-03-12 17:07:30",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F8d4bbbf9-db8e-4e8a-999b-9fa279d3daea?source=api-prod",8,[22,23,24,25,26,27,28],"changelog.txt","includes\u002FAdmin\u002Fviews\u002Fsubscription-customer.php","includes\u002FFrontend\u002FActionController.php","includes\u002FFrontend\u002FMyAccount.php","includes\u002FIlluminate.php","includes\u002FTraits\u002FEmail.php","includes\u002Ffunctions.php","researched",false,3,"# Exploitation Research Plan: CVE-2025-69347 (Insecure Direct Object Reference)\n\n## 1. Vulnerability Summary\nThe **Subscription for WooCommerce** plugin (versions \u003C= 1.8.10) contains an Insecure Direct Object Reference (IDOR) vulnerability in its subscription action handling logic. The `SpringDevs\\Subscription\\Frontend\\ActionController::control_action_subscrpt` function processes requests to modify subscription statuses (cancel, reactivate, toggle auto-renewal) based on a user-provided `subscrpt_id`. \n\nWhile the function validates a WordPress nonce (`subscrpt_nonce`), the nonce is not bound to a specific subscription ID, and the function fails to verify if the currently authenticated user owns the subscription associated with the provided ID. This allows any authenticated user with \"Customer\" permissions to perform unauthorized actions on any other user's subscription.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `[site-url]\u002Fmy-account\u002Fview-subscription\u002F[ANY_ID]\u002F`\n- **Query Parameters:**\n    - `subscrpt_id`: The target Subscription Post ID (integer).\n    - `action`: The unauthorized action (e.g., `cancelled`, `reactive`, `renew-on`, `renew-off`).\n    - `wpnonce`: A valid `subscrpt_nonce` obtained from the attacker's own session.\n- **Authentication Level:** Authenticated (Customer or higher).\n- **Preconditions:** The attacker must have at least one subscription of their own to access the \"View Subscription\" page and obtain a valid nonce.\n\n## 3. Code Flow\n1.  **Entry Point:** The `ActionController` class (in `includes\u002FFrontend\u002FActionController.php`) registers a listener on the `before_single_subscrpt_content` hook.\n2.  **Trigger:** When a user visits the \"View Subscription\" endpoint (`\u002Fmy-account\u002Fview-subscription\u002FID`), the `MyAccount::view_subscrpt_content` function is called, which eventually triggers the `before_single_subscrpt_content` hook via a template.\n3.  **Vulnerable Function:** `ActionController::control_action_subscrpt()` is executed.\n4.  **Verification (Incomplete):**\n    - Line 35: `wp_verify_nonce( $wpnonce, 'subscrpt_nonce' )` verifies the nonce. Since `subscrpt_nonce` is generated without an object-specific action string (see `includes\u002FFrontend\u002FMyAccount.php` line 111), the same nonce works for any ID for that user.\n5.  **Unauthorized Action (Sink):**\n    - The code proceeds to perform actions based on the `action` parameter.\n    - If `action=cancelled`, it calls `Action::status( 'pe_cancelled', $subscrpt_id )` (Line 52) or `Action::status( $action, $subscrpt_id )` (Line 54).\n    - If `action=renew-off`, it calls `update_post_meta( $subscrpt_id, '_subscrpt_auto_renew', 0 )` (Line 60).\n6.  **Missing Check:** There is no check (e.g., comparing `$subscrpt_id` ownership) before these status modifications occur.\n\n## 4. Nonce Acquisition Strategy\nThe `subscrpt_nonce` is required. It is generated during the rendering of any \"View Subscription\" page the user is authorized to see.\n\n1.  **Navigate to Subscription Page:** The attacker logs in and navigates to their own subscription: `\u002Fmy-account\u002Fview-subscription\u002F[ATTACKER_SUB_ID]\u002F`.\n2.  **Extract Nonce:** The nonce is used in the action buttons (Cancel, Renew, etc.).\n3.  **Browser Eval:**\n    ```javascript\n    \u002F\u002F The nonce is often found in links within the .customer-details or .actions div\n    \u002F\u002F Alternatively, it might be enqueued, but here it's typically in the HTML links\n    Array.from(document.querySelectorAll('a')).find(a => a.href.includes('wpnonce')).href.split('wpnonce=')[1].split('&')[0]\n    ```\n    If the plugin localizes data (not explicitly seen in provided snippets but common), check `window`.\n\n## 5. Exploitation Strategy\nThe goal is to cancel a victim's subscription.\n\n1.  **Identify Victim ID:** Determine the Subscription Post ID of the victim (e.g., via enumeration or leaked data).\n2.  **Obtain Nonce:** Log in as `attacker` and visit `\u002Fmy-account\u002Fview-subscription\u002F[ATTACKER_ID]`. Extract `wpnonce`.\n3.  **Craft Request:**\n    - **Method:** `GET`\n    - **URL:** `http:\u002F\u002Flocalhost:8080\u002Fmy-account\u002Fview-subscription\u002F[ATTACKER_ID]\u002F?subscrpt_id=[VICTIM_ID]&action=cancelled&wpnonce=[NONCE]`\n    - **Note:** The ID in the path doesn't matter as much as the `subscrpt_id` parameter, as the hook triggers on the page load.\n4.  **Execute:** Use the `http_request` tool to send the authenticated GET request.\n\n## 6. Test Data Setup\n1.  **Install Requirements:** WooCommerce and the \"Subscription\" plugin.\n2.  **Create Product:** Create a simple product with subscription enabled.\n3.  **Create Users:**\n    - `victim_user` (Subscriber)\n    - `attacker_user` (Subscriber)\n4.  **Generate Subscriptions:**\n    - Process a checkout for `victim_user` to create subscription `V_ID`.\n    - Process a checkout for `attacker_user` to create subscription `A_ID`.\n5.  **Ensure Status:** Ensure `V_ID` status is `active`.\n\n## 7. Expected Results\n- The server will process the request and redirect (via JavaScript\u002FLocation header) to the view page.\n- The subscription `V_ID` will have its post status changed to `pe_cancelled` (pending cancellation) or `cancelled`.\n\n## 8. Verification Steps\n1.  **Check Status via WP-CLI:**\n    ```bash\n    wp post get [VICTIM_ID] --field=post_status\n    ```\n2.  **Verify Meta (if testing renewal toggle):**\n    ```bash\n    wp post meta get [VICTIM_ID] _subscrpt_auto_renew\n    ```\n3.  **Observe Response:** A successful exploit often results in the attacker being redirected to `\u002Fmy-account\u002Fview-subscription\u002F[VICTIM_ID]` (if they try to view it) or seeing a success message if the plugin logic allows.\n\n## 9. Alternative Approaches\n- **Renewal Toggle:** If cancellation is too disruptive for a PoC, use `action=renew-off` and verify the `_subscrpt_auto_renew` meta changes from `1` to `0`.\n- **Status Reaction:** If a subscription is cancelled, try `action=reactive` to set it back to `active`.\n- **Direct IDOR Enumeration:** If nonces were somehow bound to IDs (which they aren't here), the attacker would need to find a way to leak a victim's specific nonce. Given they are not bound, a simple loop through IDs could theoretically disrupt all subscriptions on the platform.","gemini-3-flash-preview","2026-04-18 06:07:56","2026-04-18 06:08:33",{"type":37,"vulnerable_version":38,"fixed_version":11,"vulnerable_browse":39,"vulnerable_zip":40,"fixed_browse":41,"fixed_zip":42,"all_tags":43},"plugin","1.8.10","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fsubscription\u002Ftags\u002F1.8.10","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fsubscription.1.8.10.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fsubscription\u002Ftags\u002F1.8.11","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fsubscription.1.8.11.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fsubscription\u002Ftags"]