CVE-2025-68509

User Submitted Posts <= 20251121 - Unauthenticated Open Redirect

mediumURL Redirection to Untrusted Site ('Open Redirect')
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
20251210
Patched in
5d
Time to patch

Description

The User Submitted Posts – Enable Users to Submit Posts from the Front End plugin for WordPress is vulnerable to Open Redirect in all versions up to, and including, 20251121. This is due to insufficient validation on the redirect url supplied parameter. This makes it possible for unauthenticated attackers to redirect users to potentially malicious sites if they can successfully trick them into performing an action.

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<=20251121
PublishedJanuary 1, 2026
Last updatedJanuary 5, 2026
Affected pluginuser-submitted-posts

What Changed in the Fix

Changes introduced in v20251210

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2025-68509 (Open Redirect) ## 1. Vulnerability Summary The **User Submitted Posts** plugin (version <= 20251121) contains an unauthenticated open redirect vulnerability. The plugin's post-submission logic allows a user-supplied URL to be used in a redirection call …

Show full research plan

Exploitation Research Plan: CVE-2025-68509 (Open Redirect)

1. Vulnerability Summary

The User Submitted Posts plugin (version <= 20251121) contains an unauthenticated open redirect vulnerability. The plugin's post-submission logic allows a user-supplied URL to be used in a redirection call (likely wp_redirect()) without sufficient validation. An attacker can craft a request that redirects a victim to an arbitrary external site after interacting with a page containing the plugin's form.

2. Attack Vector Analysis

  • Endpoint: Any frontend page where the [user-submitted-posts] shortcode is present.
  • Method: POST (typically) or GET (if the handler uses $_REQUEST).
  • Vulnerable Parameter: redirect-to (inferred from plugin history and settings).
  • Trigger Parameter: usp-submit (identifies the submission action).
  • Authentication: Not required (unauthenticated).
  • Preconditions: The [user-submitted-posts] shortcode must be active on a public page.

3. Code Flow

  1. Entry Point: The plugin registers an init or wp_loaded hook (likely in library/core-functions.php) to handle form submissions.
  2. Trigger: The handler checks for the presence of the usp-submit parameter in the request.
  3. Data Retrieval: The handler retrieves various user-submitted-* fields. It also retrieves the redirect-to parameter from $_POST or $_REQUEST.
  4. Processing: The plugin attempts to process the post submission (e.g., usp_create_post()).
  5. Sink: After processing (even if some validation fails, depending on the code structure), the plugin calls:
    $redirect = $_POST['redirect-to'];
    wp_redirect($redirect);
    exit;
    
  6. Vulnerability: Because wp_redirect() is used instead of wp_safe_redirect(), and the $redirect variable is not validated against a whitelist or the local site domain, the browser is redirected to the attacker-supplied URL.

4. Nonce Acquisition Strategy

User Submitted Posts is designed for guest submissions and often does not strictly enforce nonces for unauthenticated users, or it uses a specific nonce field that is rendered within the form.

  1. Identify the Form Page: Locate a page containing the [user-submitted-posts] shortcode.
  2. Create a Test Page:
    wp post create --post_type=page --post_title="Submit Post" --post_status=publish --post_content='[user-submitted-posts]'
    
  3. Navigate and Extract:
    • Navigate to the newly created page.
    • Check for a hidden field named usp-nonce or a localized JS variable.
    • Browser Eval Command:
      // Check for hidden input
      browser_eval("document.querySelector('input[name=\"usp-nonce\"]')?.value")
      // Check for localized script data (if applicable)
      browser_eval("window.usp_vars?.nonce")
      
    • Note: If no nonce is found or the field is empty, the plugin may be operating in a mode where nonces are not required for guest submissions.

5. Exploitation Strategy

We will simulate a form submission that includes the malicious redirect URL.

HTTP Request (POST)

  • URL: http://localhost:8080/submit-post/ (or the URL of the page with the shortcode)
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body Parameters:
    • usp-submit: 1 (or "Submit Post")
    • redirect-to: https://google.com (The malicious target)
    • user-submitted-title: Exploit Test
    • user-submitted-content: Exploit Content
    • usp-nonce: [EXTRACTED_NONCE] (if required)

Expected Response

The server should return a 302 Found status with a Location header pointing to https://google.com.

6. Test Data Setup

  1. Plugin Installation: Ensure user-submitted-posts version 20251121 is installed and activated.
  2. Shortcode Placement:
    wp post create --post_type=page --post_title="Vulnerable Page" --post_status=publish --post_content='[user-submitted-posts]'
    
  3. Plugin Settings (Optional): By default, the plugin allows guest submissions. Ensure "Post Status" is set to "Draft" or "Pending" to avoid cluttering the site, though this does not affect the redirect.

7. Expected Results

  • Primary Indicator: The HTTP response code is 302.
  • Secondary Indicator: The Location header in the response is exactly https://google.com.
  • Browser Behavior: If performed in a browser, the user would be navigated away from the WordPress site to Google.

