Browse CTFs New CTF Sign in

Payment bypass

web_injection_logic Difficulty 1–5 30 min certifiable

Theory

Why This Matters

In 2019, a penetration tester assessing a mid-tier SaaS platform discovered that the checkout POST body included a price field. By submitting {"price": 0.01, "product_id": "enterprise-annual"}, they provisioned an enterprise subscription for one cent. The platform's payment gateway charged the submitted amount without verifying it against the server's own product catalog. A separate class of attack — direct POST to the order confirmation endpoint — was documented on an e-commerce platform where navigating to /checkout/complete?order_id=123 after abandoning the payment page triggered order fulfillment without any payment gateway interaction. Both findings represent the same failure: the application trusted the client to represent the price and the payment outcome, rather than deriving these from authoritative server-side records.

Core Concept

Payment flow bypass encompasses any technique that causes the application to fulfill an order without a valid, server-verified payment equal to the catalog price. The attack surface spans three mechanisms.

Price parameter injection: the HTTP request body or query string contains a price, amount, or total field that the server forwards to the payment gateway unchanged. An attacker modifies this to 0.01, 0, or a negative value. With a negative price, some platforms issue a credit to the attacker's account instead of charging them.

Payment step skipping: the checkout flow is a multi-step sequence (cart → shipping → payment → confirmation). If the confirmation endpoint performs fulfillment based solely on a URL parameter (order_id) without verifying that the linked order has a successful payment record, an attacker can POST directly to the confirmation endpoint, bypassing the payment step entirely.

Payment gateway callback forgery: after processing, the payment gateway redirects the browser to a success or failure URL. If the application reads the payment outcome from parameters on the redirect URL (?status=success&transaction_id=TX-001) rather than from a server-to-server webhook, an attacker can craft a success redirect manually. Signed cart tokens bind the cart contents and total to a server-generated HMAC, preventing price tampering without key knowledge. Webhook-only payment confirmation eliminates the callback forgery vector entirely.

Technical Deep-Dive

# Attack 1: Price parameter injection in checkout POST
POST /api/checkout HTTP/1.1
Host: shop.example.com
Cookie: session=abc123
Content-Type: application/json

{
  "cart_id": "CART-555",
  "product_id": "pro-annual",
  "price": 0.01,
  "currency": "USD",
  "payment_method": "card_tok_visa_4242"
}

# Server forwards price=0.01 to payment gateway, charges $0.01, fulfils pro-annual plan

# Attack 2: Currency manipulation (USD → lower-value currency with same numeric amount)
POST /api/checkout HTTP/1.1
Host: shop.example.com
Cookie: session=abc123
Content-Type: application/json

{"cart_id": "CART-555", "price": 99.99, "currency": "IDR"}
# 99.99 IDR ≈ $0.006 USD — if server charges 99.99 in the submitted currency

# Attack 3: Direct POST to confirmation endpoint (payment step skip)
# Attacker creates an order but abandons payment page, captures order_id
POST /checkout/complete HTTP/1.1
Host: shop.example.com
Cookie: session=abc123
Content-Type: application/json

{"order_id": "ORD-9901"}

# Vulnerable server: looks up order, checks status == "pending", marks fulfilled
# No check that a payment record exists for ORD-9901

# Attack 4: Callback forgery — payment gateway redirects to:
# /checkout/callback?status=success&transaction_id=FAKE-TX&order_id=ORD-9901
# Attacker manually requests this URL after abandoning payment
GET /checkout/callback?status=success&transaction_id=FAKE-TX&order_id=ORD-9901 HTTP/1.1
Host: shop.example.com
Cookie: session=abc123
# Negative price test — does the application issue a credit?
import requests

s = requests.Session()
s.cookies.set('session', 'abc123')

r = s.post('https://shop.example.com/api/checkout', json={
    'cart_id': 'CART-555',
    'product_id': 'basic-monthly',
    'price': -50.00,
    'currency': 'USD',
    'payment_method': 'card_tok_visa_4242'
})
print(r.status_code, r.json())
# Watch for: wallet_credit, balance_added, or negative charge in payment gateway logs

