Payment bypass
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
- Intercept the checkout POST — Use Burp Suite to capture the full checkout request body. Look for
price,amount,total,currency, ordiscountfields that originate client-side. - Test price parameter tampering — Modify the price to
0.01,0,-1, and0.001. Submit each variant. Verify whether the order is fulfilled and the payment gateway was charged the tampered amount or the catalog amount. - Test currency manipulation — If a
currencyfield 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. - 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.
- 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.
- 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 + timestampwith 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 apayment_idforeign 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.