Ninja Forms – The Contact Form Builder That Grows With You <= 3.13.2 - Insecure Direct Object Reference to Unauthenticated Sensitive Information Exposure via Unscoped Bearer Token
Description
The Ninja Forms – The Contact Form Builder That Grows With You plugin for WordPress is vulnerable to Insecure Direct Object Reference in versions up to, and including, 3.13.2. This is due to the plugin not properly verifying that a user is authorized before the `ninja-forms-views` REST endpoints return form metadata and submission content. This makes it possible for unauthenticated attackers to read arbitrary form definitions and submission records via a leaked bearer token granted they can load any page containing the Submissions Table block. NOTE: The developer released a patch for this issue in 3.13.1, but inadvertently introduced a REST API endpoint in which a valid bearer token could be minted for arbitrary form IDs, making this patch ineffective.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:NTechnical Details
<=3.13.2Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2025-11924 ## 1. Vulnerability Summary **CVE-2025-11924** is a high-severity Insecure Direct Object Reference (IDOR) vulnerability in the **Ninja Forms** plugin (versions up to 3.13.2). The vulnerability resides in the `ninja-forms-views` REST API endpoints. Whi…
Show full research plan
Exploitation Research Plan - CVE-2025-11924
1. Vulnerability Summary
CVE-2025-11924 is a high-severity Insecure Direct Object Reference (IDOR) vulnerability in the Ninja Forms plugin (versions up to 3.13.2). The vulnerability resides in the ninja-forms-views REST API endpoints.
While the plugin attempted to restrict access via Bearer Tokens, two critical flaws exist:
- Authorization Bypass: The REST endpoints do not properly verify if the requester has the authority to view metadata or submissions associated with a specific form ID.
- Token Minting Flaw: A REST API endpoint (introduced in 3.13.1 as a "fix") allows an unauthenticated user to generate a valid bearer token for any arbitrary
form_id. This token can then be used to access sensitive submission data and form definitions.
2. Attack Vector Analysis
- Namespace:
wp-json/ninja-forms-views/v1(inferred from "ninja-forms-views"). - Vulnerable Endpoints:
- Token Minting: Likely a route like
GET /ninja-forms-views/v1/tokenorGET /ninja-forms-views/v1/auth. - Data Access:
GET /ninja-forms-views/v1/submissionsorGET /ninja-forms-views/v1/forms/(?P<id>[\d]+).
- Token Minting: Likely a route like
- Authentication: Unauthenticated.
- Parameters:
form_id(integer). - Preconditions: The "Submissions Table" block must be active or the REST routes must be registered (default behavior in affected versions).
3. Code Flow
- Entry Point: An unauthenticated HTTP request is made to the REST API.
- Route Registration: The plugin registers routes in the
ninja-forms-viewsnamespace. Look forregister_rest_routein files located inincludes/or aviewsspecific subdirectory. - Token Generation: A controller method (likely within a class handling the "Submissions Table" block) generates a JWT or Bearer token using a server-side secret but accepts a user-provided
form_idwithout checking if the user should have access to that form. - Data Retrieval: The
submissionsormetadataendpoint retrieves records from the$wpdb->prefix . 'nf3_submissions'table. It validates the Bearer token's signature but fails to check if theform_idembedded in the token (or provided as a parameter) belongs to the current user (which is 0/unauthenticated).
4. Nonce & Token Acquisition Strategy
Unlike standard AJAX actions, this vulnerability relies on a Bearer Token generated by the REST API itself.
Identifying the Minting Endpoint:
- Search the codebase for the string
ninja-forms-views. - Locate where the token is generated. Look for functions using
jwt,Bearer, oropenssl_encrypt. - Identify the specific REST route that calls this function.
Token Extraction via Browser (If needed):
If the token is localized for the block:
- Create a page with the Ninja Forms Submissions Table block.
- Identify the localized JS variable. It is likely something like
window.nfSubmissionsTableorwindow.nfViews. - Use
browser_eval("window.nfViewsConfig?.token")or similar to extract it.
Note: Since 3.13.1 allows minting for "arbitrary form IDs," the primary strategy is to hit the minting endpoint directly via http_request.
5. Exploitation Strategy
Step 1: Discover Form IDs
Iterate through small integers (1, 2, 3...) or use the public-facing REST API to list forms if available.
Step 2: Mint the Bearer Token
Perform an unauthenticated request to the identified minting endpoint.
- URL:
http://victimsite.com/wp-json/ninja-forms-views/v1/get-token?form_id=1(Target endpoint name to be confirmed in source). - Method:
GET - Expected Response: A JSON object containing a
tokenstring.
Step 3: Access Sensitive Information
Use the token to request submissions for the form_id.
- URL:
http://victimsite.com/wp-json/ninja-forms-views/v1/submissions?form_id=1 - Method:
GET - Headers:
Authorization: Bearer <TOKEN_FROM_STEP_2> - Expected Response: A JSON array of submission data, including user-submitted field values (PII, messages, etc.).
6. Test Data Setup
To verify the exploit, the environment must contain:
- A Ninja Form: Create a form with ID 1 using
wp-cli.# (Simplified) Ninja Forms data is complex; better to use the UI or import a form # but the agent can check for existing forms: wp db query "SELECT id FROM wp_nf3_forms;" - Submissions: Ensure the form has at least one submission containing sensitive data (e.g., Email:
victim@example.com, Message:SECRET_DATA). - Submissions Table Block: Create a post containing the block to ensure all REST routes are initialized.
wp post create --post_type=page --post_status=publish --post_content='<!-- wp:ninja-forms/submissions-table {"form_id":1} /-->' --post_title='Submissions'
7. Expected Results
- Token Minting: The response should return a token string even when no cookies or
X-WP-Nonceheaders are provided. - Data Leakage: The final request should return a
200 OKwith the full content of the submissions for the requestedform_id.
8. Verification Steps
After the HTTP exploit, verify via wp-cli:
- Compare the data returned by the exploit with the data in the database:
wp db query "SELECT * FROM wp_nf3_submissions WHERE form_id = 1;" wp db query "SELECT * FROM wp_nf3_submission_values WHERE parent_id = (SELECT id FROM wp_nf3_submissions WHERE form_id = 1 LIMIT 1);" - Check the version of Ninja Forms to ensure it is
<= 3.13.2:wp plugin get ninja-forms --field=version
9. Alternative Approaches
- Metadata Leakage: If submissions are empty, target the form metadata endpoint (
/ninja-forms-views/v1/forms/1) to see if internal form configurations (which might include email routing or API keys) are exposed. - Parameter Brute-forcing: If the token endpoint name is not obvious, use
grep -r "register_rest_route" .to find all available routes under theninja-forms-viewsnamespace.
Summary
Ninja Forms (<= 3.13.2) is vulnerable to an Insecure Direct Object Reference (IDOR) that allows unauthenticated users to access sensitive form submissions and metadata. A flaw in the 'ninja-forms-views' REST API allows attackers to 'mint' a valid Bearer token for any form ID, which can then be used to authenticate requests for protected submission records.
Exploit Outline
The exploit involves two main steps. First, an unauthenticated attacker sends a GET request to the token-minting endpoint (likely located at /wp-json/ninja-forms-views/v1/get-token or similar) with a target 'form_id' parameter. Because the endpoint lacks a permission check (permission_callback is likely set to __return_true), it returns a valid Bearer token. Second, the attacker uses this token in an Authorization header to query data endpoints such as /wp-json/ninja-forms-views/v1/submissions?form_id=[ID], which returns a JSON response containing sensitive submission values and PII.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.