CVE-2026-39503

Easy Digital Downloads – eCommerce Payments and Subscriptions made easy <= 3.6.5 - Missing Authorization

mediumMissing Authorization
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
3.6.6
Patched in
11d
Time to patch

Description

The Easy Digital Downloads – eCommerce Payments and Subscriptions made easy plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 3.6.5. 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<=3.6.5
PublishedApril 20, 2026
Last updatedApril 30, 2026
Affected plugineasy-digital-downloads

What Changed in the Fix

Changes introduced in v3.6.6

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

This analysis focuses on a "Missing Authorization" vulnerability in Easy Digital Downloads (EDD) <= 3.6.5. Based on the provided CSS assets and known architecture of EDD, the vulnerability likely resides in an AJAX handler used for administrative tasks that was inadvertently exposed to unauthenticat…

Show full research plan

This analysis focuses on a "Missing Authorization" vulnerability in Easy Digital Downloads (EDD) <= 3.6.5. Based on the provided CSS assets and known architecture of EDD, the vulnerability likely resides in an AJAX handler used for administrative tasks that was inadvertently exposed to unauthenticated users via wp_ajax_nopriv_ hooks without a current_user_can() check.

The presence of assets/build/css/admin/emails.min.css referencing .edd-promo-notice__ajax and #edd-admin-notice-emails strongly suggests the vulnerability involves the unauthorized dismissal of administrative or promotional notices.

1. Vulnerability Summary

The Easy Digital Downloads plugin uses AJAX handlers to manage admin notices and promotional content. In version 3.6.5, specific handlers (likely edd_dismiss_notice) are registered using wp_ajax_nopriv_, making them accessible to unauthenticated visitors. The function fails to perform a capability check (e.g., current_user_can( 'manage_shop_settings' )), allowing any user to dismiss important administrative alerts or promotional notices for all administrators.

2. Attack Vector Analysis

  • Endpoint: /wp-admin/admin-ajax.php
  • Action: edd_dismiss_notice (inferred from .edd-promo-notice__ajax in CSS)
  • HTTP Method: POST
  • Authentication: None required (unauthenticated)
  • Preconditions: The plugin must have an active notice that is targetable (e.g., the "Emails" promo notice).

3. Code Flow (Inferred)

  1. Hook Registration: The plugin registers the action:
    add_action( 'wp_ajax_nopriv_edd_dismiss_notice', 'edd_ajax_dismiss_notice' );
  2. Entry Point: admin-ajax.php receives a POST request with action=edd_dismiss_notice.
  3. Vulnerable Function: edd_ajax_dismiss_notice() is called.
  4. Missing Check: The function likely checks a nonce but fails to verify if the user has manage_options or manage_shop_settings capabilities.
  5. Sink: The function calls update_option( 'edd_dismissed_notices', ... ) or set_user_meta(...), modifying the global or user-specific state of dismissed notices.

4. Nonce Acquisition Strategy

EDD typically localizes its administrative AJAX data. Even for unauthenticated users, the nonce might be leaked if the plugin enqueues scripts on the frontend (e.g., for checkout or download management).

  1. Identify the Script: Look for edd_admin_vars or edd_scripts_vars in the page source.
  2. Check Frontend: Navigate to the homepage or a "Downloads" page.
  3. Extraction:
    • browser_navigate("http://localhost:8080/")
    • browser_eval("window.edd_scripts_vars?.dismiss_notice_nonce") (inferred key)
    • Note: If the action is specifically for the Email promo, look for a variable named edd_emails_vars or similar.

5. Exploitation Strategy

The goal is to unauthentically dismiss the "Emails" promotional notice (referenced in emails.min.css).

Step 1: Discover target notice ID
Common EDD notice IDs include:

  • edd_emails_promo_notice
  • edd_api_notice
  • edd_connect_notice

Step 2: Construct the Exploit Request

  • URL: http://localhost:8080/wp-admin/admin-ajax.php
  • Headers: Content-Type: application/x-www-form-urlencoded
  • Body:
    action=edd_dismiss_notice&notice_id=edd_emails_promo_notice&nonce=[EXTRACTED_NONCE]
    

Step 3: Alternative Payload (Generic Dismissal)
If a specific nonce is not required for nopriv (or if it's checked loosely), try:

action=edd_dismiss_notice&notice_id=edd_emails_promo_notice

6. Test Data Setup

To ensure the exploit is testable, the "Emails" notice should be "active" in the environment.

  1. Activate EDD: Ensure the plugin is active.
  2. Clear Dismissed Notices: Reset the option to ensure the notice would normally be visible.
    wp option delete edd_dismissed_notices
    

7. Expected Results

  • Response: The server should return 1, success, or a JSON object like {"success":true}.
  • State Change: The database option edd_dismissed_notices will be updated to include the targeted notice_id.

8. Verification Steps

After sending the HTTP request, verify the dismissal using WP-CLI:

# Check if the notice is now in the dismissed list
wp option get edd_dismissed_notices

The output should be a serialized array containing edd_emails_promo_notice.

9. Alternative Approaches

If edd_dismiss_notice is not the vulnerable action, use grep to find all nopriv actions that perform "update" or "dismiss" logic:

  1. grep -r "wp_ajax_nopriv_" wp-content/plugins/easy-digital-downloads/
  2. Search for any function calls that update options or meta:
    grep -r "update_option" wp-content/plugins/easy-digital-downloads/includes/admin/
  3. Look for "Stats Recount" functions: edd_recount_stats. In some versions, unauthenticated users could trigger a recount of shop stats, leading to potential DoS or unauthorized data processing:
    • Action: edd-recount-stats
    • Request: GET /wp-admin/index.php?edd-action=recount_stats&type=orders (check if edd-action is handled in init without auth).

Check if your site is affected.

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