Skip to content

Commit 1d10f7d

Browse files
authored
Merge pull request #1095 from HackTricks-wiki/research_update_src_pentesting-web_rate-limit-bypass_20250711_012858
Research Update Enhanced src/pentesting-web/rate-limit-bypas...
2 parents c2941c1 + cf4df6a commit 1d10f7d

1 file changed

Lines changed: 66 additions & 3 deletions

File tree

src/pentesting-web/rate-limit-bypass.md

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,74 @@ If the target system applies rate limits on a per-account or per-session basis,
5454

5555
Note that even if a rate limit is in place you should try to see if the response is different when the valid OTP is sent. In [**this post**](https://mokhansec.medium.com/the-2-200-ato-most-bug-hunters-overlooked-by-closing-intruder-too-soon-505f21d56732), the bug hunter discovered that even if a rate limit is triggered after 20 unsuccessful attempts by responding with 401, if the valid one was sent a 200 response was received.
5656

57-
### Tools
57+
---
5858

59-
- [**https://github.com/Hashtag-AMIN/hashtag-fuzz**](https://github.com/Hashtag-AMIN/hashtag-fuzz): hashtag-fuzz is a fuzzing tool designed to test and bypass WAFs and CDNs. By leveraging advanced features such as random User-Agent and header value, random delays, handle multi-threading, selective chunking of wordlists and Round Robin proxy rotation for each chunked, it offers a robust solution for security professionals aiming to identify vulnerabilities in web applications.
59+
### Abusing HTTP/2 multiplexing & request pipelining (2023-2025)
6060

61-
{{#include ../banners/hacktricks-training.md}}
61+
Modern rate–limiter implementations frequently count **TCP connections** (or even individual HTTP/1.1 requests) instead of the *number of HTTP/2 streams* a connection contains. When the same TLS connection is reused, an attacker can open hundreds of parallel streams, each carrying a separate request, while the gateway only deducts *one* request from the quota.
62+
63+
```bash
64+
# Send 100 POST requests in a single HTTP/2 connection with curl
65+
seq 1 100 | xargs -I@ -P0 curl -k --http2-prior-knowledge -X POST \
66+
-H "Content-Type: application/json" \
67+
-d '{"code":"@"}' https://target/api/v2/verify &>/dev/null
68+
```
69+
70+
If the limiter protects only `/verify` but not `/api/v2/verify`, you can also combine **path confusion** with HTTP/2 multiplexing for *extremely* high-speed OTP or credential brute-forcing.
71+
72+
> 🐾 **Tip:** PortSwigger’s [Turbo Intruder](https://portswigger.net/research/turbo-intruder) supports HTTP/2 and lets you fine-tune `maxConcurrentConnections` and `requestsPerConnection` to automate this attack.
73+
74+
### GraphQL aliases & batched operations
75+
76+
GraphQL allows the client to send **several logically independent queries or mutations in a single request** by prefixing them with *aliases*. Because the server executes every alias but the rate-limiter often counts only *one* request, this is a reliable bypass for login or password-reset throttling.
77+
78+
```graphql
79+
mutation bruteForceOTP {
80+
a: verify(code:"111111") { token }
81+
b: verify(code:"222222") { token }
82+
c: verify(code:"333333") { token }
83+
# … add up to dozens of aliases …
84+
}
85+
```
86+
87+
Look at the response: exactly one alias will return 200 OK when the correct code is hit, while the others are rate-limited.
88+
89+
The technique was popularised by PortSwigger’s research on “GraphQL batching & aliases” in 2023 and has been responsible for many recent bug-bounty payouts.
90+
91+
### Abuse of *batch* or *bulk* REST endpoints
6292

93+
Some APIs expose helper endpoints such as `/v2/batch` or accept an **array of objects** in the request body. If the limiter is placed in front of the *legacy* endpoints only, wrapping multiple operations inside a single bulk request may completely sidestep the protection.
6394

95+
```json
96+
[
97+
{"path": "/login", "method": "POST", "body": {"user":"bob","pass":"123"}},
98+
{"path": "/login", "method": "POST", "body": {"user":"bob","pass":"456"}}
99+
]
100+
```
101+
102+
### Timing the sliding-window
103+
104+
A classic token-bucket or leaky-bucket limiter *resets* on a fixed time boundary (for example, every minute). If the window is known (e.g. via error messages such as `X-RateLimit-Reset: 27`), fire the maximum allowed number of requests **just before** the bucket resets, then immediately fire another full burst.
105+
106+
```
107+
|<-- 60 s window ‑->|<-- 60 s window ‑->|
108+
###### ######
109+
```
110+
111+
This simple optimisation can more than double your throughput without touching any other bypass technique.
64112

113+
---
114+
115+
## Tools
116+
117+
- [**https://github.com/Hashtag-AMIN/hashtag-fuzz**](https://github.com/Hashtag-AMIN/hashtag-fuzz): Fuzzing tool that supports header randomisation, chunked word-lists and round-robin proxy rotation.
118+
- [**https://github.com/ustayready/fireprox**](https://github.com/ustayready/fireprox): Automatically creates disposable AWS API Gateway endpoints so every request originates from a different IP address – perfect for defeating IP-based throttling.
119+
- **Burp Suite – IPRotate + extension**: Uses a pool of SOCKS/HTTP proxies (or AWS API Gateway) to rotate the source IP transparently during *Intruder* and *Turbo Intruder* attacks.
120+
- **Turbo Intruder (BApp)**: High-performance attack engine supporting HTTP/2 multiplexing; tune `requestsPerConnection` to 100-1000 to collapse hundreds of requests into a single connection.
121+
122+
## References
123+
124+
- PortSwigger Research – “Bypassing rate limits with GraphQL aliasing” (2023) <https://portswigger.net/research/graphql-authorization-bypass>
125+
- PortSwigger Research – “HTTP/2: The Sequel is Always Worse” (section *Connection-based throttling*) (2024) <https://portswigger.net/research/http2>
126+
127+
{{#include ../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)