Multi-endpoint race conditions
Cadena de race condition multi-endpoint: comprar gift cards en paralelo antes de que el checkout consolide el balance, acumulando crédito sin límite mediante una ventana de carrera entre endpoints.
Target Overview & Vulnerability Summary
El objetivo es comprar el "lightweight l33t leather jacket" (1337 de saldo. La tienda vende gift cards de 10 $ que generan un código canjeable. Una race condition entre los endpoints de compra y canje permite multiplicar el crédito: la validación de balance y la generación del código de gift card no son atómicas, abriendo una ventana de carrera multi-endpoint.
| Campo | Valor |
|---|---|
| Severidad | Alta (abuso financiero: generación de crédito ilimitado) |
| Endpoints involucrados | POST /cart (añadir), /cart/checkout, POST /gift-card (canjear) |
| Root cause | Validación de balance/stock no atómica entre operaciones de checkout y canje |
Technical Breakdown & Exploitation Flow
1. Contexto del flujo
- Saldo disponible: 100 (faltan 1237 $).
- Las gift cards de 10 $ generan un código canjeable tras el checkout. El cupón de descuento es distinto de la gift card:
coupon code != gift card.
Compra normal de una gift card:
POST /cart HTTP/2
Host: 0a050040037c3fbb811c989b00da009e.web-security-academy.net
productId=2&redir=PRODUCT&quantity=1
Resultado:
Store credit: $90.00
Your order is on its way!
Gift Card $10.00 1
Total: $10.00
You have bought the following gift cards:
Code
5nXhYcOvSK
El código obtenido se canjea posteriormente:
POST /gift-card HTTP/2
Host: <LAB-ID>.web-security-academy.net
Cookie: session=<SESSION_ID>
Content-Type: application/x-www-form-urlencoded
gift-card=5nXhYcOvSK
Cada canje devuelve 10 $ de crédito. Se dispone de dos códigos (KBhI12MUH6 corresponde al cupón de descuento; 5nXhYcOvSK a la gift card).
2. Endpoints relevantes
/cart/checkout— consolida la compra y descuenta el balance./cart— gestiona el carrito (añadir producto conproductId,redir,quantity).POST /gift-card— canjea un código y acredita 10 $ (gift-card=<CODE>)./cart?couponError=INVALID_COUPON&coupon=KBhI12MUH6— aplica el cupón de descuento al carrito.
3. La ventana de carrera multi-endpoint
Existe una race window explotable entre el checkout y el canje: si la validación del balance se ejecuta antes de que se acredite el crédito del canje (o si múltiples checkouts leen el mismo balance sin serialización), se pueden comprar varias gift cards en paralelo aprovechando fracciones de segundo. Cada checkout genera un código nuevo de gift card, y cada código canjeado incrementa el crédito; repitiendo la ráfaga el saldo crece hasta cubrir los 1337 $.
Plan de ataque:
- Encadenar varias requests
POST /cart+/cart/checkouten paralelo para generar múltiples gift cards en la misma ventana. - Canjear todos los códigos con
POST /gift-carden paralelo. - Repetir la ráfaga hasta acumular el saldo necesario.
- Añadir el producto objetivo (1337 $) y completar la compra.
Root Cause Analysis
La causa raíz es la falta de atomicidad entre la validación del balance y el registro de la compra/canje. El servidor lee el saldo del usuario, genera la gift card y actualiza el balance en pasos separados sin locking ni transacción: requests concurrentes leen el mismo saldo antiguo y todas lo aprueban. Es un TOCTOU multi-endpoint: la sección crítica abarca dos endpoints que comparten el mismo estado (balance), en lugar de residir en un único punto serializado.
Secure Remediation
- Serializar la lógica de balance en el backend con transacciones atómicas:
with db.transaction():
balance = db.get_balance(user, for_update=True) # SELECT ... FOR UPDATE
if balance < order_total:
abort(400)
db.debit(user, order_total)
code = db.issue_gift_card(user)
- Un solo endpoint transaccional que valide y debite en la misma operación, de modo que las requests concurrentes se encolen sobre el lock de fila.
- Para el canje:
UPDATEcondicional que acredite solo si el código está sin usar (operación atómicaRETURNING). - Rate limiting sobre compra/canje por usuario y monitorización de anomalías de saldo.