Ninja Forms <= 3.14.1 - Authenticated (Contributor+) Sensitive Information Disclosure via Block Editor Token
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:NTechnical Details
<=3.14.1What Changed in the Fix
Changes introduced in v3.14.2
Source Code
WordPress.org SVN# 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 endpointwp-json/ninja-forms-submissions/v1/submissions. - Preconditions:
- Attacker must have an account with at least
Contributorprivileges. - At least one Ninja Form must exist with submission data.
- Attacker must have an account with at least
- 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
- Entry Point: A Contributor user accesses
wp-admin/post-new.php. - Hook Execution: The
admin_enqueue_scriptsaction inblocks/bootstrap.phpfires. - Condition Check: The code checks
is_block_editor(). Since Contributor users can create posts, this is true. - 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. - Token Generation:
NinjaForms\Blocks\Authentication\TokenFactory::make()->create($publicKey, $allFormIds)generates a token for all forms. - Information Disclosure:
wp_localize_scriptattaches the token to theninja-forms/submissions-table/blockscript as thetokenproperty of theninjaFormsViewsobject. - Exploitation: The attacker extracts
window.ninjaFormsViews.tokenand 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.
- Login: Log in as a Contributor.
- Navigation: Navigate to the "New Post" page:
wp-admin/post-new.php. - Extraction: Use
browser_evalto access the global JS object.- JS Object:
window.ninjaFormsViews - Key:
token - Execution:
browser_eval("window.ninjaFormsViews?.token")
- JS Object:
- Form Discovery: The
nfFormsBlockobject (also localized in the same file) may contain form IDs.- Execution:
browser_eval("window.nfFormsBlock?.forms")
- Execution:
5. Exploitation Strategy
Step 1: Setup Test Data
- Create a Ninja Form (ID 1).
- Use WP-CLI to simulate a submission for Form 1.
- Create a user
attackerwith thecontributorrole.
Step 2: Extract Leaked Token
- Log in to the WordPress dashboard as
attacker. - Navigate to
wp-admin/post-new.php. - Extract the token from
window.ninjaFormsViews.token.
Step 3: Access Submissions via REST API
- Use the leaked token to query the submissions endpoint.
- Request Type:
GET - Endpoint:
/wp-json/ninja-forms-submissions/v1/submissions - Parameters:
formID: (e.g.,1)token:[LEAKED_TOKEN]
- Headers:
X-WP-Nonce: Standard REST nonce (can be obtained viawindow.wpApiSettings.noncein the editor). Note: The token itself handles authorization for the specific Ninja Forms data.
Step 4: Verify Disclosure
- 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 a200 OKwith sensitive submission data.- Without the token, the same request returns
403 Forbiddenor401 Unauthorized.
8. Verification Steps
- Check API Response: Verify the JSON contains the string "submission" and the values submitted in Step 1.
- Check Capability: Confirm that a standard
GET /wp-admin/edit.php?post_type=nf_sub&form_id=1results in a permission error for theattackeruser, 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/renderis 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_initinblocks/bootstrap.php(truncated in source) for the exact route path. It is likelyninja-forms-submissions/v1.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.