Cost Calculator Builder <= 4.0.11 - Unauthenticated Sensitive Information Exposure of Payment Gateway Secret Keys
Description
The Cost Calculator Builder plugin for WordPress is vulnerable to Sensitive Information Exposure in all versions up to, and including, 4.0.11 via the (template body). This makes it possible for unauthenticated attackers to extract the plaintext Stripe secret key, Razorpay secret key, and PayPal client_secret embedded in the page source of any page containing a calculator, enabling full control of the merchant's payment gateway accounts. This exposure only occurs when the 'use in all calculators' option is enabled for one or more payment gateways in the plugin's global settings.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:NTechnical Details
<=4.0.11What Changed in the Fix
Changes introduced in v4.0.12
Source Code
WordPress.org SVN# Exploitation Research Plan - CVE-2026-10865 ## 1. Vulnerability Summary The **Cost Calculator Builder** plugin (<= 4.0.11) is vulnerable to **Sensitive Information Exposure**. The plugin exposes payment gateway secret keys (Stripe, Razorpay, and PayPal) in the HTML source code of any page where a…
Show full research plan
Exploitation Research Plan - CVE-2026-10865
1. Vulnerability Summary
The Cost Calculator Builder plugin (<= 4.0.11) is vulnerable to Sensitive Information Exposure. The plugin exposes payment gateway secret keys (Stripe, Razorpay, and PayPal) in the HTML source code of any page where a calculator is embedded. This occurs when the "use in all calculators" option is enabled in the global settings, causing the plugin to localize sensitive configuration data to the frontend JavaScript context without filtering out secrets.
2. Attack Vector Analysis
- Endpoint: Any public-facing page or post containing a
[cost_calculator]shortcode. - Method: Unauthenticated
GETrequest. - Precondition:
- A payment gateway (Stripe, Razorpay, or PayPal) must be configured in the plugin settings.
- The "use in all calculators" option for that gateway must be enabled.
- At least one calculator must be published on a page.
- Authentication: None required.
3. Code Flow Trace
The vulnerability stems from how settings are passed from the server to the frontend Vue.js components.
- Entry Point: A user visits a page with the
[cost_calculator]shortcode. - Shortcode Handling:
CCBEmbedCalculatororCCBFrontController(likely insideincludes/classes/CCBFrontController.php) processes the shortcode and enqueues the necessary scripts. - Data Localization: The plugin uses
wp_localize_script()orwp_add_inline_script()to pass configuration data to the frontend. - The Sink: The function responsible for gathering settings (likely inside
includes/classes/CCBSettingsData.phporCCBCalculatorsHandler.php) retrieves the entire gateway configuration object from the database (wp_options). - The Bug: If "use in all calculators" is enabled, the code does not sanitize the configuration object before passing it to the localization function, resulting in
secret_keyorclient_secretbeing printed in the page source inside a JSON object.
4. Nonce Acquisition Strategy
No nonce is required. This is a passive information exposure vulnerability via a standard GET request.
5. Test Data Setup
To reproduce the vulnerability, the environment must be configured as follows:
- Configure Payment Gateway:
# Use WP-CLI to simulate setting up a Stripe gateway with a secret key # The actual option name might be ccb_settings or ccb_payment_settings # We will verify the exact option name in the research phase wp option patch insert ccb_settings stripe_secret_key "sk_test_51MzVulnerabilityTestKey" wp option patch insert ccb_settings stripe_use_global "on" wp option patch insert ccb_settings razorpay_secret_key "rzp_test_SecretKey123" wp option patch insert ccb_settings razorpay_use_global "on" - Create a Calculator:
- Use the plugin's internal methods or WP-CLI to ensure a calculator exists. (Default ID is usually 1).
- Publish a Page:
wp post create --post_type=page --post_title="Payment Calculator" --post_status=publish --post_content='[cost_calculator id="1"]'
6. Exploitation Strategy
The exploitation is a two-step process: discovering where the data is localized and then extracting it.
Phase 1: Discovery
- Identify the localization variable name. We will search for
wp_localize_scriptin the plugin directory. - Search for the "use in all calculators" setting logic in
includes/classes/CCBSettingsData.php.
Phase 2: Extraction
- Request:
GET /payment-calculator/ HTTP/1.1 Host: target.local - Analysis:
- Inspect the response body for
<script>tags. - Look for common localization keys like
ccb_data,ccb_frontend_settings, orcalc_data. - Search for the specific secret key strings (e.g.,
sk_test_,rzp_test_).
- Inspect the response body for
7. Expected Results
A successful exploit will find a JSON object in the page source similar to:
<script id="ccb-frontend-settings-js-extra">
var ccb_data = {
"payments": {
"stripe": {
"enabled": "on",
"publishable_key": "pk_test_...",
"secret_key": "sk_test_51MzVulnerabilityTestKey",
"use_global": "on"
},
"razorpay": {
"key_id": "rzp_test_...",
"key_secret": "rzp_test_SecretKey123",
"use_global": "on"
}
}
};
</script>
8. Verification Steps
- Manual Check: Perform a
GETrequest to the page and grep for the secret:# In the tool context http_request(url="http://localhost:8080/payment-calculator/") # Then grep the response for "secret_key" - Internal Comparison: Compare the value found in the HTML source with the value stored in the database:
wp option get ccb_settings --format=json | jq .stripe_secret_key
9. Alternative Approaches
If the secrets are not in a standard wp_localize_script block:
- Check if they are embedded as
data-attributes on the calculator's containerdiv(e.g.,<div id="ccb-container" data-config="...">). - Check if the plugin fetches configuration via an unauthenticated AJAX/REST endpoint (e.g.,
wp-json/ccb/v1/settings?id=1). If so, check that endpoint for the same lack of sanitization. - Use
browser_evalto inspect the global window object:browser_eval("window.ccb_data").
Summary
The Cost Calculator Builder plugin for WordPress (<= 4.0.11) exposes sensitive payment gateway secret keys (Stripe, Razorpay, and PayPal) in the HTML source code of pages containing a calculator. This exposure occurs when the 'use in all calculators' option is enabled in the global settings, allowing unauthenticated attackers to extract plaintext credentials and gain control over the site owner's merchant accounts.
Security Fix
@@ -8,7 +8,7 @@ * License: GNU General Public License v2 or later * License URI: http://www.gnu.org/licenses/gpl-2.0.html * Text Domain: cost-calculator-builder - * Version: 4.0.11 + * Version: 4.0.12 */ if ( ! defined( 'ABSPATH' ) ) { @@ -17,7 +17,7 @@ define( 'CALC_DIR', __DIR__ ); define( 'CALC_FILE', __FILE__ ); -define( 'CALC_VERSION', '4.0.11' ); +define( 'CALC_VERSION', '4.0.12' ); define( 'CALC_WP_TESTED_UP', '7.0' ); define( 'CALC_DB_VERSION', '4.0.0' ); define( 'CALC_PATH', dirname( CALC_FILE ) ); ... (truncated)
Exploit Outline
1. Target Identification: Locate a WordPress site running Cost Calculator Builder (<= 4.0.11) with a calculator embedded on a public page. 2. Source Inspection: Access the page as an unauthenticated visitor and view the HTML source code. 3. Data Localization Hunt: Search for JavaScript blocks containing localized configuration data (e.g., searching for keys like 'ccb_data', 'calc_data', or 'secret_key'). 4. Credential Extraction: When the 'use in all calculators' setting is enabled globally for payment providers, the plugin includes the full gateway configuration object in the frontend JS context. Extract the plaintext values for 'stripe_secret_key', 'razorpay_secret_key', or 'paypal_client_secret' from the JSON object.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.