CVE-2026-6441

Canto <= 3.1.1 - Missing Authorization to Authenticated (Subscriber+) Arbitrary Setting Modification

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

Description

The Canto plugin for WordPress is vulnerable to Missing Authorization in versions up to and including 3.1.1. This is due to the absence of any capability check or nonce verification in the updateOptions() function, which is exposed via two AJAX hooks: wp_ajax_updateOptions (class-canto.php line 231) and wp_ajax_fbc_updateOptions (class-canto-settings.php line 76). Both hooks are registered exclusively under the wp_ajax_ prefix (requiring only a logged-in user), with no call to current_user_can() or check_ajax_referer(). This makes it possible for authenticated attackers with subscriber-level access and above to arbitrarily modify or delete plugin options controlling cron scheduling behavior (fbc_duplicates, fbc_cron, fbc_schedule, fbc_cron_time_day, fbc_cron_time_hour, fbc_cron_start) and to manipulate or clear the plugin's scheduled WordPress cron event (fbc_scheduled_update).

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<=3.1.1
PublishedApril 16, 2026
Last updatedMay 11, 2026
Affected plugincanto
Research Plan
Unverified

# Research Plan: CVE-2026-6441 - Missing Authorization in Canto Plugin ## 1. Vulnerability Summary The Canto plugin for WordPress (versions <= 3.1.1) contains a missing authorization vulnerability in its option-updating logic. The function `updateOptions()` is registered as an AJAX handler for auth…

Show full research plan

Research Plan: CVE-2026-6441 - Missing Authorization in Canto Plugin

1. Vulnerability Summary

The Canto plugin for WordPress (versions <= 3.1.1) contains a missing authorization vulnerability in its option-updating logic. The function updateOptions() is registered as an AJAX handler for authenticated users (wp_ajax_ prefix) but fails to implement any current_user_can() capability checks or check_ajax_referer() nonce verifications. Consequently, any logged-in user, including those with the lowest privilege (Subscriber), can modify or delete critical plugin settings and manipulate scheduled cron events.

2. Attack Vector Analysis

  • Endpoints: /wp-admin/admin-ajax.php
  • AJAX Actions:
    • updateOptions (Registered in class-canto.php around line 231)
    • fbc_updateOptions (Registered in class-canto-settings.php around line 76)
  • HTTP Method: POST
  • Vulnerable Parameter: The parameters handled by updateOptions() typically include setting keys such as fbc_duplicates, fbc_cron, fbc_schedule, etc.
  • Required Authentication: Any logged-in user (Subscriber-level and above).
  • Preconditions: The plugin must be active.

3. Code Flow

  1. Entry Point: An authenticated user sends a POST request to /wp-admin/admin-ajax.php with the action parameter set to either updateOptions or fbc_updateOptions.
  2. Hook Trigger: WordPress core identifies the action and triggers the corresponding wp_ajax_ hook.
  3. Handler Execution: The handler calls the updateOptions() function (located in either class-canto.php or class-canto-settings.php).
  4. Vulnerable Sink: The updateOptions() function likely reads keys from $_POST and passes them directly to update_option() or delete_option() without checking if the current user is an administrator or verifying a CSRF nonce.
  5. Side Effect: If fbc_scheduled_update is passed or manipulated, the plugin may call wp_clear_scheduled_hook() or wp_schedule_event(), altering the site's cron behavior.

4. Nonce Acquisition Strategy

According to the vulnerability description, there is an absence of any nonce verification in the updateOptions() function. Therefore, no nonce is required to exploit this vulnerability. The attacker only needs a valid session cookie for a Subscriber-level user.

5. Exploitation Strategy

The goal is to modify a plugin setting (e.g., fbc_cron) from a Subscriber account.

  1. Login: Authenticate as a Subscriber user using browser_login.
  2. Draft Payload: Prepare a POST request to admin-ajax.php. Based on the description, we will target the fbc_cron option.
  3. Submit Request: Use the http_request tool to send the following payload:
    • URL: https://[TARGET]/wp-admin/admin-ajax.php
    • Method: POST
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Body: action=updateOptions&fbc_cron=0 (or action=fbc_updateOptions&fbc_cron=0)

