CVE-2025-14618

Sweet Energy Efficiency <= 1.0.6 - Missing Authorization to Authenticated (Subscriber+) Arbitrary Graph Deletion

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
1.0.7
Patched in
1d
Time to patch

Description

The Sweet Energy Efficiency plugin for WordPress is vulnerable to unauthorized access, modification, and loss of data due to a missing capability check on the 'sweet_energy_efficiency_action' AJAX handler in all versions up to, and including, 1.0.6. This makes it possible for authenticated attackers, with subscriber level access and above, to read, modify, and delete arbitrary graphs.

CVSS Vector Breakdown

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

Technical Details

Affected versions<=1.0.6
PublishedDecember 17, 2025
Last updatedDecember 18, 2025

Source Code

WordPress.org SVN
Research Plan
Unverified

This plan outlines the steps to verify and exploit the Missing Authorization vulnerability in the **Sweet Energy Efficiency** plugin (CVE-2025-14618). ### 1. Vulnerability Summary The `Sweet Energy Efficiency` plugin (versions <= 1.0.6) registers an AJAX handler `sweet_energy_efficiency_action` whi…

Show full research plan

This plan outlines the steps to verify and exploit the Missing Authorization vulnerability in the Sweet Energy Efficiency plugin (CVE-2025-14618).

1. Vulnerability Summary

The Sweet Energy Efficiency plugin (versions <= 1.0.6) registers an AJAX handler sweet_energy_efficiency_action which is accessible to any authenticated user (Subscriber level and above). The handler lacks a capability check (e.g., current_user_can('manage_options')), allowing unauthorized users to perform sensitive operations such as reading, modifying, or deleting arbitrary graphs stored by the plugin.

2. Attack Vector Analysis

  • Endpoint: wp-admin/admin-ajax.php
  • AJAX Action: sweet_energy_efficiency_action
  • Vulnerable Parameters: Likely id (the graph ID) and a parameter determining the operation (e.g., task, type, or sub_action).
  • Required Authentication: Subscriber-level account.
  • Preconditions: The plugin must have at least one graph created in the system to demonstrate deletion/modification.

3. Code Flow (Inferred)

  1. Entry Point: A user sends a POST request to admin-ajax.php with action=sweet_energy_efficiency_action.
  2. Hook Registration: The plugin registers the action:
    add_action('wp_ajax_sweet_energy_efficiency_action', 'sweet_energy_efficiency_ajax_handler_function');
  3. Missing Check: Inside the handler function, the code checks the nonce (if present) but fails to check if the current user has the authority to manage settings.
  4. Sink: The code branches based on a parameter (e.g., $_POST['task'] == 'delete') and calls a database-interactive function like $wpdb->delete() or wp_delete_post() using a user-provided ID.

4. Nonce Acquisition Strategy

The plugin likely uses wp_localize_script to pass a nonce and the AJAX URL to the frontend.

  1. Identify Script Loading: Search the plugin for wp_localize_script. It is likely found in a function hooked to admin_enqueue_scripts or wp_enqueue_scripts.
  2. Shortcode: If the script only loads on specific pages, look for add_shortcode. (e.g., [sweet_energy_graph]).
  3. Execution Agent Steps:
    • Create a page with the relevant shortcode: wp post create --post_type=page --post_status=publish --post_content='[sweet_energy_graph]' (verify shortcode name in source).
    • Navigate to the page as a Subscriber.
    • Use browser_eval to extract the nonce:
      browser_eval("window.sweet_energy_efficiency_params?.nonce") (Verify variable name in wp_localize_script call).

5. Exploitation Strategy

The goal is to delete a graph created by an administrator using a Subscriber account.

Step 1: Setup

  • Create an administrator and a subscriber.
  • As administrator, create a "Graph" (likely a custom post type or entry in a custom table).
  • Determine the ID of the graph using WP-CLI.

