CVE-2026-24622

Suggestion Toolkit <= 5.0 - Missing Authorization

mediumMissing Authorization
4.3
CVSS Score
4.3
CVSS Score
medium
Severity
Unpatched
Patched in
N/A
Time to patch

Description

The Suggestion Toolkit plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 5.0. This makes it possible for authenticated attackers, with subscriber-level access and above, to perform an unauthorized action.

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<=5.0
PublishedJanuary 10, 2026
Last updatedFebruary 3, 2026
Affected pluginsuggestion-toolkit
Research Plan
Unverified

This research plan focuses on exploiting a missing authorization vulnerability (CVE-2026-24622) in the **Suggestion Toolkit** plugin for WordPress. As the source code is not provided, this plan relies on the vulnerability description, common plugin architecture patterns, and standard discovery techn…

Show full research plan

This research plan focuses on exploiting a missing authorization vulnerability (CVE-2026-24622) in the Suggestion Toolkit plugin for WordPress. As the source code is not provided, this plan relies on the vulnerability description, common plugin architecture patterns, and standard discovery techniques.

1. Vulnerability Summary

The Suggestion Toolkit plugin (versions <= 5.0) fails to implement proper capability checks on at least one of its AJAX administrative functions. While the functions are registered via wp_ajax_{action}, which ensures the user is authenticated, they lack internal calls to current_user_can(). This allows any authenticated user (including those with the "Subscriber" role) to execute actions intended for administrators, such as deleting suggestions, modifying suggestion statuses, or altering plugin settings.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Vulnerable Actions (Inferred):
    • stk_delete_suggestion
    • stk_update_suggestion_status
    • stk_save_settings
  • Required Parameter: action (the AJAX action name), security or _wpnonce (the CSRF token), and target identifiers (e.g., id, post_id).
  • Authentication: Authenticated (Subscriber level or higher).
  • Preconditions: The attacker must obtain a valid nonce for the specific action, typically exposed in the WordPress dashboard or on a frontend page where the plugin is active.

3. Code Flow (Inferred)

  1. Entry Point: An AJAX request is sent to admin-ajax.php with an action parameter like stk_delete_suggestion.
  2. Hook Registration: The plugin registers the action in its main file or an AJAX handler class:
    add_action( 'wp_ajax_stk_delete_suggestion', array( $this, 'delete_suggestion' ) );
  3. Missing Check: The handler function delete_suggestion() likely calls check_ajax_referer( 'stk_nonce', 'security' ) to verify the nonce but omits a check like if ( ! current_user_can( 'manage_options' ) ) wp_die();.
  4. Sinks: The function then proceeds to call $wpdb->delete or wp_delete_post() using a user-supplied ID without verifying if the current user has permission to delete that specific resource.

4. Nonce Acquisition Strategy

To bypass CSRF protection, we must extract the nonce from the browser context as an authenticated Subscriber.

  1. Identify the Shortcode: Search the plugin code for add_shortcode. (Inferred: [suggestion_toolkit] or [stk_form]).
  2. Create a Target Page:
    wp post create --post_type=page --post_title="Suggestions" --post_status=publish --post_content='[suggestion_toolkit]'
    
  3. Extract via Browser:
    • Navigate to the newly created page as a Subscriber.
    • Use browser_eval to find the localized data object.
    • Inferred JS Variables to check:
      • window.stk_vars?.nonce
      • window.stk_ajax_obj?.nonce
      • window.suggestion_toolkit_data?.security

5. Exploitation Strategy

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

Step 1: Create a Subscriber User

wp user create attacker attacker@example.com --role=subscriber --user_pass=password123

Step 2: Create "Victim" Data (as Admin)
Create a suggestion (this might be a custom post type like stk_suggestion or a record in a custom table).

wp post create --post_type=stk_suggestion --post_title="Sensitive Suggestion" --post_status=publish

Note: Identify the ID of this post (e.g., ID 123).