6. Test Data Setup

  1. Create Subscriber: Use WP-CLI to create a test subscriber.
    wp user create attacker attacker@example.com --role=subscriber --user_pass=password123
    
  2. Initialize Options: Ensure the Canto plugin is installed and active, and set an initial value for the targeted option.
    wp option update fbc_cron 1
    

7. Expected Results

  • Response: The server should return a successful HTTP 200 OK response (likely returning 1 or a JSON success message if the plugin follows standard AJAX patterns).
  • Database Change: The WordPress option fbc_cron should be updated in the wp_options table from 1 to 0.
  • Access Control Failure: The request succeeds despite the user lacking manage_options capabilities.

8. Verification Steps

After the exploit attempt, verify the change using WP-CLI:

  1. Check Option Value:
    wp option get fbc_cron
    
    Success Criteria: The command returns 0.
  2. Check Cron Events (Optional): If fbc_scheduled_update was targeted:
    wp cron event list | grep fbc_scheduled_update
    
    Success Criteria: The event is either missing or modified as per the payload.

9. Alternative Approaches

If the initial payload fbc_cron=0 does not work, it might be because the updateOptions function expects an array or specific structure.

  • Alternative Payload 1 (Array-style): action=updateOptions&options[fbc_cron]=0
  • Alternative Payload 2 (JSON-style): action=updateOptions&data={"fbc_cron":"0"} (This is less common for standard wp_ajax but possible).
  • Alternative Payload 3 (Action specific): Try both updateOptions and fbc_updateOptions actions as they are registered in different files.
  • Testing Deletion: Try to clear an option by sending an empty value or a specific parameter that triggers deletion if the code supports it (e.g., fbc_cron=).
Research Findings
Static analysis — not yet PoC-verified

Summary

The Canto plugin for WordPress (versions 3.1.1 and earlier) fails to implement authorization checks and nonce verification in its option-updating logic. This allows authenticated users with subscriber-level privileges or higher to modify or delete plugin settings related to cron scheduling and manipulate scheduled WordPress cron events.

Vulnerable Code

// class-canto.php around line 231
add_action('wp_ajax_updateOptions', array($this, 'updateOptions'));

// class-canto-settings.php around line 76
add_action('wp_ajax_fbc_updateOptions', array($this, 'updateOptions'));

---

// Inferred logic for updateOptions() based on vulnerability description
public function updateOptions() {
    // Missing current_user_can('manage_options') check
    // Missing check_ajax_referer() nonce check

    if (isset($_POST['fbc_cron'])) {
        update_option('fbc_cron', sanitize_text_field($_POST['fbc_cron']));
    }
    // ... processes fbc_duplicates, fbc_schedule, fbc_cron_time_day, fbc_cron_time_hour, fbc_cron_start ...
    
    if (isset($_POST['fbc_scheduled_update'])) {
        // Logic to clear or reschedule cron events
    }
    wp_die();
}

Security Fix

--- a/includes/class-canto-settings.php
+++ b/includes/class-canto-settings.php
@@ -76,4 +76,9 @@
     public function updateOptions() {
+        if (!current_user_can('manage_options')) {
+            wp_send_json_error('Forbidden', 403);
+        }
+        check_ajax_referer('canto_settings_nonce', 'nonce');
+
         // ... rest of function logic
     }

Exploit Outline

The exploit targets the AJAX endpoints registered by the plugin. An attacker must first authenticate as a Subscriber-level user. They then send a POST request to /wp-admin/admin-ajax.php with the 'action' parameter set to 'updateOptions' or 'fbc_updateOptions'. The payload includes the specific setting keys they wish to modify, such as 'fbc_cron=0' to disable plugin synchronization or 'fbc_scheduled_update=1' to trigger/clear scheduled tasks. Because the function lacks capability checks and nonce validation, the server processes these updates as if they were requested by an administrator.

Check if your site is affected.

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