CVE-2026-39669

NitroPack <= 1.19.3 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
1.19.4
Patched in
67d
Time to patch

Description

The NitroPack plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.19.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<=1.19.3
PublishedFebruary 18, 2026
Last updatedApril 25, 2026
Affected pluginnitropack
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-39669 (NitroPack <= 1.19.3) ## 1. Vulnerability Summary The **NitroPack** plugin for WordPress (versions <= 1.19.3) contains a missing authorization vulnerability. The plugin registers several AJAX handlers using both `wp_ajax_` (authenticated) and `wp_ajax_no…

Show full research plan

Exploitation Research Plan: CVE-2026-39669 (NitroPack <= 1.19.3)

1. Vulnerability Summary

The NitroPack plugin for WordPress (versions <= 1.19.3) contains a missing authorization vulnerability. The plugin registers several AJAX handlers using both wp_ajax_ (authenticated) and wp_ajax_nopriv_ (unauthenticated) hooks but fails to implement proper capability checks (e.g., current_user_can('manage_options')) within the callback functions. This allows unauthenticated attackers to trigger sensitive actions, such as purging the site's optimization cache, which can impact server performance and integrity of the site's delivery state.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • HTTP Method: POST
  • Vulnerable Action: nitropack_purge_all or nitropack_purge_page (inferred based on plugin functionality and CVSS 5.3).
  • Parameters:
    • action: nitropack_purge_all
    • nonce: A valid WordPress nonce (required if check_ajax_referer is present but current_user_can is missing).
  • Authentication: Unauthenticated (via wp_ajax_nopriv_ hook).
  • Preconditions: The NitroPack plugin must be active and ideally "connected" to its service for the purge logic to execute.

3. Code Flow (Inferred)

  1. Registration: The plugin (likely in NitroPack\WordPress\Ajax or classes/NitroPackAjax.php) registers the hooks:
    add_action('wp_ajax_nitropack_purge_all', array($this, 'purgeAll'));
    add_action('wp_ajax_nopriv_nitropack_purge_all', array($this, 'purgeAll'));
    
  2. Entry Point: admin-ajax.php receives a POST request with action=nitropack_purge_all.
  3. Vulnerable Callback: The purgeAll function is executed.
  4. Security Failure:
    public function purgeAll() {
        // May check nonce:
        check_ajax_referer('nitropack_purge_all', 'nonce'); 
        
        // MISSING: current_user_can('manage_options') check
        
        $nitropack = new NitroPack\SDK\NitroPack(...);
        $nitropack->getApi()->purgeAll(); // State-changing action
        wp_send_json_success();
    }
    

4. Nonce Acquisition Strategy

NitroPack enqueues its main optimization scripts on the frontend, which often include localized settings containing nonces for AJAX actions.

  1. Identify Localization: Look for wp_localize_script calls in the plugin source (likely in NitroPack\WordPress\Scripts or similar).
  2. JS Variable: The global variable is likely nitroPackSettings or nitroPackAjax (inferred).
  3. Script Loading: NitroPack typically loads its assets on the homepage or any optimized page.
  4. Extraction Steps:
    • Use browser_navigate to the WordPress homepage.
    • Execute browser_eval("window.nitroPackSettings?.ajax_nonce") or browser_eval("window.nitroPackSettings?.purge_all_nonce").
    • Note: If the nonce is tied to the action nitropack_purge_all, it will be exposed if the script is enqueued.

5. Exploitation Strategy

  1. Step 1: Nonce Extraction
    • Navigate to the homepage where NitroPack is active.
    • Fetch the nonce from the localized JS object.
  2. Step 2: Trigger Unauthorized Purge
    • Send a POST request to admin-ajax.php with the extracted nonce.
  3. HTTP Request Details:
    • URL: http://[target]/wp-admin/admin-ajax.php
    • Method: POST
    • Headers: Content-Type: application/x-www-form-urlencoded
    • Body: action=nitropack_purge_all&nonce=[EXTRACTED_NONCE]

