MetForm Pro <= 3.9.7 - Unauthenticated Payment Amount Manipulation via 'mf-calculation'
Description
The MetForm Pro plugin for WordPress is vulnerable to Improper Input Validation in all versions up to, and including, 3.9.7 This is due to the payment integrations (Stripe/PayPal) trusting a user-submitted calculation field value without recomputing or validating it against the configured form price. This makes it possible for unauthenticated attackers to manipulate the payment amount via the 'mf-calculation' field in the form submission REST request granted there exists a specific form with this particular configuration.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:NTechnical Details
# Exploitation Research Plan: CVE-2026-1782 (MetForm Pro Price Manipulation) ## 1. Vulnerability Summary The **MetForm Pro** plugin (up to version 3.9.7) contains a vulnerability that allows unauthenticated users to manipulate payment amounts. When a form is configured to use a calculation field (`…
Show full research plan
Exploitation Research Plan: CVE-2026-1782 (MetForm Pro Price Manipulation)
1. Vulnerability Summary
The MetForm Pro plugin (up to version 3.9.7) contains a vulnerability that allows unauthenticated users to manipulate payment amounts. When a form is configured to use a calculation field (mf-calculation) for the total price in Stripe or PayPal integrations, the plugin fails to verify the calculated total on the server side. Instead, it trusts the value sent in the mf-calculation parameter of the form submission REST request.
2. Attack Vector Analysis
- Endpoint:
POST /wp-json/metform/v1/entries/insert/{form_id}(or similar REST route used for form submission). - Vulnerable Parameter:
mf-calculation(and potentially specific field IDs prefixed withmf-field-calculation-). - Authentication: None required (Unauthenticated).
- Preconditions:
- A MetForm must be published containing a "Calculation" field.
- The form must have Stripe or PayPal payment integration enabled.
- The payment settings must be configured to use the calculation field as the total price.
3. Code Flow (Inferred)
- Entry Point: The user submits a form. This triggers a request to the MetForm REST API handler, typically registered via
register_rest_routeinmetform-pro/inc/api/entry.php. - Processing: The submission handler (e.g.,
insert_entry) processes the fields. - Payment Initialization: If payment is enabled, the plugin invokes the payment gateway logic (e.g.,
metform-pro/inc/payment/stripe-handler.php). - Vulnerability: The payment handler retrieves the amount to charge. It looks for the value of the calculation field provided in the request:
$amount = $request->get_param('mf-calculation'); // Vulnerable line // Or it might use the specific field key - Sink: The unvalidated
$amountis passed directly to the Stripe/PayPal API to create a checkout session or order.
4. Nonce Acquisition Strategy
MetForm typically requires a REST nonce for submissions, localized via wp_localize_script.
- Identify Script/Variable: MetForm often uses the variable
mf_dataormetform_rest_obj. - Create Test Page:
- Use WP-CLI to create a page containing a MetForm shortcode:
wp post create --post_type=page --post_status=publish --post_content='[metform form_id="123"]' --post_title='Payment Form'
- Use WP-CLI to create a page containing a MetForm shortcode:
- Navigate and Extract:
- Use
browser_navigateto the created page. - Use
browser_evalto extract the nonce:// Common MetForm localization patterns window.metform_rest_obj?.nonce || window.mf_data?.nonce
- Use
- Action String: The nonce is usually for the
wp_restaction.
5. Exploitation Strategy
Step 1: Form Identification
Find an existing form ID that has calculation and payment enabled. If creating a test environment, note the form_id.
Step 2: Extract Parameters
Submit a legitimate form once while monitoring the network tab to see the exact structure of the JSON payload. It usually includes:
form_id: The ID of the form.mf-calculation: The total price.mf-field-calculation-XXXX: The specific field value.
Step 3: Manipulate and Submit
Perform a POST request to the REST endpoint with a manipulated price.
Request Details:
- URL:
http://[target]/wp-json/metform/v1/entries/insert/[form_id] - Method:
POST - Headers:
Content-Type: application/jsonX-WP-Nonce: [extracted_nonce]
- Payload:
{ "form_id": "[form_id]", "mf-calculation": "0.01", "mf-field-calculation-123": "0.01", "other_fields": "data" }
Step 4: Verification of Manipulation
The response from a successful submission usually contains a redirect URL to Stripe or PayPal.
- Expected Response:
200 OKor302containing apayment_url. - Validation: Inspect the
payment_url. If it is a Stripe Checkout link, navigate to it and verify the price displayed is $0.01 instead of the configured price.
6. Test Data Setup
- Install MetForm Pro 3.9.7.
- Configure Stripe/PayPal: Enable "Test Mode" in the plugin settings to avoid real transactions.
- Create a Form:
- Add a "Number" field (Price).
- Add a "Calculation" field (set formula to the Number field's value).
- Enable Stripe in the "Payment" tab and select the "Calculation" field as the "Total Price".
- Publish: Add the form to a public WordPress page using the
[metform id="..."]shortcode.
7. Expected Results
- Success: The plugin returns a payment session URL where the total amount matches the attacker-provided
mf-calculationvalue rather than the server-calculated value. - Failure: The plugin returns an error, or the payment session URL reflects the correct price (indicating server-side re-calculation).
8. Verification Steps
- Capture Response: Store the
payment_urlreturned by thehttp_request. - Browser Check: Use
browser_navigate("[payment_url]"). - Inspect DOM: Use
browser_evalto check the price displayed on the Stripe/PayPal checkout page.- Example for Stripe:
document.querySelector('.Checkout-TotalAmount').innerText
- Example for Stripe:
9. Alternative Approaches
- Parameter Variation: If
mf-calculationis ignored, try targeting the specific field ID found in the HTML source (e.g.,name="mf-field-calculation-789"). - Request Format: If
application/jsonfails, tryapplication/x-www-form-urlencoded. - Form Action: Check if the form submits to
admin-ajax.phpinstead of the REST API in older configurations; if so, the action is likelymetform_entries_insert.
Summary
MetForm Pro (up to version 3.9.7) is vulnerable to payment amount manipulation because it trusts the user-submitted 'mf-calculation' value during form submission. Unauthenticated attackers can override the intended price of a product or service by providing a lower value in the REST API request, which is then passed directly to Stripe or PayPal gateways.
Vulnerable Code
// Inferred from metform-pro/inc/api/entry.php or payment handlers // The plugin retrieves the amount directly from the request parameters without server-side validation $amount = $request->get_param('mf-calculation');
Exploit Outline
1. Identify a WordPress site using MetForm Pro with a form that has a 'Calculation' field linked to Stripe or PayPal payments. 2. Extract the REST API nonce from the frontend source code (usually located in the 'metform_rest_obj' or 'mf_data' JavaScript objects). 3. Identify the 'form_id' and the specific field names (e.g., 'mf-calculation' and 'mf-field-calculation-XXXX') used by the form. 4. Send a POST request to the endpoint '/wp-json/metform/v1/entries/insert/{form_id}' using the extracted nonce in the 'X-WP-Nonce' header. 5. Include a JSON payload where the 'mf-calculation' parameter is set to a manipulated price (e.g., '0.01'). 6. Follow the 'payment_url' returned in the JSON response to confirm the payment gateway (Stripe/PayPal) is requesting the manipulated amount.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.