CVE-2026-1307

Ninja Forms <= 3.14.1 - Authenticated (Contributor+) Sensitive Information Disclosure via Block Editor Token

mediumExposure of Sensitive Information to an Unauthorized Actor
6.5
CVSS Score
6.5
CVSS Score
medium
Severity
3.14.2
Patched in
1d
Time to patch

Description

The Ninja Forms - The Contact Form Builder That Grows With You plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 3.14.1 via a callback function for the admin_enqueue_scripts action handler in blocks/bootstrap.php. This makes it possible for authenticated attackers, with Contributor-level access and above, to gain access to an authorization token to view form submissions for arbitrary forms, which could potentially contain sensitive information.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=3.14.1
PublishedMarch 27, 2026
Last updatedMarch 28, 2026
Affected pluginninja-forms

What Changed in the Fix

Changes introduced in v3.14.2

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2026-1307 ## 1. Vulnerability Summary The **Ninja Forms** plugin (versions <= 3.14.1) contains a sensitive information disclosure vulnerability. The plugin improperly exposes a cryptographic authorization token to users with **Contributor-level** access and above.…

Show full research plan

Exploitation Research Plan - CVE-2026-1307

1. Vulnerability Summary

The Ninja Forms plugin (versions <= 3.14.1) contains a sensitive information disclosure vulnerability. The plugin improperly exposes a cryptographic authorization token to users with Contributor-level access and above. This token is intended to grant access to form submission data via the REST API.

The flaw exists in blocks/bootstrap.php within the admin_enqueue_scripts action handler. While the code attempts to restrict token generation to users with specific capabilities, the default or filtered capability requirements in affected versions allow Contributor+ users (who can access the WordPress Block Editor) to receive the token. This token is localized into the global JavaScript object ninjaFormsViews, allowing an attacker to use it to retrieve submission data for any form on the site.

2. Attack Vector Analysis

  • Endpoint: wp-admin/post-new.php (or any block editor page) and the REST API endpoint wp-json/ninja-forms-submissions/v1/submissions.
  • Preconditions:
    • Attacker must have an account with at least Contributor privileges.
    • At least one Ninja Form must exist with submission data.
  • Leaked Material: An authorization token generated by NinjaForms\Blocks\Authentication\TokenFactory.
  • Target Sink: The Ninja Forms Submissions REST API, which accepts the leaked token to bypass standard capability checks for viewing submissions.

3. Code Flow

  1. Entry Point: A Contributor user accesses wp-admin/post-new.php.
  2. Hook Execution: The admin_enqueue_scripts action in blocks/bootstrap.php fires.
  3. Condition Check: The code checks is_block_editor(). Since Contributor users can create posts, this is true.
  4. Capability Check (Vulnerable): The code checks current_user_can( $views_capability ). In vulnerable versions, $views_capability (derived from filters) is either not properly enforced or defaults to a capability held by Contributors.
  5. Token Generation: NinjaForms\Blocks\Authentication\TokenFactory::make()->create($publicKey, $allFormIds) generates a token for all forms.
  6. Information Disclosure: wp_localize_script attaches the token to the ninja-forms/submissions-table/block script as the token property of the ninjaFormsViews object.
  7. Exploitation: The attacker extracts window.ninjaFormsViews.token and calls the REST API.

4. Nonce & Token Acquisition Strategy

Since the vulnerability is the exposure of a token, we must use the browser context to extract it.

  1. Login: Log in as a Contributor.
  2. Navigation: Navigate to the "New Post" page: wp-admin/post-new.php.
  3. Extraction: Use browser_eval to access the global JS object.
    • JS Object: window.ninjaFormsViews
    • Key: token
    • Execution: browser_eval("window.ninjaFormsViews?.token")
  4. Form Discovery: The nfFormsBlock object (also localized in the same file) may contain form IDs.
    • Execution: browser_eval("window.nfFormsBlock?.forms")

5. Exploitation Strategy

Step 1: Setup Test Data

  1. Create a Ninja Form (ID 1).
  2. Use WP-CLI to simulate a submission for Form 1.
  3. Create a user attacker with the contributor role.

Step 2: Extract Leaked Token

  1. Log in to the WordPress dashboard as attacker.
  2. Navigate to wp-admin/post-new.php.
  3. Extract the token from window.ninjaFormsViews.token.

Step 3: Access Submissions via REST API

  1. Use the leaked token to query the submissions endpoint.
  2. Request Type: GET
  3. Endpoint: /wp-json/ninja-forms-submissions/v1/submissions
  4. Parameters:
    • formID: (e.g., 1)
    • token: [LEAKED_TOKEN]
  5. Headers:
    • X-WP-Nonce: Standard REST nonce (can be obtained via window.wpApiSettings.nonce in the editor). Note: The token itself handles authorization for the specific Ninja Forms data.

Step 4: Verify Disclosure

  1. The response should be a JSON array containing the fields and values of the submissions for the requested form, which a Contributor normally cannot see.

6. Test Data Setup

# 1. Create a form (or use default if plugin creates one)
# 2. Create a submission for form 1
# Note: Submissions are stored in 'nf3_submissions' and 'nf3_submission_values' tables
# It is easier to use a manual HTTP POST to a public form if it exists.

# 3. Create Contributor user
wp user create attacker attacker@example.com --role=contributor --user_pass=password123

7. Expected Results

  • Navigating to the editor as a Contributor reveals a token in the page source/JS scope.
  • GET /wp-json/ninja-forms-submissions/v1/submissions?formID=1&token=<TOKEN> returns a 200 OK with sensitive submission data.
  • Without the token, the same request returns 403 Forbidden or 401 Unauthorized.

8. Verification Steps

  1. Check API Response: Verify the JSON contains the string "submission" and the values submitted in Step 1.
  2. Check Capability: Confirm that a standard GET /wp-admin/edit.php?post_type=nf_sub&form_id=1 results in a permission error for the attacker user, proving that the REST API bypass is the only way they accessed the data.

9. Alternative Approaches

If ninja-forms/submissions-table/block is not enqueued for some reason:

  • Check if ninja-forms/submissions-table/render is enqueued if a "Submissions Table" block is added to a post (even if not published).
  • Attempt to manually enqueue the script if the Contributor has enough permissions to trigger the block loader.
  • If the endpoint differs, check rest_api_init in blocks/bootstrap.php (truncated in source) for the exact route path. It is likely ninja-forms-submissions/v1.

Check if your site is affected.

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