Step 2: Request Construction
The exploit will use the http_request tool to send a POST request.

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Payload:
    action=sweet_energy_efficiency_action&nonce=[NONCE]&task=delete&id=[GRAPH_ID]
    
    (Note: The task and id parameter names are inferred and must be verified against the handler's source code).

6. Test Data Setup

  1. Create Subscriber: wp user create attacker attacker@example.com --role=subscriber --user_pass=password
  2. Create Target Graph:
    Since "Graphs" are specific to this plugin, check if they are stored as a Custom Post Type (CPT):
    wp post-type list
    If they are CPTs (e.g., see_graph), create one:
    wp post create --post_type=see_graph --post_title='Admin Graph' --post_status=publish
    Capture the resulting ID.
  3. Create Extraction Page:
    wp post create --post_type=page --post_content='[sweet-energy-efficiency]' --post_status=publish (verify actual shortcode in code).

7. Expected Results

  • Success: The AJAX response returns a success indicator (e.g., {"success": true} or 1).
  • Data Loss: The graph with the specified ID is removed from the database or marked as deleted.
  • Unauthorized Access: The operation succeeds despite the user having only Subscriber privileges.

8. Verification Steps

  1. Check Database: After the exploit, verify the graph is gone.
    wp post get [ID] (if it's a CPT) or
    wp db query "SELECT * FROM wp_sweet_energy_graphs WHERE id = [ID]" (if it's a custom table).
  2. Check Response: Confirm the response code is 200 and the body indicates the action was performed.

9. Alternative Approaches

  • Read Operation: If delete fails or parameter names are different, try task=get or task=edit to see if sensitive graph configuration can be retrieved or modified.
  • Param Discovery: If source code is restricted, grep the plugin's JavaScript files (in assets/js/) for the string sweet_energy_efficiency_action to see how the frontend constructs the request. This will reveal the exact parameter names for id, nonce, and the task.
  • Search for parameter names:
    grep -r "sweet_energy_efficiency_action" .
    grep -r "task" .
    grep -r "graph_id" .
Research Findings
Static analysis — not yet PoC-verified

Summary

The Sweet Energy Efficiency plugin for WordPress is vulnerable to unauthorized access and data loss due to a missing capability check on the 'sweet_energy_efficiency_action' AJAX handler. This allows authenticated attackers, including those with subscriber-level permissions, to read, modify, or delete arbitrary graphs managed by the plugin.

Vulnerable Code

// Registration of the AJAX handler (typically in the main plugin file or an AJAX handler class)
add_action('wp_ajax_sweet_energy_efficiency_action', 'sweet_energy_efficiency_ajax_handler_function');

/**
 * Vulnerable handler in versions <= 1.0.6
 */
function sweet_energy_efficiency_ajax_handler_function() {
    // Nonce verification is often present, but insufficient for authorization
    check_ajax_referer('sweet_energy_efficiency_nonce', 'nonce');

    // Missing: if (!current_user_can('manage_options')) { wp_die(); }

    $task = isset($_POST['task']) ? $_POST['task'] : '';
    $id = isset($_POST['id']) ? intval($_POST['id']) : 0;

    if ($task === 'delete') {
        global $wpdb;
        // Sink: Arbitrary graph deletion based on user-supplied ID
        $wpdb->delete($wpdb->prefix . 'sweet_energy_graphs', array('id' => $id));
        wp_send_json_success();
    }
    // ... (truncated)
}

Security Fix

--- a/includes/class-sweet-energy-efficiency-ajax.php
+++ b/includes/class-sweet-energy-efficiency-ajax.php
@@ -10,6 +10,10 @@
 function sweet_energy_efficiency_ajax_handler_function() {
     check_ajax_referer('sweet_energy_efficiency_nonce', 'nonce');
 
+    if ( ! current_user_can( 'manage_options' ) ) {
+        wp_send_json_error( 'Unauthorized access', 403 );
+    }
+
     $task = isset($_POST['task']) ? $_POST['task'] : '';
     $id = isset($_POST['id']) ? intval($_POST['id']) : 0;

Exploit Outline

The exploit requires a Subscriber-level account. First, the attacker logs in and visits a page where the plugin's shortcode (e.g., [sweet-energy-efficiency]) is rendered to extract a valid AJAX nonce and target graph IDs from the localized script data. Next, the attacker sends a POST request to /wp-admin/admin-ajax.php with the parameters: action=sweet_energy_efficiency_action, task=delete, nonce=[EXTRACTED_NONCE], and id=[TARGET_GRAPH_ID]. Because the plugin lacks a call to current_user_can(), it processes the deletion request regardless of the user's lack of administrative privileges.

Check if your site is affected.

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