CVE-2026-2126

User Submitted Posts <= 20260113 - Incorrect Authorization to Unauthenticated Category Restriction Bypass via 'user-submitted-category' Parameter

mediumIncorrect Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
20260217
Patched in
1d
Time to patch

Description

The User Submitted Posts – Enable Users to Submit Posts from the Front End plugin for WordPress is vulnerable to Incorrect Authorization in all versions up to, and including, 20260113. This is due to the `usp_get_submitted_category()` function accepting user-submitted category IDs from the POST body without validating them against the admin-configured allowed categories stored in `usp_options['categories']`. This makes it possible for unauthenticated attackers to assign submitted posts to arbitrary categories, including restricted ones, by crafting a direct POST request with manipulated `user-submitted-category[]` values, bypassing the frontend category restrictions.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=20260113
PublishedFebruary 17, 2026
Last updatedFebruary 18, 2026
Affected pluginuser-submitted-posts

What Changed in the Fix

Changes introduced in v20260217

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-2126 - User Submitted Posts Category Restriction Bypass ## 1. Vulnerability Summary The **User Submitted Posts** plugin (<= 20260113) contains an incorrect authorization vulnerability in the way it handles post category assignments during frontend submissions.…

Show full research plan

Exploitation Research Plan: CVE-2026-2126 - User Submitted Posts Category Restriction Bypass

1. Vulnerability Summary

The User Submitted Posts plugin (<= 20260113) contains an incorrect authorization vulnerability in the way it handles post category assignments during frontend submissions. While the plugin allows administrators to define a set of "allowed categories" for user submissions (stored in usp_options['categories']), the function responsible for retrieving the user's choice, usp_get_submitted_category(), fails to validate the submitted category IDs against this allowed list.

An unauthenticated attacker can manipulate the user-submitted-category[] POST parameter to assign their submission to any existing category on the WordPress site, bypassing the administrator's intended restrictions.

2. Attack Vector Analysis

  • Endpoint: Any frontend page containing the [user-submitted-posts] shortcode, or a direct POST request to the site's home/index URL (since the plugin processes submissions on the init or parse_request hook).
  • Vulnerable Parameter: user-submitted-category[] (POST body).
  • Authentication: Unauthenticated (Default configuration allows guest submissions).
  • Preconditions:
    • The plugin must be active.
    • At least one "Private" or "Restricted" category must exist that the admin did not intend for public use.
    • (Optional but common) The "Post Category" field is enabled in USP settings.

3. Code Flow

  1. Entry Point: A visitor submits the USP form. The plugin typically hooks into init via library/core-functions.php (referenced in user-submitted-posts.php).
  2. Submission Detection: The plugin checks for a specific POST parameter (often usp-title or a hidden trigger) to identify a submission attempt.
  3. Data Retrieval: The processing logic calls usp_get_submitted_category().
  4. The Vulnerable Sink: Inside usp_get_submitted_category() (located in user-submitted-posts.php or library/core-functions.php):
    • It reads $_POST['user-submitted-category'].
    • It performs basic sanitization (like intval).
    • Vulnerability: It returns these IDs directly to the post creation logic without checking if the IDs exist within the allowed array found in get_option('usp_options')['categories'].
  5. Post Creation: The returned category IDs are passed into wp_insert_post() or wp_set_post_categories(), successfully assigning the post to the attacker-chosen category.

4. Nonce Acquisition Strategy

Based on the plugin architecture and readme.txt:

  • The plugin emphasizes "anti-spam security" via challenge questions or Google reCAPTCHA rather than standard WordPress nonces for the submission itself, as it is designed for unauthenticated users.
  • However, if a nonce is present, it is likely enqueued via wp_localize_script in library/enqueue-scripts.php.

Strategy:

  1. Create a page with the shortcode [user-submitted-posts].
  2. Navigate to the page.
  3. Check for a localized JavaScript object. The common key for this plugin is usp_vars.
  4. Run in browser_eval: window.usp_vars?.nonce.
  5. If no nonce is found in the JS, check the HTML for a hidden field: document.querySelector('input[name="usp-nonce"]')?.value.

5. Exploitation Strategy

The goal is to submit a post assigned to a category that is not in the allowed list.

Step 1: Discover Category IDs

Identify the ID of a restricted category (e.g., "Uncategorized" or a custom "Private" category).

Step 2: Form Submission Request

Send a POST request to the WordPress root or the page containing the form.

HTTP Request Template:

POST / HTTP/1.1
Host: target.local
Content-Type: application/x-www-form-urlencoded

user-submitted-name=Attacker
user-submitted-title=Bypass+Test
user-submitted-content=This+post+should+be+in+a+restricted+category.
user-submitted-category[]=TARGET_CATEGORY_ID
usp-nonce=NONCE_VALUE (if found)
usp_verify_default=1 (Often used as a form submission trigger)

6. Test Data Setup

  1. Create Categories:
    • Create a "Public" category: wp term create category "Public" (Note ID, e.g., 2).
    • Create a "Restricted" category: wp term create category "Restricted" (Note ID, e.g., 3).
  2. Configure Plugin:
    • Set USP to allow only the "Public" category (ID 2).
    • wp option patch insert usp_options categories "2"
    • Ensure "Post Category" field is enabled: wp option patch insert usp_options usp_category "show"
  3. Create Submission Page:
    • wp post create --post_type=page --post_title="Submit" --post_status=publish --post_content="[user-submitted-posts]"
  4. Enable Guest Submissions:
    • Ensure usp_options['logged_in_users'] is not set to require login.

7. Expected Results

  • The HTTP response should indicate success (e.g., a redirect or a success message like "Success! Thank you for your submission.").
  • A new post should be created in the database.
  • The post_category or associated terms for this new post should include the Restricted category ID (ID 3), even though only ID 2 was allowed in settings.

8. Verification Steps

  1. Check Post Terms via WP-CLI:
    # Get the ID of the latest post
    LAST_POST_ID=$(wp post list --post_type=post --posts_per_page=1 --field=ID --orderby=date)
    
    # List the categories assigned to that post
    wp post term list $LAST_POST_ID category --fields=name,term_id
    
  2. Verify Bypass:
    • If the output shows the "Restricted" category ID, the bypass is confirmed.

9. Alternative Approaches

  • Multiple Categories: Attempt to pass an array to user-submitted-category[] containing both an allowed ID and a restricted ID to see if validation is partial.
  • Hidden Inputs: If the form is configured to not show the category selector, the attacker can still append user-submitted-category[] to the POST body, as the server-side code usp_get_submitted_category() will still look for it.
  • Default Category Fallback: If the plugin has a "Default Category" setting, verify if providing an invalid or non-existent ID in the POST request triggers a fallback or if it allows assigning the post to no category (potentially hiding it from standard feeds).

Check if your site is affected.

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