JS

Application Security Series

3 CHAPTERS100% DONE
Week 3~ 5 min read

Parameter Tampering — Price Manipulation

Parameter tampering is a type of web application/API security issue where an attacker modifies a parameter controlled by the client and the server incorrectly trusts the modified value.

The important concept is:

SECURITY_ADVISORY

The client sends the input; the server must decide whether that input is actually allowed.

If the server accepts a manipulated parameter without properly validating it or checking authorization/business rules, the application may be vulnerable.

1. What Is a Parameter?

A parameter is information sent from the client to the server.

For example:

http
GET /account?user_id=1001

Here:

text
user_id=1001

is a parameter.

A POST request could contain:

http
POST /purchase

product_id=500
quantity=2
price=100

An API might use JSON:

json
{
  "product_id": 500,
  "quantity": 2,
  "price": 100
}

All of these values can potentially be controlled or modified by the client.

2. What Does Tampering Mean?

Suppose an application sends:

http
POST /purchase

product_id=500&quantity=2&price=100

The attacker changes:

text
price=100

to:

text
price=1

and sends:

http
POST /purchase

product_id=500&quantity=2&price=1

If the server processes the purchase for $1 instead of obtaining the legitimate price from its database, the application has a business-logic parameter tampering vulnerability.

The fundamental problem isn't that the attacker changed the request. Clients are inherently capable of changing their own requests.

The problem is that the server trusted a value that should have been controlled by the server.

3. Common Types of Parameter Tampering

A. Price Manipulation

An application sends:

json
{
  "product_id": 123,
  "price": 9999
}

The legitimate price is stored on the server as ₹9,999.

If changing the request to:

json
{
  "product_id": 123,
  "price": 10
}

causes the transaction to be processed for ₹10, that's a serious business-logic flaw.

Proper Implementation

The server should essentially do:

text
Receive product_id
        ↓
Look up product_id in database
        ↓
Retrieve trusted price
        ↓
Calculate total
        ↓
Process payment

rather than:

text
Receive product_id + price
        ↓
Trust client-supplied price
        ↓
Process payment

Think of it this way:

Secure Application

Suppose the database contains:

text
Product ID: 101
Price: ₹5,000

The browser sends:

http
POST /buy

product_id=101&price=10

A secure server says:

text
Client says price = ₹10
        ↓
Server ignores that price
        ↓
Looks up product_id=101
        ↓
Database says ₹5,000
        ↓
Uses ₹5,000

So changing the parameter has no useful effect.

Vulnerable Application

The server might have the correct price in the database, but the developer has written the business logic something like:

text
Receive product_id
Receive price
        ↓
Calculate using received price
        ↓
Process transaction

Then:

text
product_id=101&price=10

could result in:

text
Order total = ₹10

The fact that the server has the correct value doesn't automatically mean it will use it.

4. Quantity Manipulation

Suppose:

http
POST /order

product_id=123&quantity=1

The application should enforce rules such as:

text
quantity >= 1
quantity <= available_stock

If the application accepts something unexpected such as:

text
quantity=-1

or an excessively large quantity, the result can depend on the application's business logic.

Potential consequences include:

  • Incorrect inventory calculations
  • Incorrect billing
  • Negative totals
  • Order-processing errors
  • Resource exhaustion

The exact impact depends on how the backend handles the value.

5. How to Fix / Remediation

The client can send a price, but the server should ignore it and calculate the price from trusted server-side data.

Vulnerable Flow

text
Client
  |
  | product_id=101
  | price=₹10   ← attacker modified this
  | quantity=1
  ↓
Server
  |
  | trusts price=₹10
  ↓
Order = ₹10

Even if the database contains:

text
Product 101 → ₹50,000

the vulnerable code never uses that value.

Secure Flow

text
Client
  |
  | product_id=101
  | price=₹10   ← ignored
  | quantity=1
  ↓
Server
  |
  | 1. Validate product_id & quantity
  ↓
  | 2. Authenticate user
  ↓
  | 3. Check authorization
  ↓
  | 4. Get product_id=101 from database
  ↓
Database
  |
  | Product 101 → ₹50,000
  ↓
Server
  |
  | 5. price = database.price
  | 6. total = ₹50,000 × quantity
  ↓
Payment / Order
  |
  ↓
₹50,000

Vulnerable Code

python
product_id = request.json["product_id"]
price = request.json["price"]
quantity = request.json["quantity"]

total = price * quantity

The problem is:

python
price = request.json["price"]

because request data is controlled by the client.

Fixed Code

python
product_id = request.json["product_id"]
quantity = request.json["quantity"]

product = get_product_from_database(product_id)

if not product:
    return {"error": "Product not found"}, 404

price = product.price

total = price * quantity

Now:

text
Client says:       price = ₹10
                         ↓
                     IGNORE
                         ↓
Database says:     price = ₹50,000
                         ↓
Server uses:       ₹50,000

For a Real Payment System, Go One Step Further

Don't trust the client for any financial calculation:

  • ❌ Price
  • ❌ Discount
  • ❌ Tax
  • ❌ Shipping fee
  • ❌ Final amount
  • ❌ Currency

Instead:

text
product_id
quantity
    ↓
Server
    ↓
Fetch product price
    ↓
Validate quantity/stock
    ↓
Calculate subtotal
    ↓
Calculate permitted discount
    ↓
Calculate tax/shipping
    ↓
Calculate final amount
    ↓
Create payment/order

Also make sure the payment provider amount is generated from this server-side calculation, rather than accepting a total amount supplied by the browser.

Janmejaya Swain's Blog — Security Research & Logs