8. Verification Steps

  1. Check Redirection: Use the http_request tool to send the payload and inspect the headers.
    {
      "action": "http_request",
      "method": "POST",
      "url": "http://localhost:8080/vulnerable-page/",
      "data": "usp-submit=1&redirect-to=https://google.com&user-submitted-title=test&user-submitted-content=test"
    }
    
  2. Confirm Lack of Validation: Verify that the redirection works for domains outside the WordPress instance (e.g., google.com, attacker.com).
  3. Database check (Post-Exploit): Verify if a post was actually created (optional, as the redirect may occur regardless).
    wp post list --post_title="Exploit Test"
    

9. Alternative Approaches

  • GET-based Redirect: Try the same parameters in a query string (?usp-submit=1&redirect-to=https://google.com) to see if the handler processes $_GET or $_REQUEST.
  • Insufficient Validation: If the plugin attempts some validation (e.g., checking for "http"), try bypasses like //google.com (protocol-relative URL) or https:google.com.
  • Alternative Parameter Names: If redirect-to fails, inspect the form's HTML for other hidden inputs like usp-redirect-to or url. (Quote from readme.txt: "Redirect user to any URL or current page after submission").
Research Findings
Static analysis — not yet PoC-verified

Summary

The User Submitted Posts plugin for WordPress is vulnerable to an open redirect due to insufficient validation of the 'redirect-override' parameter during form submission. Unauthenticated attackers can exploit this to redirect users to arbitrary external websites after they submit content through the plugin's frontend form.

Vulnerable Code

// user-submitted-posts.php line 476
if ($post_id) {
			
	if (!empty($_POST['redirect-override'])) {
				
		$redirect = $_POST['redirect-override'];
				
		$redirect = remove_query_arg(array('usp-error'), $redirect);
		$redirect = add_query_arg(array('usp_redirect' => '1', 'success' => 1, 'post_id' => $post_id), $redirect);
				
	} else {
		
		$redirect = $_SERVER['REQUEST_URI'];
		
		$redirect = remove_query_arg(array('usp-error'), $redirect);
		$redirect = add_query_arg(array('success' => 1, 'post_id' => $post_id), $redirect);
		
	}
	
	do_action('usp_submit_success', $redirect);

Security Fix

--- /home/deploy/wp-safety.org/data/plugin-versions/user-submitted-posts/20251121/user-submitted-posts.php	2025-11-22 17:29:40.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/user-submitted-posts/20251210/user-submitted-posts.php	2025-12-10 14:04:30.000000000 +0000
@@ -10,8 +10,8 @@
 	Contributors: specialk
 	Requires at least: 4.7
 	Tested up to: 6.9
-	Stable tag: 20251121
-	Version:    20251121
+	Stable tag: 20251210
+	Version:    20251210
 	Requires PHP: 5.6.20
 	Text Domain: usp
 	Domain Path: /languages
@@ -38,7 +38,7 @@
 if (!defined('ABSPATH')) die();
 
 if (!defined('USP_WP_VERSION')) define('USP_WP_VERSION', '4.7');
-if (!defined('USP_VERSION'))    define('USP_VERSION', '20251121');
+if (!defined('USP_VERSION'))    define('USP_VERSION', '20251210');
 if (!defined('USP_PLUGIN'))     define('USP_PLUGIN', 'User Submitted Posts');
 if (!defined('USP_FILE'))       define('USP_FILE', plugin_basename(__FILE__));
 if (!defined('USP_PATH'))       define('USP_PATH', plugin_dir_path(__FILE__));
@@ -473,21 +473,10 @@
 		
 		if ($post_id) {
 			
-			if (!empty($_POST['redirect-override'])) {
-				
-				$redirect = $_POST['redirect-override'];
-				
-				$redirect = remove_query_arg(array('usp-error'), $redirect);
-				$redirect = add_query_arg(array('usp_redirect' => '1', 'success' => 1, 'post_id' => $post_id), $redirect);
-				
-			} else {
-				
-				$redirect = $_SERVER['REQUEST_URI'];
-				
-				$redirect = remove_query_arg(array('usp-error'), $redirect);
-				$redirect = add_query_arg(array('success' => 1, 'post_id' => $post_id), $redirect);
-				
-			}
+			$redirect = $_SERVER['REQUEST_URI'];
+			
+			$redirect = remove_query_arg(array('usp-error'), $redirect);
+			$redirect = add_query_arg(array('success' => 1, 'post_id' => $post_id), $redirect);
 			
 			do_action('usp_submit_success', $redirect);

Exploit Outline

1. Find a WordPress page where the plugin's submission form is active via the `[user-submitted-posts]` shortcode. 2. Construct a POST request to the submission endpoint (the page URL) including standard submission fields such as `user-submitted-title`, `user-submitted-content`, and `usp-submit=1`. 3. Include a malicious `redirect-override` parameter set to an external domain (e.g., `https://attacker.com`). 4. Submit the request. Because the plugin does not validate the domain of the `redirect-override` value, it will redirect the browser to the attacker-specified URL upon successful post creation.

Check if your site is affected.

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