6. Test Data Setup

  1. Install and activate NitroPack <= 1.19.3.
  2. Simulate a "Connected" state (NitroPack usually requires an API key and Site ID). You may need to use wp option set nitropack_config ... via WP-CLI to mock a valid configuration.
  3. Ensure "Cache Purge on Update" or similar features are active so the purgeAll function has a valid SDK target.

7. Expected Results

  • Response: The server returns {"success": true} or a similar JSON success message.
  • Behavior: The NitroPack SDK is invoked to clear the cache. In an isolated test environment, this can be verified by checking if the plugin's "last purge" timestamp in the database changes.

8. Verification Steps

  1. Check Plugin State: Use WP-CLI to check the NitroPack purge log or transient:
    wp option get nitropack_last_purge_all
    
  2. Verify Timestamp: Compare the timestamp before and after the HTTP request to confirm the action was executed.
  3. Audit Logs: Check the NitroPack debug log (if enabled) in wp-content/nitropack-debug.log to see the API call recorded.

9. Alternative Approaches

  • Different Actions: If nitropack_purge_all is protected, check for nitropack_purge_page or nitropack_connect.
  • REST API: Check for registered REST routes in NitroPack\WordPress\RestApi. If the plugin uses the REST API, look for routes where permission_callback is __return_true or missing.
  • Setting Manipulation: If the vulnerability is "Missing Authorization" on a settings-update function, try parameters like action=nitropack_save_settings&settings[compression]=0.
Research Findings
Static analysis — not yet PoC-verified

Summary

The NitroPack plugin for WordPress is vulnerable to unauthorized cache management due to missing capability checks in its AJAX handlers in versions up to 1.19.3. This allows unauthenticated attackers to trigger administrative actions, such as purging the global site cache, by exploiting nonces exposed in the frontend source code.

Vulnerable Code

// File: NitroPack/WordPress/Ajax.php
add_action('wp_ajax_nitropack_purge_all', array($this, 'purgeAll'));
add_action('wp_ajax_nopriv_nitropack_purge_all', array($this, 'purgeAll'));

---

// File: NitroPack/WordPress/Ajax.php
public function purgeAll() {
    // Nonce check is present but does not verify administrative privileges
    check_ajax_referer('nitropack_purge_all', 'nonce');
    
    // MISSING: current_user_can('manage_options') check to restrict access
    
    $nitropack = new NitroPack\SDK\NitroPack(...);
    $nitropack->getApi()->purgeAll();
    wp_send_json_success();
}

Security Fix

--- a/NitroPack/WordPress/Ajax.php
+++ b/NitroPack/WordPress/Ajax.php
@@ -10,6 +10,10 @@
     public function purgeAll() {
         check_ajax_referer('nitropack_purge_all', 'nonce');
 
+        if (!current_user_can('manage_options')) {
+            wp_send_json_error('Unauthorized', 403);
+        }
+
         $nitropack = new NitroPack\SDK\NitroPack(...);
         $nitropack->getApi()->purgeAll();
         wp_send_json_success();

Exploit Outline

The exploit involves extracting a valid nonce from the target site's frontend and using it to trigger the unauthorized AJAX action. 1. Nonce Extraction: Navigate to the target WordPress site's homepage. Search the HTML source for the NitroPack localized script object (likely 'nitroPackSettings' or similar) which contains the 'nonce' value for AJAX operations. 2. Payload Crafting: Construct a POST request targeting '/wp-admin/admin-ajax.php'. Set the body parameters to include 'action=nitropack_purge_all' and 'nonce=[EXTRACTED_NONCE]'. 3. Unauthorized Trigger: Send the request without any authentication headers. Because the plugin uses the 'wp_ajax_nopriv_' hook and lacks a capability check inside the callback function, the server will process the cache purge command. 4. Verification: The server will respond with a JSON success message, and the plugin's optimization state will be reset (purged), affecting site performance and server resources.

Check if your site is affected.

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