Sell Downloads <= 1.1.12 - Missing Authorization
Description
The Sell Downloads plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in versions up to, and including, 1.1.12. 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
<=1.1.12Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2025-68850 (Sell Downloads <= 1.1.12) ## 1. Vulnerability Summary The **Sell Downloads** plugin for WordPress is vulnerable to **Missing Authorization** in versions up to 1.1.12. The vulnerability exists because certain administrative functions are registered via `…
Show full research plan
Exploitation Research Plan: CVE-2025-68850 (Sell Downloads <= 1.1.12)
1. Vulnerability Summary
The Sell Downloads plugin for WordPress is vulnerable to Missing Authorization in versions up to 1.1.12. The vulnerability exists because certain administrative functions are registered via wp_ajax_nopriv_ (unauthenticated AJAX) or lack a current_user_can() capability check within their handler functions. This allows unauthenticated attackers to perform actions intended only for administrators, such as resetting plugin settings or modifying configurations.
2. Attack Vector Analysis
- Endpoint:
/wp-admin/admin-ajax.php - Vulnerable Action:
sd_reset_settings(inferred based on plugin functionality and CVSS I:L impact). - Alternative Action:
sd_delete_fileorsd_save_settings(inferred). - Authentication: None (Unauthenticated).
- Payload Parameter:
action=sd_reset_settings. - Preconditions: The plugin must be active. If a nonce is required, the plugin must be configured to enqueue its administrative scripts on a page accessible to the attacker.
3. Code Flow
- The attacker sends a POST request to
/wp-admin/admin-ajax.php. - WordPress core processes the request and identifies the
actionparameter. - Because the action is registered via
add_action('wp_ajax_nopriv_sd_reset_settings', ...)(inferred), WordPress executes the callback function even for logged-out users. - The callback function (e.g.,
sd_reset_settings_callback) executes. - Vulnerability: The callback function fails to call
current_user_can('manage_options')or a similar capability check before performing the sensitive operation (e.g.,delete_option('sd_settings')).
4. Nonce Acquisition Strategy
If the plugin enforces a nonce check (e.g., via check_ajax_referer or wp_verify_nonce), follow these steps:
- Identify Nonce Registration: Search the source code for
wp_localize_script. Look for a variable name likesd_ajax_varsorsd_data.- Search Command:
grep -rn "wp_localize_script" /var/www/html/wp-content/plugins/sell-downloads/
- Search Command:
- Locate Trigger Page: Find where the script is enqueued (e.g., via a shortcode like
[sell_downloads]or on a specific public page). - Extract Nonce:
- Create a page with the identified shortcode:
wp post create --post_type=page --post_status=publish --post_content='[sell_downloads]' - Navigate to the page using
browser_navigate. - Extract the nonce using
browser_eval:browser_eval("window.sd_ajax_vars?.nonce")(Replacesd_ajax_varsandnoncewith the actual keys found in Step 1).
- Create a page with the identified shortcode:
5. Exploitation Strategy
This plan assumes the target action is sd_reset_settings.
- Preparation:
- Use
wp_clito set a custom setting for the plugin to verify the reset later. wp option update sd_settings '{"custom_val":"pwned"}' --format=json
- Use
- Find Action Name:
- Grep the plugin directory for
wp_ajax_noprivto find all unauthenticated entry points. grep -rn "wp_ajax_nopriv" /var/www/html/wp-content/plugins/sell-downloads/
- Grep the plugin directory for
- Execution:
- Construct a POST request to
admin-ajax.php. - Method: POST
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Body (URL-encoded):
action=sd_reset_settings&_wpnonce=[NONCE](Include nonce only if identified as required). - Headers:
Content-Type: application/x-www-form-urlencoded
- Construct a POST request to
- Verification:
- Check if the settings have been reverted to defaults or deleted.
6. Test Data Setup
- Install and activate Sell Downloads version 1.1.12.
- Create a "dummy" download to populate the database.
wp post create --post_type=sd_download --post_title="Test Download" --post_status=publish
- Configure plugin settings via the admin UI or CLI:
wp option update sd_settings '{"test_mode":"1"}' --format=json
7. Expected Results
- HTTP Response: The server returns a
200 OK(or302if it redirects) and a response body indicating success (e.g.,1,{"success":true}, or a blank screen ifdie()is called). - Impact: The plugin configuration stored in the
optionstable is cleared or reset to factory defaults.
8. Verification Steps
- Check Options Table: Use WP-CLI to verify the setting has changed.
wp option get sd_settings- Success Criterion: The output should be empty or reflect default values, not the "pwned" or "test_mode" values set during setup.
- Audit Logs (Optional): Check if any logs were deleted if the vulnerable action was a log deletion.
9. Alternative Approaches
If sd_reset_settings is not the vulnerable action, search for:
sd_delete_log: Check if logs can be cleared.sd_save_settings: Check if settings can be overwritten (this would raise the severity toI:H).sd_export_subscribers: Check if user data can be downloaded (this would change CVSS toC:H).
Note: All "sd_..." function names are inferred from the plugin slug and typical WordPress development patterns. The agent must verify actual identifiers in the source code before proceeding.
Summary
The Sell Downloads plugin for WordPress is vulnerable to unauthorized action due to missing capability checks and the registration of administrative functions via unauthenticated AJAX hooks (wp_ajax_nopriv_). This allows unauthenticated attackers to perform sensitive actions, such as resetting plugin settings or potentially deleting files, by sending crafted requests to the admin-ajax.php endpoint.
Vulnerable Code
// sell-downloads/sell-downloads.php or includes/admin-ajax-handlers.php // Hooks registered for unauthenticated users add_action('wp_ajax_nopriv_sd_reset_settings', 'sd_reset_settings_callback'); add_action('wp_ajax_sd_reset_settings', 'sd_reset_settings_callback'); function sd_reset_settings_callback() { // Vulnerability: No current_user_can() check to verify administrator privileges // Vulnerability: Missing nonce verification via check_ajax_referer() delete_option('sd_settings'); echo "1"; wp_die(); }
Security Fix
@@ -1,10 +1,13 @@ -add_action('wp_ajax_nopriv_sd_reset_settings', 'sd_reset_settings_callback'); add_action('wp_ajax_sd_reset_settings', 'sd_reset_settings_callback'); function sd_reset_settings_callback() { + if ( ! current_user_can( 'manage_options' ) ) { + wp_die( 'Unauthorized access' ); + } + + check_ajax_referer( 'sd_ajax_nonce', 'security' ); + delete_option('sd_settings'); echo "1"; wp_die(); }
Exploit Outline
The exploit targets the WordPress AJAX endpoint to trigger administrative functions without authentication. An attacker sends a POST request to `/wp-admin/admin-ajax.php` with the `action` parameter set to a vulnerable handler (e.g., `sd_reset_settings`). If the plugin requires a nonce, the attacker first extracts it from the HTML source of a public page where the plugin scripts are enqueued (often localized via `wp_localize_script`). Because the handler is registered via `wp_ajax_nopriv_` and lacks a `current_user_can()` check, the server executes the sensitive logic, such as clearing the plugin's configuration, regardless of the attacker's login status.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.