Security Assessment Methodology

  1. Intercept the checkout POST — Use Burp Suite to capture the full checkout request body. Look for price, amount, total, currency, or discount fields that originate client-side.
  2. Test price parameter tampering — Modify the price to 0.01, 0, -1, and 0.001. Submit each variant. Verify whether the order is fulfilled and the payment gateway was charged the tampered amount or the catalog amount.
  3. Test currency manipulation — If a currency field is present, change it from a high-value to a low-value currency while keeping the numeric amount the same. Confirm the charged amount in the payment gateway or account statement.
  4. Map the checkout multi-step flow — Identify the URL for each checkout step. Attempt to POST directly to the confirmation or complete endpoint with a pending order_id, bypassing the payment step.
  5. Capture and forge payment callbacks — Identify the success redirect URL from the payment gateway integration. Craft a forged success URL with a fake transaction_id and send it directly, then check whether the order is fulfilled.
  6. Test negative price for credit issuance — Submit a negative price or amount. Check the user's wallet balance and any credit memos generated.

Defensive Countermeasure — Never accept price or currency from client requests. At checkout initiation, generate a signed cart token (HMAC-SHA256 of cart_id + total + currency + timestamp with a server-side secret) and include it in the payment request to the gateway. Verify the token on callback. Confirm payment exclusively via server-to-server webhooks from the payment gateway — never from redirect URL parameters. Require a payment_id foreign key in the orders table and enforce a NOT NULL constraint so that no order can be marked fulfilled without a linked, gateway-confirmed payment record.

Common Assessment Errors

  • Only testing price=0 — Zero often triggers a different validation path ("free item") that may be intentionally allowed for free-tier products. Test 0.01 (below minimum), negative values, and extreme currency mismatches.
  • Missing the currency manipulation vector — Applications that support multi-currency often validate the amount in the submitted currency, not in a normalised base currency. Always test currency field modification independently of price.
  • Not following the full redirect chain — Payment gateway integrations involve multiple redirects. Trace the complete redirect chain with Burp Proxy to identify where the application reads the payment outcome.
  • Assuming HTTPS prevents interception — The callback forgery attack does not require intercepting HTTPS traffic — the attacker simply constructs the callback URL themselves after abandoning the payment page. No MitM is required.
  • Ignoring payment webhook signature verification — If the application verifies webhook signatures, callback forgery via redirect URL is the relevant bypass. Test both vectors separately.
  • Not testing with a real low-value transaction — Some applications implement anti-tamper checks only for amounts above a threshold. A $0.01 charge may legitimately process and reveal the vulnerability more clearly than a $0 attempt that is caught by a "minimum amount" check.

NICE Framework Alignment

Code Knowledge/Skill/Task Statement How This Card Develops It
K0007 Knowledge of authentication, authorization, and access control methods Links payment verification to authorization of order fulfillment actions
K0065 Knowledge of web application security testing techniques Develops price injection, step-skipping, and callback forgery testing methods
K0070 Knowledge of system and application security threats and vulnerabilities Identifies payment bypass as a high-impact business logic vulnerability class
S0001 Skill in conducting vulnerability scans and recognizing vulnerabilities in security systems Trains systematic checkout flow analysis for client-trusted payment parameters
T0028 Identify and analyze vulnerabilities and risks in web applications Applies data-flow analysis to identify where price authority originates in checkout flows
T0570 Perform technical security assessments of web applications Structures end-to-end payment bypass assessment from parameter identification through fulfillment proof

Further Reading

  • OWASP Testing Guide v4.2, OTG-BUSLOGIC-008: Test Unexpected File Types — OWASP Foundation
  • Payment Card Industry Data Security Standard (PCI-DSS) v4.0, Requirement 6.4 — PCI SSC
  • PortSwigger Web Security Academy: Business Logic Vulnerabilities — PortSwigger

Challenge Lab

Reinforce your learning with a hands-on generated challenge based on this card's competency.