Gift Card Balance Manipulation: Charging Stored Value You Did Not Buy
Gift cards are miniature bank accounts with weaker audits. If any redeem or check-balance endpoint trusts a client-supplied amount, stored value becomes a suggestion.
Work carefully. Programs often restrict live gift-card testing—use issued test cards or tiny denominations you purchased yourself.
Follow the card object
Typical flows: purchase → email code → POST /giftcards/redeem → balance applied to wallet or cart. Intercept redeem and balance calls. Fields to mutate:
amount/balance/valuecurrencycard_idor codepinif present
Set amount higher than the card's real value. If the wallet credits your figure, stop and document. Try negative amounts that might credit the card when the logic inverts. Try applying the same code twice across parallel requests—double redeem is a sibling of balance manipulation.
Guessability matters. Sequential codes, short numeric PINs, and unprotected GET /giftcards/{code} balance oracles turn manipulation into theft against other buyers. Only probe codes you own unless the program runs a dedicated gift-card scope with test batches.
Cart apply versus wallet credit
Some stores never put value in a wallet; they attach the card to a cart line. Edit the applied credit in the checkout payload independently of the card. Others let you split one card across orders—race two checkouts and see if both receive the full balance.
Currency mismatch is underrated. Redeem a USD card while your account is EUR without conversion, or supply amount: 100 with currency: "JPY" when the card was USD 100. Weird FX paths can mint value.
Integer overflow on legacy platforms still appears: 999999999 balances, or cents versus dollars confusion where 100 means a dollar in one service and a cent in another.
Refund-to-gift-card paths can reopen a closed loop: buy with card, refund to gift card, manipulate the refund credit, then spend. Stay inside your own orders so you are not touching stranger funds.
Keep the proof non-abusive
Show original balance inquiry, tampered redeem request, and resulting wallet or order credit. Use a unique order memo. Refund or reverse when the program asks. Do not drain arbitrary cards.
Recommend authoritative balances in the ledger service, ignore client amounts, lock rows during redeem, bind codes to unguessable tokens, rate-limit balance checks, and alert on redeem amounts that disagree with issuance records.
Partial redeem APIs are worth a dedicated test: request a redeem of $5 from a $25 card, then change amount to $25 on a parallel call. If both succeed, you minted value. Keep both redemptions on cards you purchased so the ledger story stays clean for triage.
Check whether deactivated or expired cards still accept a balance patch through an admin-shaped field name on the customer API. Naming like admin_credit in a public route is a giveaway.
CWE-840 (business logic) fits when the crypto of the code is fine but the accounting is not. Frame it that way so triage does not bounce you as "just a coupon."