On Saturday 5 July 2025 at 17:49 UTC, a TLS handshake exhaustion targeted a sports betting customer in Iberia. The attack peaked at 482.8 million requests per second and lasted 127 minutes. Traffic originated from 3466 autonomous systems in 45 countries, predominantly misconfigured open reflectors.
| Vector | TLS handshake exhaustion |
| Peak | 482.8 million requests per second |
| Duration | 127 min |
| Time to mitigation | 0.464 s |
| Attack traffic reaching origin | 0.064% |
| Legitimate traffic challenged | 0.27% |
Timeline
The attack was preceded by a hacktivist channel announcing the target. Request rates on the targeted routes exceeded their hourly baseline by a factor of 80 within 25 seconds. The risk score of participating clients crossed the challenge threshold automatically and proof-of-work difficulty rose with origin load.
What the customer saw
The customer’s status page stayed green throughout; they learned about the attack from our notification.
Recommendations
- Enable log streaming to your SIEM for faster correlation.
- Keep origin IPs out of public DNS history.
- Add a dedicated rate limit for the targeted route.
Any plans to support per-tenant limits keyed on a JWT claim?
We moved from a scrubbing provider to always-on last year; time to mitigation went from minutes to basically nothing.
We moved from a scrubbing provider to always-on last year; time to mitigation went from minutes to basically nothing.
Machine-readable ranges are at /ips.json and via the API.
The point about origin IPs leaking through certificate transparency logs is underrated.
Could you share the dataset behind the percentages?
The point about origin IPs leaking through certificate transparency logs is underrated.
Solid runbook advice. The DNS-at-2am point hit home.
We had the exact false-positive issue with CGNAT carriers. The weighting change makes sense.
Machine-readable ranges are at /ips.json and via the API.