CVE-2025-14742

WP Recipe Maker <= 10.2.4 - Missing Authorization to Authenticated (Subscriber+) Sensitive Information Exposure

mediumAuthorization Bypass Through User-Controlled Key
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
10.3.0
Patched in
76d
Time to patch

Description

The WP Recipe Maker plugin for WordPress is vulnerable to unauthorized access of data due to a missing capability check on the 'ajax_search_recipes' and 'ajax_get_recipe' functions in all versions up to, and including, 10.2.4 This makes it possible for authenticated attackers, with Subscriber-level access and above, to retrieve sensitive recipe information including draft, pending, and private recipes that they shouldn't be able to access.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Unchanged
Low
Confidentiality
None
Integrity
None
Availability

Technical Details

Affected versions<=10.2.4
PublishedFebruary 24, 2026
Last updatedMay 11, 2026
Affected pluginwp-recipe-maker

What Changed in the Fix

Changes introduced in v10.3.0

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Research Plan: CVE-2025-14742 - WP Recipe Maker Missing Authorization ## 1. Vulnerability Summary The **WP Recipe Maker** plugin (<= 10.2.3) contains a missing authorization vulnerability in its AJAX handlers for searching and retrieving recipes. Specifically, the functions `ajax_search_recipes` …

Show full research plan

Research Plan: CVE-2025-14742 - WP Recipe Maker Missing Authorization

1. Vulnerability Summary

The WP Recipe Maker plugin (<= 10.2.3) contains a missing authorization vulnerability in its AJAX handlers for searching and retrieving recipes. Specifically, the functions ajax_search_recipes and ajax_get_recipe do not implement sufficient capability checks or post-status filtering. This allows any authenticated user with Subscriber-level permissions to access recipe data that should be restricted, such as recipes in draft, pending, or private status.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • AJAX Actions (Inferred from function names):
    • wprm_search_recipes (calls ajax_search_recipes)
    • wprm_get_recipe (calls ajax_get_recipe)
  • Vulnerable Parameters:
    • recipe_id (likely used in ajax_get_recipe to fetch a specific recipe).
    • search or term (likely used in ajax_search_recipes to query recipes).
  • Authentication: Authenticated (Subscriber-level and above).
  • Preconditions: A "Secret" recipe must exist in a non-public state (Draft, Private, or Pending).

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers AJAX actions during init or admin_init:
    add_action( 'wp_ajax_wprm_search_recipes', array( $this, 'ajax_search_recipes' ) );
    add_action( 'wp_ajax_wprm_get_recipe', array( $this, 'ajax_get_recipe' ) );
    
  2. Missing Check: Inside ajax_get_recipe($recipe_id), the code likely calls WPRM_Recipe_Handler::get_recipe( $recipe_id ) or get_post( $recipe_id ) without verifying if the current user has the edit_posts capability or if the post is publish.
  3. Missing Check: Inside ajax_search_recipes(), the code likely performs a WP_Query with post_type => 'wprm_recipe' but fails to set post_status => 'publish', thereby returning results from all statuses to any logged-in user.
  4. Sink: The raw recipe object (including sensitive meta and content) is returned as a JSON response via wp_send_json().

4. Nonce Acquisition Strategy

The plugin typically enqueues admin scripts for the Recipe Modal which contain the required nonces.

  1. Identify Nonce Source: The nonce is likely localized in a global JavaScript object, potentially wprm_admin or wprm_manage.
  2. Setup for Nonce Extraction:
    • The Recipe Modal logic is often present on the Post Editor or the "Manage Recipes" page.
    • Create a simple post and include the WPRM shortcode or navigate to the WPRM management page.
  3. Extraction Steps:
    • Step 1: Create a page: wp post create --post_type=page --post_status=publish --post_content='[wprm-recipe-search]' --post_title='Exploit Page'
    • Step 2: Navigate to the page as the Subscriber user using browser_navigate.
    • Step 3: Execute browser_eval to find the nonce:
      // Common WPRM localization keys (to be verified by the agent)
      window.wprm_admin?.nonce || window.wprm_manage?.nonce || window.wprm_public?.nonce
      
    • Alternative: If no nonce is verified in the wp_ajax_ handler (only a login check exists), the request may proceed with just the session cookie.

5. Exploitation Strategy

Step 1: Data Exposure via Search

Retrieve the IDs of recipes that are not public.

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=wprm_search_recipes&search=Secret&security=[NONCE]
    
  • Expected Response: JSON array containing objects with id and title for recipes including those in "Draft" status.

Step 2: Data Exposure via Get Recipe

Retrieve the full details of a restricted recipe ID discovered in Step 1.

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=wprm_get_recipe&recipe_id=[RESTRICTED_ID]&security=[NONCE]
    
  • Expected Response: A JSON object containing the full recipe content (ingredients, instructions, notes) that should only be visible to authors/admins.

6. Test Data Setup

  1. Admin Actions:
    • Install and activate wp-recipe-maker version 10.2.3.
    • Create a recipe titled "Public Apple Pie" and Publish it.
    • Create a recipe titled "Secret Agent Cookies" and set status to Draft.
    • Create a recipe titled "Private Government Pasta" and set status to Private.
    • Create a Subscriber user: wp user create attacker attacker@example.com --role=subscriber --user_pass=password123.
  2. Shortcode Deployment:
    • wp post create --post_type=page --post_status=publish --post_content='[wprm-recipe-search]' --post_title='Search Portal' (To help find nonces if enqueued).

7. Expected Results

  • The Subscriber user, despite having no permissions to view drafts or private posts, receives a JSON response from wprm_search_recipes that includes "Secret Agent Cookies".
  • The Subscriber user receives the full JSON data for "Private Government Pasta" when querying its ID via wprm_get_recipe.
  • The post_status of the returned recipes in the DB is confirmed as draft or private.

8. Verification Steps

  1. Check Recipe Status via CLI:
    wp post list --post_type=wprm_recipe --post_status=any --fields=ID,post_title,post_status
    
  2. Confirm Lack of Permissions:
    wp user cap list attacker
    # Confirm 'edit_others_posts' or 'read_private_posts' is NOT present.
    
  3. Evaluate Response: Verify that the JSON response body from the http_request tool contains the sensitive recipe ingredients or instructions.

9. Alternative Approaches

  • Parameter Variation: If security is not the nonce key, try nonce, _wpnonce, or wprm_nonce.
  • Search Discovery: If wprm_search_recipes does not return IDs, try to brute-force ID numbers (e.g., 1-100) using wprm_get_recipe to see which ones return data.
  • Direct Access Check: Try accessing the REST API (if enabled) at /wp-json/wprm/v1/recipes/[ID] to see if the missing authorization extends to REST routes.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.