GLS Shipping for WooCommerce <= 1.4.0 - Reflected Cross-Site Scripting via 'failed_orders'
Description
The GLS Shipping for WooCommerce plugin for WordPress is vulnerable to Reflected Cross-Site Scripting via the 'failed_orders' parameter in all versions up to, and including, 1.4.0 due to insufficient input sanitization and output escaping. This makes it possible for unauthenticated attackers to inject arbitrary web scripts in pages that execute if they can successfully trick a user into performing an action such as clicking on a link.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:NTechnical Details
<=1.4.0Source Code
WordPress.org SVN# Exploitation Research Plan: CVE-2026-6417 (GLS Shipping for WooCommerce) ## 1. Vulnerability Summary The **GLS Shipping for WooCommerce** plugin (up to version 1.4.0) is vulnerable to **Reflected Cross-Site Scripting (XSS)**. The vulnerability exists because the plugin retrieves the value of the …
Show full research plan
Exploitation Research Plan: CVE-2026-6417 (GLS Shipping for WooCommerce)
1. Vulnerability Summary
The GLS Shipping for WooCommerce plugin (up to version 1.4.0) is vulnerable to Reflected Cross-Site Scripting (XSS). The vulnerability exists because the plugin retrieves the value of the failed_orders HTTP GET parameter and reflects it back into an administrative notice or a settings page without applying proper sanitization (e.g., sanitize_text_field) or output escaping (e.g., esc_html).
This allows an attacker to craft a malicious URL containing JavaScript. When a logged-in administrator clicks this link, the script executes within the context of their session, potentially leading to unauthorized actions such as account takeover or configuration changes.
2. Attack Vector Analysis
- Endpoint:
wp-admin/admin.php - Query Parameters:
page: The plugin's admin page slug (inferred asgls-shipping-for-woocommerceorgls-shipping-orders).failed_orders: The vulnerable parameter carrying the XSS payload.
- Authentication: Requires a user with access to the plugin's admin pages (typically
manage_woocommerceormanage_optionscapabilities). - Preconditions: The plugin must be active. The attacker must trick an authenticated user into clicking a crafted link.
3. Code Flow
- Entry Point: The user navigates to an admin URL containing
page=gls-shipping-for-woocommerce&failed_orders=<script>.... - Hook Registration: The plugin likely hooks into
admin_noticesor the admin page rendering callback (registered viaadd_submenu_page). - Vulnerable Logic (Inferred):
- Inside the callback function (e.g.,
GLS_Admin::display_noticesor similar), the code checks for the existence of the parameter. $failed_ids = $_GET['failed_orders'];- Sink: The value is echoed directly into the HTML:
echo '<div class="notice notice-error"><p>Sync failed for: ' . $failed_ids . '</p></div>';
- Inside the callback function (e.g.,
- Execution: The browser interprets the unsanitized
failed_idsas HTML/JavaScript, executing the payload.
4. Nonce Acquisition Strategy
Reflected XSS in a GET parameter used for displaying notices typically does not involve a nonce check. Nonces are intended to prevent CSRF (unauthorized actions), whereas this vulnerability is a failure of output encoding during a simple GET request for a page view.
If the admin page itself requires a nonce (rare for top-level menu views):
- Use
wp post createto create a test page containing any GLS-related shortcode if required to load plugin assets. - Use
browser_navigateto the plugin's main settings page:http://localhost:8080/wp-admin/admin.php?page=gls-shipping-for-woocommerce. - Use
browser_evalto extract any nonces if they appear in the source:browser_eval("document.querySelector('#_wpnonce')?.value")
Note: For this specific Reflected XSS, the attack is triggered by the link itself; a missing nonce check in the display logic is what makes the reflection possible.
5. Exploitation Strategy
The goal is to demonstrate script execution via the failed_orders parameter.
Step 1: Discover the Admin Slug
Determine the exact page parameter value. Common slugs for this plugin:
gls-shipping-for-woocommercegls-wc-shipping
Step 2: Construct the Payload
We will use a diagnostic payload to prove execution:failed_orders=<script>console.log("XSS_VULNERABLE_CONFIRMED")</script>
Step 3: Execute the Request
Use the http_request tool to simulate an administrator clicking the link.
- URL:
http://localhost:8080/wp-admin/admin.php?page=gls-shipping-for-woocommerce&failed_orders=%3Cscript%3Econsole.log(%22XSS_VULNERABLE_CONFIRMED%22)%3C/script%3E - Method:
GET - Headers: Must include the administrator's session cookies.
Step 4: Verify via Browser
Since this is reflected XSS, the result is visible in the DOM. Use browser_navigate to the same URL and check the console logs or the page source for the injected <script> tag.
6. Test Data Setup
- Install Plugin: Ensure GLS Shipping for WooCommerce v1.4.0 is installed and activated.
- Administrator User: Use the existing admin account to access the dashboard.
- WooCommerce: Ensure WooCommerce is active, as the plugin depends on it.
7. Expected Results
- The HTTP response will contain the raw string:
<script>console.log("XSS_VULNERABLE_CONFIRMED")</script>. - The
browser_evalofwindow.console.history(or similar logging) will show the confirmation string. - The payload will be rendered inside a
<div>with classes likenoticeornotice-error.
8. Verification Steps
- Manual Source Check:
wp eval "echo 'Search for payload in response: ' . (strpos(file_get_contents('URL_HERE'), 'XSS_VULNERABLE_CONFIRMED') !== false ? 'FOUND' : 'NOT FOUND');" - DOM Verification:
Usebrowser_evalto check if the script tag exists in the DOM:browser_eval("document.body.innerHTML.includes('XSS_VULNERABLE_CONFIRMED')")
9. Alternative Approaches
- Attribute Breakout: If the value is reflected inside an input field (e.g.,
value='[input]'), use:failed_orders=' onclick='alert(1)' type='text - HTML Tag Injection: If scripts are filtered but HTML is not:
failed_orders=<img src=x onerror=alert(1)> - Admin Action Chain: Attempt to use the XSS to trigger an administrative action, such as creating a new admin user via a
fetch()call touser-new.phpinside the payload.
Summary
The GLS Shipping for WooCommerce plugin for WordPress is vulnerable to Reflected Cross-Site Scripting (XSS) due to insufficient input sanitization and output escaping on the 'failed_orders' parameter. An unauthenticated attacker can exploit this by tricking a logged-in administrator into clicking a crafted link, leading to arbitrary JavaScript execution in the admin's browser session.
Vulnerable Code
// Inferred from Research Plan as the source files were not provided // Likely within an admin_notices hook or admin page rendering callback $failed_ids = $_GET['failed_orders']; echo '<div class="notice notice-error"><p>Sync failed for: ' . $failed_ids . '</p></div>';
Security Fix
@@ -10,2 +10,2 @@ -$failed_ids = $_GET['failed_orders']; -echo '<div class="notice notice-error"><p>Sync failed for: ' . $failed_ids . '</p></div>'; +$failed_ids = isset($_GET['failed_orders']) ? sanitize_text_field($_GET['failed_orders']) : ''; +echo '<div class="notice notice-error"><p>' . esc_html__('Sync failed for: ', 'gls-shipping-for-woocommerce') . esc_html($failed_ids) . '</p></div>';
Exploit Outline
The vulnerability is exploited by crafting a malicious URL that targets the WordPress admin dashboard. An attacker identifies the plugin's admin page (e.g., wp-admin/admin.php?page=gls-shipping-for-woocommerce) and appends a 'failed_orders' GET parameter containing an XSS payload, such as <script>alert(1)</script>. The attacker then tricks an authenticated administrator into clicking this link. Because the plugin reflects the parameter value directly into an administrative notice without using functions like esc_html(), the browser executes the script in the context of the administrator's session. No nonce is required for this reflection as it occurs during a standard GET request used for page display.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.