• Resolved Bojan Denić

    (@evilmc)


    I was able to reproduce and isolate the manual purge failure in version 2.4.4.

    Symptom

    Manual cache purge from the WordPress admin bar or plugin settings page fails with:

    The Hestia Nginx Cache could not be purged!

    The AJAX response from /wp-admin/admin-ajax.php is HTTP 200, but contains:

    {
      "success": false,
      "data": {
        "message": "The Hestia Nginx Cache could not be purged!",
        "error": "Invalid nonce."
      }
    }
    

    Hestia API itself is working

    I verified the Hestia side independently.

    v-purge-nginx-cache succeeds with exit code 0.

    The configured access key also passes v-check-access-key.

    After verifying the API credentials, I called the plugin purge method directly through WP-CLI:

    Hestia_Nginx_Cache::get_instance()->purge(true);
    

    Result:

    HTTP CODE: 200
    HESTIA EXIT CODE: 0
    

    Therefore the Hestia API request and the plugin’s actual purge method work correctly. The failure only occurs through the browser AJAX manual-purge path.

    PHP configuration was also checked:

    PHP 8.4.24
    request_order: GP
    variables_order: GPCS
    

    The AJAX request is not being cached and reaches WordPress normally.

    Regression between 2.4.3 and 2.4.4

    The 2.4.4 “Fix all Plugin Check errors” change modified the nonce request field in assets/js/admin.js from:

    wp_nonce: nonce.textContent,
    

    to:

    _wpnonce: nonce.textContent,
    

    and changed the PHP validation in includes/admin.php from the previous POST-based handling to:

    $query_arg = '_wpnonce';
    $valid_nonce = isset($_REQUEST[$query_arg])
        ? wp_verify_nonce(
            $_REQUEST[$query_arg],
            'hestia-nginx-cache-purge-wp-nonce'
        )
        : false;
    

    In my environment this consistently results in Invalid nonce. for the manual AJAX purge, while the direct purge method succeeds.

    Patch tested

    I prepared a minimal compatibility patch.

    The JavaScript request field is restored to the 2.4.3 name:

    wp_nonce: nonce.textContent,
    

    The PHP handler explicitly reads the POST value, unslashes and sanitizes it, while also accepting the 2.4.4 _wpnonce field as a fallback for cached JavaScript:

    $nonce = '';
    
    if (isset($_POST['wp_nonce'])) {
        $nonce = sanitize_text_field(wp_unslash($_POST['wp_nonce']));
    } elseif (isset($_POST['_wpnonce'])) {
        $nonce = sanitize_text_field(wp_unslash($_POST['_wpnonce']));
    }
    
    $valid_nonce = $nonce !== ''
        ? wp_verify_nonce(
            $nonce,
            'hestia-nginx-cache-purge-wp-nonce'
        )
        : false;
    

    This does not remove or bypass nonce/CSRF validation. It only restores the previously working POST field and handles the input explicitly in a Plugin Check-friendly way.

    I also bumped the patched build to 2.4.4.1 so the plugin’s versioned admin.js URL changes and browsers do not keep the 2.4.4 JavaScript cached.

    I can provide the complete patch/diff if useful.

    Note: this finding specifically isolates the manual AJAX purge nonce failure. Automatic purge does not go through this AJAX nonce path and should be investigated separately if it is also failing.

    Download “2.4.4.1”: https://we.tl/t-a1k1XjxH1gQTkccT

    • This topic was modified 2 weeks, 4 days ago by Bojan Denić.

You must be logged in to reply to this topic.