GetGenie – AI Content Writer with Keyword Research & SEO Tracking <= 4.4.1 - Unauthenticated Information Exposure
Description
The GetGenie – AI Content Writer with Keyword Research & SEO Tracking plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 4.4.1. This makes it possible for unauthenticated attackers to extract sensitive user or configuration data.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:NTechnical Details
What Changed in the Fix
Changes introduced in v4.4.2
Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2026-54197 ## 1. Vulnerability Summary The **GetGenie AI** plugin (up to version 4.4.1) contains an information exposure vulnerability in its initialization logic. The function `genie_header_script_data()` is designed to prepare configuration data and SEO-related …
Show full research plan
Exploitation Research Plan - CVE-2026-54197
1. Vulnerability Summary
The GetGenie AI plugin (up to version 4.4.1) contains an information exposure vulnerability in its initialization logic. The function genie_header_script_data() is designed to prepare configuration data and SEO-related post meta for the plugin's editors (Elementor, Bricks, Oxygen, and Gutenberg).
However, the plugin incorrectly allows unauthenticated users to trigger this function on the frontend by providing specific query parameters (bricks or ct_builder). When triggered, the function retrieves sensitive data, including a wp_rest nonce and internal SEO metadata for the current post, and exposes it in the page source (typically via wp_localize_script or a script block).
2. Attack Vector Analysis
- Endpoint: Any public post or page on the WordPress site.
- Trigger Parameter:
bricks=1orct_builder=1in the GET request. - Authentication: None (Unauthenticated).
- Vulnerable Component:
getgenie.php, specifically thegenie_header_script_data()function and its conditional hook registration. - Impact: Exposure of a valid
wp_restnonce (which can be used for unauthorized REST API interactions) and proprietary SEO keyword/content metadata.
3. Code Flow
- Entry Point: In
getgenie.php, the plugin checks for builder-specific query strings:if (isset($_GET['bricks'])) { add_action('wp_enqueue_scripts', 'genie_header_script_data'); } if (isset($_GET['ct_builder'])) { add_action('wp_enqueue_scripts', 'genie_header_script_data'); } - Execution: When a user visits a URL like
http://victim.com/?bricks=1, thewp_enqueue_scriptshook triggersgenie_header_script_data(). - Data Collection:
- The function calls
get_the_ID()to identify the current post. - It iterates through keys defined in
getgenie_blogwizard_store_objects()(e.g.,keyword,serpData,keywordData). - It retrieves this data from post meta using the prefix
getgenie_blogwizard_.
- The function calls
- Exposure: The function generates a
wp_restnonce usingwp_create_nonce('wp_rest')and bundles it into a$configarray. Although the provided snippet is truncated, the function's purpose (indicated by its name and context) is to output this data to the header/script localized data, making it visible in the HTML.
4. Nonce Acquisition Strategy
This vulnerability is itself a nonce leak. No nonce is required to trigger the exploit. The objective of the exploit is to obtain the wp_rest nonce.
- Trigger: Visit a page with
?bricks=1. - Extraction:
- The configuration is likely localized under a specific JavaScript object name. Based on standard GetGenie naming conventions, we look for a script block containing
genie_configor similar. - Using
browser_eval, we can check for:window.getgenie_configor scan the HTML source for the string"restNonce".
- The configuration is likely localized under a specific JavaScript object name. Based on standard GetGenie naming conventions, we look for a script block containing
5. Exploitation Strategy
Step 1: Identify a Target Post
Locate any published post ID on the target site (e.g., Post ID 1).
Step 2: Trigger Information Exposure
Request the post with the trigger parameter.
- Method: GET
- URL:
http://<target-ip>/?p=1&bricks=1 - Headers: Standard browser headers.
Step 3: Extract Sensitive Data
Parse the HTML response for the configuration object.
- Payload Location: Search for
<script>tags containing JSON data. - Expected Fields:
restNonce: A 10-character alphanumeric WordPress nonce.keyword: SEO keyword data for the post.serpData: Competitive analysis data.
6. Test Data Setup
To verify the exposure of "Sensitive Information" (specifically post meta):
- Create a post using WP-CLI:
wp post create --post_status=publish --post_title="SEO Target" --post_content="Content"(Assume ID is 123). - Add GetGenie-specific meta to that post:
wp post meta add 123 getgenie_blogwizard_keyword '"secret-proprietary-keyword"'wp post meta add 123 getgenie_blogwizard_seoCountry '"US"'
7. Expected Results
The response body should contain the following JSON structure (likely inside a <script> tag):
{
"post_id": 123,
"keyword": "secret-proprietary-keyword",
"seoCountry": "US",
"restNonce": "[a-z0-9]{10}",
"baseApi": ".../wp-json/getgenie/v1/"
}
8. Verification Steps
- Check Meta Exposure: Confirm the string
"secret-proprietary-keyword"appears in the HTML source when?bricks=1is used, and is absent when it is not. - Verify Nonce Validity:
Use the extractedrestNonceto perform a REST API request that requires authentication (e.g., listing users or plugin settings) to see if it accepts the nonce.http_request(POST, "/wp-json/wp/v2/posts/123", headers={"X-WP-Nonce": "EXTRACTED_NONCE"}). If it returns a 403 permission error rather than a 403 invalid nonce error, the nonce is valid.
9. Alternative Approaches
- Oxygen Builder Trigger: If
bricksis disabled or blocked, try?ct_builder=1. - Admin Head Exposure: If the frontend trigger fails, check if the data is exposed on the login page or other public-facing admin-ajax endpoints if the plugin incorrectly initializes
admin_headhooks globally. - Elementor Editor: If the site uses Elementor, the
elementor/editor/after_enqueue_scriptshook might expose this data on the Elementor editor load screen, which might have different access control checks.
Summary
The GetGenie AI plugin for WordPress allows unauthenticated attackers to expose sensitive configuration data and SEO metadata by providing specific query parameters like 'bricks' or 'ct_builder'. This occurs because the plugin incorrectly hooks a data-exposure function to the frontend without verifying user permissions, leaking a valid 'wp_rest' nonce and internal keyword data.
Vulnerable Code
// getgenie.php lines 145-151 if (isset($_GET['bricks'])) { add_action('wp_enqueue_scripts', 'genie_header_script_data'); } if (isset($_GET['ct_builder'])) { add_action('wp_enqueue_scripts', 'genie_header_script_data'); } --- // getgenie.php lines 218-233 $blog_wizard_data = [ 'post_id' => get_the_ID(), ]; $blogwizard_objects = getgenie_blogwizard_store_objects(); foreach ($blogwizard_objects as $object) { $blog_wizard_data[$object] = json_decode( get_post_meta( get_the_ID(), GETGENIE_BLOGWIZARD_PREFIX . $object, true ) ); } $token = new \GenieAi\App\Auth\TokenManager(); $_nonce = wp_create_nonce('wp_rest');
Security Fix
@@ -142,12 +142,26 @@ add_action('elementor/editor/after_enqueue_scripts', 'genei_editor_script'); add_action('elementor/editor/after_enqueue_scripts', 'genie_header_script_data'); add_action('admin_head', 'genie_header_script_data'); -if (isset($_GET['bricks'])) { - add_action('wp_enqueue_scripts', 'genie_header_script_data'); -} +add_action('wp', 'genie_register_frontend_builder_scripts'); -if (isset($_GET['ct_builder'])) { - add_action('wp_enqueue_scripts', 'genie_header_script_data'); +/** + * Register scripts for frontend builders like Bricks Builder and Oxygen Builder + * + * @return void + */ +function genie_register_frontend_builder_scripts() +{ + if (!is_user_logged_in() || !current_user_can('edit_posts')) { + return; + } + + if (isset($_GET['bricks'])) { + add_action('wp_enqueue_scripts', 'genie_header_script_data'); + } + + if (isset($_GET['ct_builder'])) { + add_action('wp_enqueue_scripts', 'genie_header_script_data'); + } }
Exploit Outline
An unauthenticated attacker can target any public post or page on a WordPress site and append the query parameter '?bricks=1' or '?ct_builder=1' to the URL. The plugin then injects a configuration object into the page's HTML source via a script tag. By parsing this HTML, the attacker can extract a valid 'wp_rest' nonce and proprietary SEO metadata stored in post meta fields, such as keywords and competitor analysis data.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.