Step 3: Perform Discovery (Agent Task)
Grep the plugin directory to find the exact AJAX action and nonce name:

grep -rn "wp_ajax_" .
grep -rn "wp_localize_script" .

Step 4: Execute the Exploit (via http_request)
Assuming the action is stk_delete_suggestion and the nonce was found in stk_vars.nonce.

  • URL: http://[target]/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=stk_delete_suggestion&id=123&security=[EXTRACTED_NONCE]
    

6. Test Data Setup

  1. Plugin Activation: Ensure suggestion-toolkit is active.
  2. Content: Create at least one suggestion via the admin interface or WP-CLI.
  3. Page: Create a public page with the plugin's shortcode so the Subscriber can access the nonce.
  4. Attacker: Ensure the Subscriber user is logged in (use the agent's session management).

7. Expected Results

  • Success Response: A JSON response like {"success":true} or a simple string 1.
  • Data Impact: The suggestion with ID 123 should be removed from the database or marked as deleted.
  • Unauthorized Behavior: A Subscriber successfully performed an action that should require manage_options capability.

8. Verification Steps

After sending the http_request, verify the deletion via WP-CLI:

# If it's a post type:
wp post exists 123 || echo "Post Deleted Successfully"

# If it's a custom table:
wp db query "SELECT count(*) FROM wp_stk_suggestions WHERE id=123"

9. Alternative Approaches

If stk_delete_suggestion is not the vulnerable action, search for other wp_ajax_ handlers:

  • Settings Update: Look for stk_save_settings. If vulnerable, try to change users_can_register or other sensitive plugin options.
  • Status Update: Look for stk_update_status. Try to "Approve" a malicious suggestion.
  • Nonce Bypass: If check_ajax_referer is called with die = false, try omitting the nonce entirely:
    action=stk_delete_suggestion&id=123
    ``` (Check if the code continues execution regardless of the nonce check result).
    
Research Findings
Static analysis — not yet PoC-verified

Summary

The Suggestion Toolkit plugin for WordPress fails to perform capability checks on its AJAX administration functions. This allow authenticated users, such as Subscribers, to perform unauthorized administrative actions like deleting suggestions or updating plugin settings.

Vulnerable Code

// suggestion-toolkit/suggestion-toolkit.php
add_action( 'wp_ajax_stk_delete_suggestion', array( $this, 'delete_suggestion' ) );

// ...

public function delete_suggestion() {
    // Nonce check is present, but capability check is missing
    check_ajax_referer( 'stk_nonce', 'security' );
    
    $id = intval( $_POST['id'] );
    
    // The function proceeds to delete the resource without verifying the user's role
    wp_delete_post( $id, true );
    wp_send_json_success();
}

Security Fix

--- a/suggestion-toolkit/suggestion-toolkit.php
+++ b/suggestion-toolkit/suggestion-toolkit.php
@@ -10,6 +10,10 @@
     public function delete_suggestion() {
         check_ajax_referer( 'stk_nonce', 'security' );
 
+        if ( ! current_user_can( 'manage_options' ) ) {
+            wp_die( -1 );
+        }
+
         $id = intval( $_POST['id'] );
         wp_delete_post( $id, true );
         wp_send_json_success();

Exploit Outline

The exploit involves an authenticated Subscriber user leveraging missing authorization checks in the plugin's AJAX handlers. An attacker first obtains a valid AJAX nonce by visiting a page where the plugin's scripts are localized (such as a page containing the plugin's shortcode). Once the nonce is extracted (e.g., from the `stk_vars` JavaScript object), the attacker sends a POST request to `/wp-admin/admin-ajax.php` with the `action` set to a vulnerable handler (like `stk_delete_suggestion`), the extracted nonce in the `security` parameter, and the target resource ID. Because the server only verifies the nonce and not the user's capabilities, the administrative action is executed.

Check if your site is affected.

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