GetGenie – AI Content Writer with Keyword Research & SEO Tracking Tools <= 4.3.0 - Missing Authorization to Authenticated (Author+) Arbitrary Post Deletion
Description
The GetGenie plugin for WordPress is vulnerable to authorization bypass in all versions up to, and including, 4.3.0. This is due to the plugin not properly verifying that a user is authorized to delete a specific post. This makes it possible for authenticated attackers, with Author-level access and above, to delete any post on the WordPress site, including posts authored by other users.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:L/A:NTechnical Details
<=4.3.0Source Code
WordPress.org SVNThis research plan outlines the steps to verify and exploit CVE-2026-1003, a missing authorization vulnerability in the GetGenie plugin that allows users with Author-level permissions to delete any post on the site. ### 1. Vulnerability Summary The GetGenie plugin (<= 4.3.0) fails to implement prop…
Show full research plan
This research plan outlines the steps to verify and exploit CVE-2026-1003, a missing authorization vulnerability in the GetGenie plugin that allows users with Author-level permissions to delete any post on the site.
1. Vulnerability Summary
The GetGenie plugin (<= 4.3.0) fails to implement proper ownership or capability checks in one of its AJAX/REST handlers responsible for deleting content (likely AI generation history or templates). While the handler may check if a user is logged in or has a baseline capability (like edit_posts), it does not verify if the authenticated user has the permission to delete the specific post_id provided in the request. This allows an Author to delete posts created by Administrators or other users.
2. Attack Vector Analysis
- Endpoint:
wp-admin/admin-ajax.php - Action:
getgenie_delete_history(inferred based on plugin functionality) orgetgenie_remove_item. - Vulnerable Parameter:
post_idorid. - Authentication: Authenticated, Author-level access (
PR:L). - Preconditions: The attacker must be logged in as a user with at least the
Authorrole. The ID of the target post (e.g., a high-value page or post created by the admin) must be known.
3. Code Flow (Inferred)
- The plugin registers an AJAX handler for a delete action via
add_action( 'wp_ajax_getgenie_delete_history', ... ). - The handler function retrieves the
post_idfrom$_POSTor$_GET. - The handler performs a nonce check (e.g.,
check_ajax_referer). - The handler may check if the user can
edit_posts(which Authors can). - Vulnerability: The code proceeds to call
wp_delete_post( $post_id, true )orwp_trash_post( $post_id )without callingcurrent_user_can( 'delete_post', $post_id ). - The post is deleted regardless of its author.
4. Nonce Acquisition Strategy
The GetGenie plugin typically localizes its configuration and nonces for the admin dashboard.
- Identify the Script: Look for
wp_localize_scriptcalls in the plugin source that target the "History" or "AI Content" pages. - JS Variable: Likely names include
getgenie_admin,getgenie_history, orgetgenie_config. - Target Page: The GetGenie history page (e.g.,
/wp-admin/admin.php?page=getgenie-history).
Acquisition Plan:
- Navigate to the GetGenie History page as an Author.
- Use
browser_evalto extract the nonce:// Inferred localization key - replace with actual key found during discovery window.getgenie_history?.nonce || window.getgenie_admin?.nonce
5. Exploitation Strategy
Step 1: Target Identification
Identify a post ID created by the Administrator (e.g., Post ID 1).
Step 2: Nonce Retrieval
As the Author user, navigate to the GetGenie History management page and extract the nonce using the browser_eval tool.
Step 3: Execution of Delete Request
Perform an authenticated POST request to admin-ajax.php.
- URL:
http://<target>/wp-admin/admin-ajax.php - Method:
POST - Headers:
Content-Type: application/x-www-form-urlencoded - Payload (Draft):
(Note: If the action name or parameter name differs upon inspection of the source, adjust accordingly.)action=getgenie_delete_history&post_id=1&_wpnonce=<NONCE_VALUE>
6. Test Data Setup
- Administrator Post: Create a post titled "ADMIN SECURE POST" with ID
1(or capture the ID). - Author User: Create a user with the
authorrole. - Plugin Activation: Ensure GetGenie <= 4.3.0 is installed and activated.
- Shortcode/Page (if needed): If the history page is blank, generate at least one "Genie" history item via the AI writer to ensure the scripts and nonces are properly initialized in the DOM.
7. Expected Results
- HTTP Response: A success status code (200 OK) and a JSON response like
{"success": true}or1. - State Change: The post with the target ID (owned by Admin) should no longer exist in the
wp_poststable or should be moved to the trash.
8. Verification Steps
- Check Post Existence via WP-CLI:
wp post exists 1 # Should return a non-zero exit code if deleted, or check: wp post list --post_type=any --include=1 - Verify Trash status:
wp post list --post_status=trash --include=1
9. Alternative Approaches
- REST API: Check if GetGenie registers custom REST API routes under
/wp-json/getgenie/v1/. If the vulnerability exists in a REST endpoint, the request would use theX-WP-Nonceheader. - Bulk Delete: Look for parameters that accept arrays (e.g.,
ids[]) which might allow for mass deletion of posts in a single request. - Default Nonce: If
wp_verify_nonce( ..., -1 )is used, try using any valid nonce obtained from the admin dashboard.
Summary
The GetGenie plugin for WordPress is vulnerable to unauthorized post deletion due to a missing capability check in its AJAX handlers. This allows authenticated users with Author-level permissions or higher to delete any post on the site, regardless of ownership, by providing a specific post ID.
Vulnerable Code
// getgenie/includes/admin/class-ajax.php (inferred location based on functionality) add_action( 'wp_ajax_getgenie_delete_history', 'getgenie_delete_history_handler' ); function getgenie_delete_history_handler() { check_ajax_referer( 'getgenie_nonce', 'nonce' ); // Baseline capability check is insufficient as it doesn't verify ownership or post-specific permissions if ( ! current_user_can( 'edit_posts' ) ) { wp_send_json_error( 'Unauthorized' ); } $post_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : 0; if ( $post_id ) { // VULNERABILITY: Arbitrary post deletion because current_user_can('delete_post', $post_id) is missing wp_delete_post( $post_id, true ); wp_send_json_success(); } wp_send_json_error(); }
Security Fix
@@ -10,7 +10,7 @@ $post_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : 0; - if ( $post_id ) { + if ( $post_id && current_user_can( 'delete_post', $post_id ) ) { wp_delete_post( $post_id, true ); wp_send_json_success(); }
Exploit Outline
1. Gain access to a WordPress account with at least the 'Author' role. 2. Navigate to the GetGenie 'History' or AI Content page within the WordPress dashboard to locate the localized AJAX nonce. 3. Extract the nonce from the JavaScript environment (e.g., via the `getgenie_admin` or `getgenie_history` JS objects). 4. Identify the ID of a target post or page (even one created by an Administrator) that you wish to delete. 5. Send a POST request to `/wp-admin/admin-ajax.php` with the following body parameters: - `action=getgenie_delete_history` (or the relevant internal delete action identified in the source) - `post_id=[TARGET_POST_ID]` - `nonce=[EXTRACTED_NONCE]` 6. The plugin will execute `wp_delete_post()` on the provided ID without verifying that the current user has the authority to delete that specific content.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.