CVE-2026-8893

Express Payment For Stripe <= 1.28.0 - Authenticated (Contributor+) Stored Cross-Site Scripting via Shortcode Attributes

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

Description

The Express Payment For Stripe plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'type' attribute of the [stripe-express] shortcode in versions up to, and including, 1.28.0. This is due to insufficient input sanitization and output escaping on the shortcode attribute value, which is concatenated into an HTML attribute in the rendered output of the register_shortcode() function without being passed through esc_attr() or any other escaping function. 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<=1.28.0
PublishedJune 5, 2026
Last updatedJune 5, 2026
Affected pluginwp-stripe-express

What Changed in the Fix

Changes introduced in v1.28.2

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

I cannot fulfill this request. I am prohibited from generating actionable exploitation plans, functional attack payloads, or step-by-step guides for exploiting specific vulnerabilities in software. I can, however, explain the security principles involved or how to remediate these types of vulnerabil…

Show full research plan

I cannot fulfill this request. I am prohibited from generating actionable exploitation plans, functional attack payloads, or step-by-step guides for exploiting specific vulnerabilities in software. I can, however, explain the security principles involved or how to remediate these types of vulnerabilities.

The vulnerability described (CVE-2026-8893) is a Stored Cross-Site Scripting (XSS) issue resulting from improper handling of shortcode attributes. In WordPress development, this is typically prevented by following these security best practices:

  1. Input Sanitization: All user-supplied input, including attributes passed through shortcodes, should be sanitized as soon as it is received. For text-based attributes, functions like sanitize_text_field() are commonly used.
  2. Output Escaping: This is the most critical defense against XSS. Data must be escaped at the point of output, specific to the context in which it is being displayed.
    • When outputting data inside an HTML attribute (like data-type=""), the esc_attr() function should be used.
    • When outputting data inside HTML tags, esc_html() should be used.
    • For URLs, esc_url() is appropriate.
  3. Principle of Least Privilege: Security audits often focus on whether the required user capability (e.g., contributor) is appropriate for the actions allowed by the code.

For more information on secure WordPress development and preventing XSS, you can refer to the WordPress Plugin Handbook section on Security.

Research Findings
Static analysis — not yet PoC-verified

Summary

The Express Payment For Stripe plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the 'type' attribute of the [stripe-express] shortcode in versions up to 1.28.0. This occurs because the plugin fails to escape the attribute value before outputting it into an HTML container, allowing authenticated attackers with Contributor-level access to inject arbitrary web scripts.

Vulnerable Code

// includes/wp-stripe-shortcodes.php line 33-44
        // End getting
        $type = ( isset( $atts['type'] ) ? $atts['type'] : $config['type'] );
        $object_id = 'wp_stripe_express_object_' . uniqid();
        wp_enqueue_style( 'wp-stripe-express-elements' );
        wp_enqueue_script(
            'wp-stripe-express-elements',
            IT_STRIPE_EXPRESS_URL . 'dist/' . 'itstripe-elements.min.js',
            null,
            IT_STRIPE_EXPRESS_VERSION,
            true
        );
        wp_localize_script( 'wp-stripe-express-elements', $object_id, $objectConfig );
        $theme = get_option( 'stripe_express_theme' );
        if ( !empty( $theme ) ) {
            wp_enqueue_style( 'wp-stripe-express-elements-theme' );
        }
        return '<div class="wp-stripe-express-shortcode" data-id="' . $object_id . '" data-type="' . $type . '"></div>';

Security Fix

--- includes/wp-stripe-shortcodes.php
+++ includes/wp-stripe-shortcodes.php
@@ -41,5 +41,5 @@
         if ( !empty( $theme ) ) {
             wp_enqueue_style( 'wp-stripe-express-elements-theme' );
         }
-        return '<div class="wp-stripe-express-shortcode" data-id="' . $object_id . '" data-type="' . $type . '"></div>';
+        return '<div class="wp-stripe-express-shortcode" data-id="' . esc_attr( $object_id ) . '" data-type="' . esc_attr( $type ) . '"></div>';

Exploit Outline

1. Login to the WordPress dashboard as a user with at least Contributor-level permissions (e.g., Contributor, Author, Editor). 2. Create a new Post or Page, or edit an existing one. 3. Insert the [stripe-express] shortcode with a malicious payload in the 'type' attribute. A valid 'id' must also be provided (the plugin fetches a configuration from the database based on this ID, so a valid element ID must exist). 4. Payload shape: [stripe-express id="1" type='" onmouseover="alert(document.cookie)" style="width:100px;height:100px;display:block;"'] or [stripe-express id="1" type='"><script>alert(1)</script>'] 5. Save or Publish the post. 6. When a user (e.g., an administrator) visits the post, the injected JavaScript will execute within their browser context.

Check if your site is affected.

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