Pricing Exploits

Price ManipulationDiscount AbusePayment Bypass

Pricing Exploits at a glance

What it is: Vulnerabilities that allow attackers to manipulate product prices, apply unauthorized discounts, or bypass payment requirements through business logic flaws.
Why it happens: Pricing exploits occur when systems trust client-supplied values, lack server-side price validation, mishandle discounts or currency conversions, or allow negative or unbounded inputs that manipulate costs.
How to fix: Validate all pricing server-side, recalculate totals from trusted sources, verify discounts and eligibility securely, and maintain detailed price audit logs.

Overview

Pricing exploits manipulate the pricing logic of e-commerce and subscription applications to obtain goods or services for less than their intended cost, or even for free. These attacks target business rules around pricing, discounts, currency conversion, and payment validation.

Common vulnerabilities include trusting client-provided prices, accepting negative quantities or prices, missing validation of discount code eligibility, inadequate validation of currency or unit conversions, and failing to recalculate totals server-side. Attackers exploit these by manipulating HTTP parameters, replaying discount codes, or exploiting rounding errors.

sequenceDiagram participant Attacker participant App participant DB Attacker->>App: Add item to cart App-->>Attacker: Cart with itemId=123, price=100 Attacker->>Attacker: Manipulate price parameter Attacker->>App: POST /checkout<br/>{itemId:123, price:1, quantity:10} App->>DB: INSERT order (trusts client price) DB-->>App: Order created for $10 App-->>Attacker: Order confirmed (should be $1000) Note over App: Missing: Server-side price validation<br/>Missing: Price recalculation
A potential flow for a Pricing Exploits exploit

Where it occurs

Pricing exploits occur in payment or checkout logic that trusts client input, lacks server-side validation, mishandles discounts or currency conversions, or allows invalid price calculations.

Impact

Pricing exploits cause direct revenue loss through underpriced sales, inventory depletion from free items, discount code fraud, chargebacks from customers discovering underpriced competitors, and business disruption from exploits at scale.

Prevention

Prevent this by recalculating all prices server-side from trusted data, rejecting client-supplied totals, validating numeric ranges and discounts, using atomic counters and decimal math, auditing all calculations, and monitoring for pricing anomalies.

Examples

Switch tabs to view language/framework variants.

Checkout accepts negative quantities for store credit

E-commerce cart allows negative item quantities, enabling attackers to receive payments instead of making them.

Vulnerable
Python • Django + Stripe — Bad
# Vulnerable: No validation on quantity
from django.http import JsonResponse
from decimal import Decimal
import stripe

def checkout(request):
    cart_items = request.POST.get('items', [])
    
    total = Decimal('0')
    for item in cart_items:
        product = Product.objects.get(id=item['product_id'])
        quantity = int(item['quantity'])  # No validation!
        
        # Vulnerable: Negative quantity allowed
        item_total = product.price * quantity
        total += item_total
    
    # Create Stripe charge
    charge = stripe.Charge.create(
        amount=int(total * 100),  # Can be negative!
        currency='usd',
        source=request.POST['stripe_token']
    )
    
    return JsonResponse({'success': True, 'total': float(total)})
  • Line 10:
  • Line 13:

Negative quantities allowed, enabling reverse charges.

Secure
Python • Django + Stripe — Good
# Secure: Validate all business logic inputs
from django.http import JsonResponse
from decimal import Decimal
import stripe

def checkout(request):
    cart_items = request.POST.get('items', [])
    
    # Validate cart before processing
    if len(cart_items) > 100:
        return JsonResponse({'error': 'Too many items'}, status=400)
    
    total = Decimal('0')
    for item in cart_items:
        product = Product.objects.get(id=item['product_id'])
        quantity = int(item['quantity'])
        
        # Validate quantity is positive and reasonable
        if quantity <= 0:
            return JsonResponse(
                {'error': f'Invalid quantity for {product.name}'}, 
                status=400
            )
        
        if quantity > 1000:
            return JsonResponse(
                {'error': 'Quantity exceeds maximum'}, 
                status=400
            )
        
        item_total = product.price * quantity
        total += item_total
    
    # Ensure total is positive
    if total <= 0:
        return JsonResponse({'error': 'Invalid total'}, status=400)
    
    # Additional sanity checks
    if total > Decimal('100000'):
        return JsonResponse(
            {'error': 'Order exceeds maximum'}, 
            status=400
        )
    
    # Create Stripe charge with validated amount
    charge = stripe.Charge.create(
        amount=int(total * 100),
        currency='usd',
        source=request.POST['stripe_token'],
        metadata={'order_id': order.id}
    )
    
    return JsonResponse({'success': True, 'total': float(total)})
  • Line 16:
  • Line 33:

Validates all inputs: quantity > 0, total > 0, reasonable maximums.

Engineer Checklist

  • Recalculate all prices server-side from product catalog

  • Never trust client-provided prices, quantities, or totals

  • Validate all numeric inputs are within valid ranges

  • Reject negative quantities or prices

  • Validate discount codes server-side (eligibility, expiration, limits)

  • Use atomic operations for limited-use discount tracking

  • Validate currency conversions server-side

  • Use decimal arithmetic for monetary calculations

  • Implement comprehensive audit logging

  • Monitor for unusual pricing patterns

  • Test with negative values, zero, and edge cases

  • Add CSRF protection to checkout forms

  • Implement idempotency for order submissions

