WC Shop Sync – Square Payment Gateway and Product Synchronization for WooCommerce <= 4.7.3 - Unauthenticated Information Exposure
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:NTechnical Details
What Changed in the Fix
Changes introduced in v4.7.4
Source Code
WordPress.org SVN# 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_scriptto pass configuration data from PHP to JavaScript. It incorrectly includes the Square Access Token in this data. - Authentication: None (Unauthenticated).
- Preconditions:
- The "Square Terminal Pay" or "Square Payment Gateway" must be enabled.
- The plugin must be configured with a Square Access Token.
- The WooCommerce store must be set to a supported country/currency (e.g., US/USD).
3. Code Flow
- Initialization: The
WooSquare_Paymentsclass constructor (inclass-woosquare-payments.php) initializes the payment gateways. - Gateway Loading: The
WooSquarePOS_Gatewayclass (inclass-woosquarepos-gateway.php) is instantiated. - Script Enqueuing: The constructor of
WooSquarePOS_Gatewayregisters the hookadd_action( 'wp_enqueue_scripts', array( $this, 'payment_scripts_terminalpay' ) );. - Localization (Sink): In the
payment_scripts_terminalpaymethod (inferred from JS usage), the plugin callswp_localize_scriptto create thesquaretpay_paramsandPOSTerminalobjects. - 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. - Exposure: The browser renders a
<script>block containing the JSON-encoded token, which is then used bySquarePaymentsPOSPay.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:
- Navigate to the
/checkout/page. - Use
browser_evalto extract the sensitive variables from the globalwindowobject. - Variable Names:
window.squaretpay_params(containsaccess_token,location_id)window.POSTerminal(containsaccess_token,location_id)
- Navigate to the
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:
- Configure WooCommerce:
- Set Store Address to United States (US).
- Set Currency to US Dollars ($).
- 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_settingsto have'enabled' => 'yes'.
- Set a dummy Square Access Token:
- 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:
- Enable Express Checkout in plugin settings.
- Navigate to
/product/test-product/. - Check
window.squaretpay_paramsagain.
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
@@ -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’ 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(); } @@ -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.