Quick answer
A corporate URL shortener, used to send purchase receipts by SMS, had three problems that together become critical: 6-character codes with low entropy, no rate limiting, and a destination page with no authentication. A single machine at 15 req/s extracted PII (phone, BIN+last 4 of the card, purchased products) from ~300 people per hour.
The chain of flaws
Three independent problems that, when combined, become critical:
[Códigos 6 chars baja entropía]
↓
[Sin rate limiting en el acortador]
↓
[Página de ticket sin autenticación]
↓
[PII completa expuesta]
Flaw 1 — Low-entropy codes
The shortener's codes are 6-character alphanumeric strings. The theoretical space is large, but the density of valid codes active in production is high enough that random enumeration returns results consistently.
Flaw 2 — No rate limiting
The shortener doesn't block or challenge requests in volume from a single IP. At 15 req/s the server responds normally. No CAPTCHA, no throttling, no 429. Enumeration can run indefinitely.
Flaw 3 — Tickets with no authentication (the main flaw)
The destination ticket pages show all of the customer's information without asking for any verification. Anyone with the link sees the same as the legitimate customer:
- Full phone number.
- Date and physical store where the purchase was made.
- List of products with prices.
- Total amount.
- Partial card number — BIN + last 4 digits (
435785******0916). - Ticket QR code.
How the attack works
Generar código aleatorio de 6 chars
↓
GET acortador/{código} (sin seguir redirección)
↓
¿HTTP 301/302/307?
No → intentar otro código
Sí → código válido
↓
Extraer header Location → URL del ticket con teléfono en base64
↓
Decodificar base64 → teléfono obtenido sin cargar la página
↓
Cargar página del ticket (sin autenticación)
↓
PII completa expuesta
The phone travels encoded in base64 directly in the redirect URL:
Location: https://target.tld/user-identification.html?phone=NjM0XXXXXXXX==&...
This means you don't even need to load the ticket page to obtain the phone number. Reading the Location header is enough.
The PoC, in one line:
python3 bruteforce.py -r 15 -o hits.txt
Impact
High-credibility smishing. The attacker knows the phone, what was bought, at which store and when. An SMS with that exact data easily gets past any victim's cognitive filters.
Bank fraud. BIN + last 4 digits is enough to pass basic identity checks at many institutions if the attacker calls impersonating the customer.
Mass profiling. By correlating tickets by phone, detailed purchase histories of specific individuals are built.
GDPR. Phone numbers, card data and purchase history of EU customers without any protection. Notifiable breach under Article 33.
What to look for in similar targets
Corporate shorteners are a commonly overlooked vector. When you find one:
- How many characters does the code have? Which alphabet does it use?
- Is there rate limiting on the resolution endpoint?
- Does the destination URL contain sensitive parameters? Are they in base64 (which is not encryption)?
- Does the destination page require authentication or is it directly accessible?
- Do the links have an expiration?
The pattern shortener + a sensitive page with no auth appears frequently in transactional notification systems: tickets, invoices, order confirmations, medical appointments.
Fix
| Point | Solution |
|---|---|
| Ticket pages | Identity verification before showing data (OTP, last digits of the phone) |
| Shortener | Rate limiting + enumeration detection |
| Short codes | Higher entropy + link expiration |
| PII in the URL | Don't expose sensitive data in URL parameters, nor in base64 |
Related labs
Practice enumerating short links and hunting sensitive pages with no auth: Information Disclosure labs.
Practice this in a lab
Information Disclosure
Keep learning · free account
Save your progress, unlock advanced payloads and rank your flags.
Related articles
Mass PII Extraction via GraphQL — 93 real profiles in 1 hour
A contact-sync GraphQL endpoint with no rate limiting, no ownership verification and batching of 200 numbers per request. Phone → real identity resolution.
API keys exposed in public HTML — $2,000 without a single bypass
A productivity platform shipped a third-party CMS token in window.CONFIG. Anyone with DevTools could download paid templates. How to hunt this pattern in any SPA app.
0-click Account Takeover — OTP brute force + Email Normalization
Two separate flaws look minor. Together, they hand you full ATO knowing only the email. Real bounty: €560 and 12 minutes of exploitation.