CVE-2026-1782

MetForm Pro <= 3.9.7 - Unauthenticated Payment Amount Manipulation via 'mf-calculation'

mediumImproper Input Validation
5.3
CVSS Score
5.3
CVSS Score
medium
Severity
3.9.8
Patched in
1d
Time to patch

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:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
None
Confidentiality
Low
Integrity
None
Availability

Technical Details

Affected versions<=3.9.7
PublishedApril 14, 2026
Last updatedApril 15, 2026
Affected pluginmetform-pro
Research Plan
Unverified

# 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 with mf-field-calculation-).
  • Authentication: None required (Unauthenticated).
  • Preconditions:
    1. A MetForm must be published containing a "Calculation" field.
    2. The form must have Stripe or PayPal payment integration enabled.
    3. The payment settings must be configured to use the calculation field as the total price.

3. Code Flow (Inferred)

  1. Entry Point: The user submits a form. This triggers a request to the MetForm REST API handler, typically registered via register_rest_route in metform-pro/inc/api/entry.php.
  2. Processing: The submission handler (e.g., insert_entry) processes the fields.
  3. Payment Initialization: If payment is enabled, the plugin invokes the payment gateway logic (e.g., metform-pro/inc/payment/stripe-handler.php).
  4. 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
    
  5. Sink: The unvalidated $amount is 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.

  1. Identify Script/Variable: MetForm often uses the variable mf_data or metform_rest_obj.
  2. 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'
  3. Navigate and Extract:
    • Use browser_navigate to the created page.
    • Use browser_eval to extract the nonce:
      // Common MetForm localization patterns
      window.metform_rest_obj?.nonce || window.mf_data?.nonce
      
  4. Action String: The nonce is usually for the wp_rest action.

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/json
    • X-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 OK or 302 containing a payment_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

  1. Install MetForm Pro 3.9.7.
  2. Configure Stripe/PayPal: Enable "Test Mode" in the plugin settings to avoid real transactions.
  3. 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".
  4. 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-calculation value 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

  1. Capture Response: Store the payment_url returned by the http_request.
  2. Browser Check: Use browser_navigate("[payment_url]").
  3. Inspect DOM: Use browser_eval to check the price displayed on the Stripe/PayPal checkout page.
    • Example for Stripe: document.querySelector('.Checkout-TotalAmount').innerText

9. Alternative Approaches

  • Parameter Variation: If mf-calculation is ignored, try targeting the specific field ID found in the HTML source (e.g., name="mf-field-calculation-789").
  • Request Format: If application/json fails, try application/x-www-form-urlencoded.
  • Form Action: Check if the form submits to admin-ajax.php instead of the REST API in older configurations; if so, the action is likely metform_entries_insert.
Research Findings
Static analysis — not yet PoC-verified

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.