Skip to content

Commit 20ef0a8

Browse files
Add advisory for reqwest: SSRF via default redirect policy
1 parent 9dad93a commit 20ef0a8

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
```toml
2+
[advisory]
3+
id = "RUSTSEC-0000-0000"
4+
package = "reqwest"
5+
date = "2026-02-22"
6+
url = "https://github.com/seanmonstar/reqwest/issues/2260"
7+
categories = ["denial-of-service"]
8+
keywords = ["ssrf", "redirect", "private-network", "metadata"]
9+
10+
[versions]
11+
patched = []
12+
unaffected = []
13+
```
14+
15+
# reqwest: SSRF via Default Redirect Policy Following to Private Networks
16+
17+
reqwest follows up to 10 redirects by default via `redirect::Policy::default()`.
18+
This policy does not filter redirect targets against private/internal IP ranges
19+
(RFC 1918, link-local, loopback, cloud metadata endpoints).
20+
21+
An attacker who can influence a URL fetched by a server-side application using
22+
reqwest can redirect the request to internal services (e.g., AWS/GCP/Azure
23+
metadata at 169.254.169.254, localhost services, internal network hosts),
24+
enabling Server-Side Request Forgery (SSRF, CWE-918).
25+
26+
This is a well-known SSRF attack class that browsers mitigate with private
27+
network access controls, but reqwest provides no equivalent built-in protection.
28+
29+
Any server-side application fetching user-controlled URLs with the default
30+
redirect policy is vulnerable.
31+
32+
## Mitigation
33+
34+
Use a custom redirect policy that validates redirect targets:
35+
36+
```rust
37+
let policy = reqwest::redirect::Policy::custom(|attempt| {
38+
let url = attempt.url();
39+
if is_private_ip(url) {
40+
attempt.stop()
41+
} else {
42+
attempt.follow()
43+
}
44+
});
45+
```

0 commit comments

Comments
 (0)