[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$feTn2arfQih384fDNPB5zu0XJwcrdeLGpcyYdK5KsNNE":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":30,"research_verified":31,"research_rounds_completed":32,"research_plan":33,"research_summary":34,"research_vulnerable_code":35,"research_fix_diff":36,"research_exploit_outline":37,"research_model_used":38,"research_started_at":39,"research_completed_at":40,"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":31,"poc_model_used":9,"poc_verification_depth":9,"poc_exploit_code_gated":31,"source_links":41},"CVE-2026-2917","happy-addons-for-elementor-insecure-direct-object-reference-to-authenticated-contributor-post-duplication-via-postid-par","Happy Addons for Elementor \u003C= 3.21.0 - Insecure Direct Object Reference to Authenticated (Contributor+) Post Duplication via 'post_id' Parameter","The Happy Addons for Elementor plugin for WordPress is vulnerable to Insecure Direct Object Reference in all versions up to, and including, 3.21.0 via the `ha_duplicate_thing` admin action handler. This is due to the `can_clone()` method only checking `current_user_can('edit_posts')` (a general capability) without performing object-level authorization such as `current_user_can('edit_post', $post_id)`, and the nonce being tied to the generic action name `ha_duplicate_thing` rather than to a specific post ID. This makes it possible for authenticated attackers, with Contributor-level access and above, to clone any published post, page, or custom post type by obtaining a valid clone nonce from their own posts and changing the `post_id` parameter to target other users' content. The clone operation copies the full post content, all post metadata (including potentially sensitive widget configurations and API tokens), and taxonomies into a new draft owned by the attacker.","happy-elementor-addons",null,"\u003C=3.21.0","3.21.1","medium",5.4,"CVSS:3.1\u002FAV:N\u002FAC:L\u002FPR:L\u002FUI:N\u002FS:U\u002FC:L\u002FI:L\u002FA:N","Authorization Bypass Through User-Controlled Key","2026-03-10 19:07:37","2026-03-11 07:36:25",[19],"https:\u002F\u002Fwww.wordfence.com\u002Fthreat-intel\u002Fvulnerabilities\u002Fid\u002F9234b1ce-032f-487d-b60a-f80c78373238?source=api-prod",1,[22,23,24,25,26,27,28,29],"assets\u002Fadmin\u002Fjs\u002Feditor.js","assets\u002Fadmin\u002Fjs\u002Feditor.min.js","changelog.txt","classes\u002Fclone-handler.php","classes\u002Fcondition-manager.php","classes\u002Ftheme-builder.php","plugin.php","readme.txt","researched",false,3,"# Exploitation Research Plan: CVE-2026-2917\n\n## 1. Vulnerability Summary\nThe **Happy Addons for Elementor** plugin (up to 3.21.0) contains an **Insecure Direct Object Reference (IDOR)** vulnerability in its post duplication feature. The vulnerability exists within the `Happy_Addons\\Elementor\\Classes\\Clone_Handler::duplicate_thing` method. \n\nWhile the plugin checks if the user has the general `edit_posts` capability (possessed by Contributors), it fails to perform object-level authorization (i.e., checking if the user is allowed to edit the specific `post_id` being cloned). Furthermore, the WordPress nonce used to protect the action is tied only to the static action string `ha_duplicate_thing` rather than being unique per post. This allows a Contributor-level user to obtain a valid nonce from one of their own posts and use it to clone any published post or page on the site, effectively gaining access to its full content and metadata.\n\n## 2. Attack Vector Analysis\n- **Endpoint:** `\u002Fwp-admin\u002Fadmin.php` (Admin Action)\n- **Action:** `ha_duplicate_thing`\n- **Parameters:**\n    - `action`: `ha_duplicate_thing`\n    - `post_id`: The ID of the target post to clone (IDOR target).\n    - `_wpnonce`: A valid nonce for the `ha_duplicate_thing` action.\n- **Authentication:** Authenticated (Contributor or higher). Contributors have the `edit_posts` capability required by the `can_clone()` check.\n- **Preconditions:** The target post must have a status other than 'private' or 'draft' (unless the attacker is the author), as per the check in `duplicate_thing()`. Published posts are the primary targets.\n\n## 3. Code Flow\n1. **Entry Point:** A request is sent to `admin.php?action=ha_duplicate_thing`.\n2. **Hook Registration:** The plugin registers the action handler (likely via `admin_action_ha_duplicate_thing`).\n3. **Authorization Check (`classes\u002Fclone-handler.php:24`):**\n   ```php\n   public static function can_clone() {\n       return current_user_can( 'edit_posts' ); \u002F\u002F Contributor+ passes this\n   }\n   ```\n4. **Parameter Extraction (`classes\u002Fclone-handler.php:73-75`):**\n   ```php\n   $nonce = isset( $_GET['_wpnonce'] ) ? $_GET['_wpnonce'] : '';\n   $post_id = isset( $_GET['post_id'] ) ? absint( $_GET['post_id'] ) : 0;\n   ```\n5. **Nonce Verification (`classes\u002Fclone-handler.php:78`):**\n   ```php\n   if ( ! wp_verify_nonce( $nonce, self::ACTION ) ) { \u002F\u002F self::ACTION = 'ha_duplicate_thing'\n       return;\n   }\n   ```\n6. **Weak Ownership Check (`classes\u002Fclone-handler.php:84-90`):**\n   ```php\n   if ( ('private' == $post_status || 'draft' == $post_status) && ! $same_author ) {\n       wp_die( __( 'Sorry, you are not allowed to clone this item.' ) );\n   }\n   ```\n   *Crucially, this check is skipped for 'published' posts.*\n7. **Sink (`classes\u002Fclone-handler.php:97`):**\n   ```php\n   $duplicated_post_id = self::duplicate_post( $post );\n   ```\n   The `duplicate_post` method creates a new draft where `post_author` is set to the current user (the attacker).\n\n## 4. Nonce Acquisition Strategy\nThe nonce is for the action `ha_duplicate_thing`. Since it is not post-specific, an attacker can extract it from the WordPress admin interface where they have permission to see the \"Happy Clone\" link.\n\n1. **Requirement:** The attacker must have at least one post they are allowed to edit (e.g., a post they created).\n2. **Steps:**\n   - Log in as a Contributor.\n   - Create a post: `wp post create --post_type=post --post_status=publish --post_title=\"Attacker Post\" --post_author=[CONTRIBUTOR_ID]`.\n   - Navigate to the \"Posts\" list: `\u002Fwp-admin\u002Fedit.php`.\n   - The \"Happy Clone\" link is added via `Clone_Handler::add_row_actions` (Line 46).\n   - Use `browser_navigate` to `\u002Fwp-admin\u002Fedit.php`.\n   - Use `browser_eval` to find the \"Happy Clone\" link associated with the attacker's post and extract the `_wpnonce` parameter from its URL.\n\n## 5. Exploitation Strategy\n1. **Setup:**\n   - Create an Administrator user.\n   - Create a Contributor user.\n   - As Administrator, create a \"Sensitive Post\" (ID `X`) with content and perhaps some custom metadata (simulating sensitive widget data).\n2. **Nonce Extraction:**\n   - As Contributor, create a dummy post (ID `Y`).\n   - Navigate to `\u002Fwp-admin\u002Fedit.php`.\n   - Extract the `_wpnonce` from the \"Happy Clone\" link for post `Y`.\n3. **Trigger IDOR:**\n   - Construct the exploit URL: `\u002Fwp-admin\u002Fadmin.php?action=ha_duplicate_thing&post_id=[X]&_wpnonce=[EXTRACTED_NONCE]`.\n   - Send the request using `http_request`.\n4. **Validation:**\n   - The response should be a redirect (302) to `edit.php?post_type=post`.\n   - Check the post list for a new post titled \"Sensitive Post - [Cloned #[X]]\".\n   - Verify the author of the new post is the Contributor.\n\n## 6. Test Data Setup\n- **Target Post (Admin):**\n  - Title: `Secret Admin Blueprint`\n  - Content: `This is restricted content with internal API keys: {key: \"12345\"}`\n  - Status: `publish`\n- **Attacker Post (Contributor):**\n  - Title: `My Trash Post`\n  - Status: `publish`\n\n## 7. Expected Results\n- The HTTP request to clone the Admin post (ID `X`) returns a 302 redirect.\n- A new post is created in the database.\n- The new post's `post_content` is identical to the Admin post.\n- The new post's `post_author` is the ID of the Contributor.\n- The new post's `post_status` is `draft`.\n\n## 8. Verification Steps\n1. **List Posts via CLI:**\n   `wp post list --post_author=[CONTRIBUTOR_ID] --post_status=draft --fields=ID,post_title,post_content`\n2. **Check for Cloned Content:**\n   Compare the `post_content` of the new draft with the original Admin post content.\n3. **Verify Metadata:**\n   `wp post meta list [NEW_DRAFT_ID]`\n   Check if metadata from the Admin post was successfully copied.\n\n## 9. Alternative Approaches\n- **Custom Post Types:** If the site uses Elementor Templates (CPT `elementor_library`), try cloning a Template ID. These often contain complex JSON in `_elementor_data` metadata which is copied by `duplicate_meta_entries` (Line 183).\n- **Ref Parameter:** Test the `ref=editor` parameter to see if the plugin redirects the Contributor directly into the Elementor editor for the stolen content:\n  `\u002Fwp-admin\u002Fadmin.php?action=ha_duplicate_thing&post_id=[X]&_wpnonce=[NONCE]&ref=editor`","The Happy Addons for Elementor plugin is vulnerable to an Insecure Direct Object Reference (IDOR) that allows Contributor-level users and above to clone any published post, page, or custom post type. This vulnerability exists because the plugin checks for general 'edit_posts' capabilities rather than object-specific permissions, and utilizes a generic nonce that is not tied to a specific post ID.","\u002F\u002F classes\u002Fclone-handler.php:18\npublic static function can_clone() {\n\treturn current_user_can( 'edit_posts' );\n}\n\n---\n\n\u002F\u002F classes\u002Fclone-handler.php:73\n$nonce = isset( $_GET['_wpnonce'] ) ? $_GET['_wpnonce'] : '';\n$post_id = isset( $_GET['post_id'] ) ? absint( $_GET['post_id'] ) : 0;\n$ref = isset( $_GET['ref'] ) ? sanitize_text_field($_GET['ref']) : '';\n\nif ( ! wp_verify_nonce( $nonce, self::ACTION ) ) {\n\treturn;\n}\n\n$post_status = get_post_status ( $post_id );\n$same_author = self::is_the_same_author( $post_id );\n\nif ( ('private' == $post_status || 'draft' == $post_status) && ! $same_author ) {\n\twp_die( __( 'Sorry, you are not allowed to clone this item.' ) );\n}","--- a\u002Fclasses\u002Fclone-handler.php\n+++ b\u002Fclasses\u002Fclone-handler.php\n@@ -81,6 +81,10 @@\n \t\t\treturn;\n \t\t}\n \n+\t\tif ( ! current_user_can( 'edit_post', $post_id ) ) {\n+\t\t\twp_die( __( 'Sorry, you are not allowed to clone this item.' ) );\n+\t\t}\n+\n \t\t$post_status = get_post_status ( $post_id );\n \t\t$same_author = self::is_the_same_author( $post_id );","1. Authenticate to the WordPress site as a user with at least Contributor-level privileges.\n2. Create or navigate to a post owned by the attacker to view the 'Happy Clone' link in the admin dashboard.\n3. Extract the `_wpnonce` value from the 'Happy Clone' link; this nonce is valid for the `ha_duplicate_thing` action across all posts because it is not post-specific.\n4. Identify the `post_id` of the target content (e.g., a published post or page authored by an Administrator).\n5. Construct an exploit URL by targeting the `admin_action_ha_duplicate_thing` endpoint: `\u002Fwp-admin\u002Fadmin.php?action=ha_duplicate_thing&post_id=[TARGET_ID]&_wpnonce=[EXTRACTED_NONCE]`.\n6. Submit the request. The plugin will create a new draft containing the full content and metadata of the target post, with the attacker as the new owner.","gemini-3-flash-preview","2026-04-18 04:29:35","2026-04-18 04:29:56",{"type":42,"vulnerable_version":43,"fixed_version":11,"vulnerable_browse":44,"vulnerable_zip":45,"fixed_browse":46,"fixed_zip":47,"all_tags":48},"plugin","3.21.0","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fhappy-elementor-addons\u002Ftags\u002F3.21.0","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fhappy-elementor-addons.3.21.0.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fhappy-elementor-addons\u002Ftags\u002F3.21.1","https:\u002F\u002Fdownloads.wordpress.org\u002Fplugin\u002Fhappy-elementor-addons.3.21.1.zip","https:\u002F\u002Fplugins.trac.wordpress.org\u002Fbrowser\u002Fhappy-elementor-addons\u002Ftags"]