End-to-End Example

An e-commerce site trusts client-provided prices during checkout, allowing attackers to purchase items at arbitrary prices.

Vulnerable
PYTHON
# Vulnerable: Trusts client price
@app.route('/checkout', methods=['POST'])
def checkout():
    items = request.json['items']
    
    # Vulnerable: Uses client-provided price!
    total = sum(item['price'] * item['quantity'] for item in items)
    
    order = create_order(items, total)
    process_payment(total)
    return jsonify({'order_id': order.id})
Secure
PYTHON
# Secure: Server-side price validation
from decimal import Decimal

@app.route('/checkout', methods=['POST'])
def checkout():
    items = request.json['items']
    
    # Recalculate from authoritative source
    validated_items = []
    total = Decimal('0')
    
    for item in items:
        # Get actual price from database
        product = Product.query.get(item['product_id'])
        if not product:
            return "Invalid product", 400
        
        quantity = Decimal(str(item['quantity']))
        
        # Validate quantity
        if quantity <= 0 or quantity > 1000:
            return "Invalid quantity", 400
        
        # Use server-side price
        item_total = product.price * quantity
        total += item_total
        
        validated_items.append({
            'product_id': product.id,
            'price': product.price,
            'quantity': quantity,
            'subtotal': item_total
        })
    
    # Validate discount if provided
    discount = Decimal('0')
    if 'discount_code' in request.json:
        discount_obj = validate_discount_code(
            request.json['discount_code'],
            user_id=current_user.id,
            total=total
        )
        if discount_obj:
            discount = discount_obj.calculate_discount(total)
            discount_obj.mark_used()
    
    final_total = total - discount
    
    # Create order with validated data
    order = create_order(
        user_id=current_user.id,
        items=validated_items,
        subtotal=total,
        discount=discount,
        total=final_total
    )
    
    # Log for audit
    log_order_created(order, validated_items, discount)
    
    process_payment(final_total)
    return jsonify({'order_id': order.id, 'total': str(final_total)})

Discovery

Intercept checkout requests and modify price, quantity, or discount parameters. Test with negative values and extreme numbers.

  1. 1. Test price parameter manipulation

    http

    Action

    Intercept checkout request and modify price values

    Request

    POST https://app.example.com/checkout
    Body:
    "{'items': [{'id': 123, 'price': 0.01, 'quantity': 1}]}"

    Response

    Status: 200
    Body:
    {
      "note": "Order processes at manipulated price instead of catalog price"
    }

    Artifacts

    manipulated_price price_acceptance
  2. 2. Test negative quantity exploit

    http

    Action

    Submit negative quantities to test for credit/refund

    Request

    POST https://app.example.com/cart/add
    Body:
    "{'product_id': 123, 'quantity': -10}"

    Response

    Status: 200
    Body:
    {
      "note": "Negative quantity accepted, creating credit in account"
    }

    Artifacts

    negative_quantity account_credit
  3. 3. Test discount code abuse

    http

    Action

    Attempt to reuse expired or single-use discount codes

    Request

    POST https://app.example.com/apply-coupon
    Body:
    "{'code': 'EXPIRED50', 'order_id': 456}"

    Response

    Status: 200
    Body:
    {
      "note": "Expired or exhausted discount code still applies"
    }

    Artifacts

    discount_reuse code_bypass

Exploit steps

Attacker manipulates client-side price parameters, applies expired or invalid discount codes, or uses negative quantities to credit their account.

  1. 1. Purchase items at manipulated prices

    Zero-dollar checkout

    http

    Action

    Modify price to $0.01 and purchase high-value items

    Request

    POST https://app.example.com/checkout
    Body:
    "{'items': [{'product_id': 999, 'price': 0.01, 'quantity': 100}]}"

    Response

    Status: 200
    Body:
    {
      "note": "$10,000 worth of items purchased for $1"
    }

    Artifacts

    fraudulent_order revenue_loss inventory_depletion
  2. 2. Exploit negative quantities for credits

    Generate account credits

    http

    Action

    Use negative quantities to add credits to account balance

    Request

    POST https://app.example.com/order/create
    Body:
    "{'items': [{'id': 123, 'quantity': -100, 'price': 50}]}"

    Response

    Status: 200
    Body:
    {
      "note": "$5,000 credit added to attacker's account"
    }

    Artifacts

    account_credit_fraud financial_manipulation
  3. 3. Stack and reuse discount codes

    Unlimited discount abuse

    http

    Action

    Apply multiple or expired discount codes to same order

    Request

    POST https://app.example.com/checkout
    Body:
    "{'coupons': ['SAVE50', 'SAVE50', 'EXPIRED20'], 'items': [...]}"

    Response

    Status: 200
    Body:
    {
      "note": "120% discount applied, resulting in negative total or free items"
    }

    Artifacts

    discount_stacking free_merchandise

Specific Impact

Direct financial loss from items sold below cost, fraud at scale causing significant revenue impact, and inventory depletion.

Fix

Always fetch prices from the authoritative product catalog server-side. Validate all quantities and numeric inputs. Use Decimal arithmetic for money. Validate discount codes with eligibility and usage checks. Implement comprehensive audit logging.

Detect This Vulnerability in Your Code

Sourcery automatically identifies pricing exploits vulnerabilities and many other security issues in your codebase.

Scan Your Code for Free