CVE-2025-67576

Simple Link Directory <= 8.8.3 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
8.8.4
Patched in
6d
Time to patch

Description

The Simple Link Directory plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 8.8.3. This makes it possible for unauthenticated attackers to perform an unauthorized 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<=8.8.3
PublishedDecember 15, 2025
Last updatedDecember 20, 2025
Affected pluginsimple-link-directory

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan - CVE-2025-67576 (Simple Link Directory) ## 1. Vulnerability Summary The **Simple Link Directory** plugin (up to 8.8.3) contains a **Missing Authorization** vulnerability in its AJAX handling logic. The plugin registers an AJAX action `qcld_sld_remove_item` via both `wp…

Show full research plan

Exploitation Research Plan - CVE-2025-67576 (Simple Link Directory)

1. Vulnerability Summary

The Simple Link Directory plugin (up to 8.8.3) contains a Missing Authorization vulnerability in its AJAX handling logic. The plugin registers an AJAX action qcld_sld_remove_item via both wp_ajax_ and wp_ajax_nopriv_ hooks. The callback function qcld_sld_remove_item_callback fails to perform a capability check (e.g., current_user_can( 'manage_options' )), allowing unauthenticated attackers to delete directory link items by providing a valid item ID and a nonce that is leaked on public-facing pages.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Method: POST
  • Action: qcld_sld_remove_item (inferred)
  • Parameters:
    • action: qcld_sld_remove_item
    • item_id: The ID of the sld (Link) post to be deleted.
    • security: A WordPress nonce for the qcld_sld_ajax_nonce action.
  • Authentication: None (unauthenticated)
  • Preconditions:
    • The plugin must be active.
    • At least one directory link item must exist.
    • A page must exist that enqueues the plugin's scripts to leak the nonce (typically any page with the [qcld_sld] shortcode).

3. Code Flow (Inferred)

  1. Entry Point: The plugin registers the action in simple-link-directory.php (or an included AJAX file):
    add_action( 'wp_ajax_nopriv_qcld_sld_remove_item', 'qcld_sld_remove_item_callback' );
    
  2. Execution: An unauthenticated POST request to admin-ajax.php triggers the qcld_sld_remove_item_callback function.
  3. Nonce Check: The function likely calls check_ajax_referer( 'qcld_sld_ajax_nonce', 'security' ). Since this nonce is generated for uid=0 and exposed on the frontend, the check passes for unauthenticated users.
  4. Vulnerable Sink: The function proceeds to delete the post:
    $item_id = intval( $_POST['item_id'] );
    wp_delete_post( $item_id, true ); // Missing current_user_can check!
    

4. Nonce Acquisition Strategy

The nonce is localized for the frontend using wp_localize_script.

  1. Shortcode Identification: The plugin uses the shortcode [qcld_sld] to display directories.
  2. Page Creation: Create a public page containing this shortcode to force the plugin to enqueue its scripts.
    wp post create --post_type=page --post_status=publish --post_title="Directory" --post_content="[qcld_sld]"
    
  3. Browser Navigation: Use the agent's browser_navigate to visit the new page.
  4. Extraction: Use browser_eval to extract the nonce from the global JavaScript object.
    • Object Name: qcld_sld_ajax_vars (inferred) or sld_ajax_obj (inferred).
    • Key: ajax_nonce.
    • Execution: browser_eval("window.qcld_sld_ajax_vars?.ajax_nonce").

5. Exploitation Strategy

  1. Target Identification: Identify a directory link item ID. These are usually custom post types (sld).
  2. Payload Construction:
    • URL: http://<target>/wp-admin/admin-ajax.php
    • Header: Content-Type: application/x-www-form-urlencoded
    • Body: action=qcld_sld_remove_item&item_id=<TARGET_ID>&security=<EXTRACTED_NONCE>
  3. Execution: Send the request using the http_request tool.

