← Back to all reports

GraphQL Gift Card PIN Enumeration with No Rate Limiting

Reported Apr 16, 2026
Severity High
Platform Web / Mobile API
Vulnerability Class Missing Rate Limit + Predictable Tokens (CWE-307, CWE-330)
Target Type Fashion E-commerce
Impact Instant theft of other customers' gift cards

The Risk

Anyone with a free account on a major fashion e-commerce platform and one purchased gift card could find and instantly spend other customers' unredeemed gift cards. There was no lockout, no slowdown, and no warning to the legitimate recipient. During testing, a $100 card belonging to a real customer was found and redeemed in under twenty seconds. Cards on the platform sell for up to $500 each and are issued in bulk for corporate gifting, so the value at risk was significant.

The Vulnerability

Two flaws compounded into instant gift card theft:

1. No rate limiting on the GraphQL redemption mutation

The customerRedeemGiftCard mutation on the GraphQL endpoint had no rate limit. The equivalent legacy REST endpoint was protected by a Cloudflare rule that triggered after roughly 22 requests, but that rule did not cover the GraphQL endpoint. During testing, 23,000 redemption probes were sent in 85 seconds (about 270 requests per second) with zero throttling, no challenge, and no lockout.

2. Sequential PIN issuance within a batch

Gift card PINs were 19 digits long with predictable structure:

6087480024515610906
^^^^^^^^             fixed prefix
        ^^^^^        batch ID (sequential per issuance window)
             ^^^     fixed segment
                ^^^  counter (sequential within batch)

Cards in the same batch shared the same batch ID. Within a batch the counter incremented predictably as cards were issued. An attacker holding any one card knew that cards within plus or minus a hundred positions had been issued in the same window.

The Attack

  1. The attacker creates a free account on the platform and obtains a bearer token by logging in.
  2. They purchase one low-value gift card to use as a seed position in the issuance sequence.
  3. They run an asynchronous script that fires the redemption mutation against PIN values plus or minus 200 from the seed, using 20 concurrent workers.
  4. Invalid PINs return BAD_REQUEST with HTTP 200. Valid unredeemed PINs return a StoreCredit object with the card's value and a transaction ID, and the card is instantly credited to the attacker's account.
  5. The full 203-probe scan completes in under 20 seconds. With 50 concurrent workers it finishes in under 10.

Confirmed test result

One scan was run from the seed position. A $100 gift card belonging to a real third-party customer was found at offset +91 and redeemed in a single mutation. The card needed to be reinstated for the original recipient as part of the disclosure.

FieldValue
Card found at offset+91 from seed
Value stolen$100.00
Probes sent203
Time takenApproximately 18.5 seconds
Concurrency20 workers

The Impact

Gift cards on the platform were sold in denominations up to $500 and issued in bulk for corporate gifting and promotions. An attacker who purchased one low-value card obtained a position in the issuance sequence and could scan adjacent positions at unlimited speed. The attack scaled linearly with concurrency.

There was no detection on the server side, no lockout on repeated bad PINs, and no notification to the legitimate recipient. A stolen card could not be refunded after the fact because the redemption was atomic. The legitimate recipient would only discover the theft when they tried to use a card that already showed a zero balance.

Remediation

  • Apply rate limiting to the redemption mutation. Three to five attempts per account per hour matches the existing protection on the REST endpoint.
  • Extend the existing WAF rate-limit rule to cover the GraphQL endpoint, not just the legacy REST path.
  • Replace sequential or near-sequential PIN generation with cryptographically random values of at least 128 bits of entropy. Predictable structure inside a PIN must be removed.
  • Add a CAPTCHA or step-up challenge after two consecutive failed redemption attempts in a single session.
  • Alert on sustained redemption failure patterns from a single account and lock the account pending review.