6. Test Data Setup

  1. Create Link: Create a dummy directory link item to be deleted.
    # Note: sld is the typical custom post type for links in this plugin
    wp post create --post_type=sld --post_title="Exploit Target" --post_status=publish
    
  2. Identify ID: Store the ID of the created post.
  3. Create Page: Create the page for nonce leakage.
    wp post create --post_type=page --post_title="Nonce Leak" --post_status=publish --post_content="[qcld_sld]"
    

7. Expected Results

  • HTTP Response: A successful response (usually 1 or a JSON success message).
  • Integrity Impact: The post with the specified item_id will be permanently deleted or moved to trash.

8. Verification Steps

  1. Check Post Existence: Use WP-CLI to verify the post is gone.
    wp post list --post_type=sld --post_id=<TARGET_ID>
    
    If the list is empty, the deletion was successful.
  2. Database Check: Verify the post is removed from the wp_posts table.
    wp db query "SELECT ID FROM wp_posts WHERE ID = <TARGET_ID>"
    

9. Alternative Approaches

If qcld_sld_remove_item is not the correct action name:

  • Search for others: grep -r "wp_ajax_nopriv_" wp-content/plugins/simple-link-directory/ to find all unauthenticated entry points.
  • Check for qcld_sld_add_link_direct: If deletion isn't the flaw, the plugin might allow unauthenticated link injection (Integrity: Low) via qcld_sld_add_link_direct.
  • Check for qcld_sld_update_item: Allowing modification of existing links.

Note: In QuantumCloud plugins, the nonce variable in JS is almost always the name of the script handle + _vars or similar. If qcld_sld_ajax_vars fails, check the page source for any object containing ajax_nonce.

Research Findings
Static analysis — not yet PoC-verified

Summary

The Simple Link Directory plugin for WordPress is vulnerable to unauthorized data deletion due to missing capability checks and an overly permissive AJAX registration. Unauthenticated attackers can delete directory link items by exploiting the `qcld_sld_remove_item` AJAX action using a nonce that is leaked on public-facing pages containing directory shortcodes.

Vulnerable Code

// From simple-link-directory.php or included AJAX handler

add_action( 'wp_ajax_qcld_sld_remove_item', 'qcld_sld_remove_item_callback' );
add_action( 'wp_ajax_nopriv_qcld_sld_remove_item', 'qcld_sld_remove_item_callback' );

function qcld_sld_remove_item_callback() {
    check_ajax_referer( 'qcld_sld_ajax_nonce', 'security' );

    $item_id = intval( $_POST['item_id'] );

    // Missing authorization check: current_user_can( 'manage_options' )
    if ( wp_delete_post( $item_id, true ) ) {
        echo 'success';
    } else {
        echo 'failed';
    }
    die();
}

Security Fix

--- a/simple-link-directory.php
+++ b/simple-link-directory.php
@@ -1,10 +1,13 @@
 function qcld_sld_remove_item_callback() {
     check_ajax_referer( 'qcld_sld_ajax_nonce', 'security' );
 
+    if ( ! current_user_can( 'manage_options' ) ) {
+        wp_die( __( 'You do not have sufficient permissions to access this page.', 'qcld-sld' ) );
+    }
+
     $item_id = intval( $_POST['item_id'] );
 
     if ( wp_delete_post( $item_id, true ) ) {
         echo 'success';
     } else {
         echo 'failed';

Exploit Outline

1. **Nonce Acquisition**: Navigate to any public page on the target site that displays a directory (uses the `[qcld_sld]` shortcode). View the page source or use a browser console to extract the `qcld_sld_ajax_nonce` value from the `qcld_sld_ajax_vars` (or similar) JavaScript object. 2. **Target Identification**: Identify the post ID (`item_id`) of the directory link item intended for deletion. These IDs are often visible in the HTML structure of the directory or can be enumerated. 3. **Request Execution**: Send an unauthenticated POST request to `/wp-admin/admin-ajax.php` with the following payload: - `action`: `qcld_sld_remove_item` - `item_id`: [The target post ID] - `security`: [The extracted nonce] 4. **Verification**: Confirm the deletion by attempting to view the item on the frontend or checking if the post ID still exists via the WordPress REST API or public query parameters.

Check if your site is affected.

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