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
Copy file name to clipboardExpand all lines: src/pentesting-web/cors-bypass.md
+37-5Lines changed: 37 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -106,25 +106,39 @@ Note that usually (depending on the content-type and headers set) in a **GET/POS
106
106
107
107
### **Local Network Requests Pre-flight request**
108
108
109
-
1.**`Access-Control-Request-Local-Network`**: This header is included in the client's request to signify that the inquiry is aimed at a local network resource. It serves as a marker to inform the server that the request originates from within the local network.
110
-
2.**`Access-Control-Allow-Local-Network`**: In response, servers utilize this header to communicate that the requested resource is permitted to be shared with entities outside of the local network. It acts as a green light for sharing resources across different network boundaries, ensuring controlled access while maintaining security protocols.
109
+
Modern browsers and the current **Private Network Access (PNA)** draft use the headers **`Access-Control-Request-Private-Network: true`** in the preflight and **`Access-Control-Allow-Private-Network: true`** in the response. Older articles and PoCs may still refer to `Local-Network` header names, but for current testing you should expect the `Private-Network` variants.
111
110
112
-
A **valid response allowing the local network request** needs to have also in the response the header `Access-Controls-Allow-Local_network: true`:
111
+
A **valid response allowing the local network request** needs to also include `Access-Control-Allow-Private-Network: true`:
113
112
114
113
```
115
114
HTTP/1.1 200 OK
116
115
...
117
116
Access-Control-Allow-Origin: https://example.com
118
117
Access-Control-Allow-Methods: GET
119
118
Access-Control-Allow-Credentials: true
120
-
Access-Control-Allow-Local-Network: true
119
+
Access-Control-Allow-Private-Network: true
121
120
Content-Length: 0
122
121
...
123
122
```
124
123
124
+
And the preflight request will look similar to:
125
+
126
+
```http
127
+
OPTIONS / HTTP/1.1
128
+
Host: router.local
129
+
Origin: https://example.com
130
+
Access-Control-Request-Method: GET
131
+
Access-Control-Request-Private-Network: true
132
+
```
133
+
134
+
> [!NOTE]
135
+
> Chrome's PNA rollout changed several times during 2024. As of **October 9, 2024**, Chrome documented that **PNA preflights were on hold** because of compatibility problems, while secure-context restrictions remained in place. Therefore, keep testing both the **spec-compliant preflight flow** and the older **"works in practice because enforcement is incomplete"** behavior.
136
+
125
137
> [!WARNING]
126
138
> Note that the linux **0.0.0.0** IP works to **bypass** these requirements to access localhost as that IP address is not considered "local".
127
139
>
140
+
> Chrome also documented that **`0.0.0.0/8`** is now treated as part of Private Network Access, so this trick is browser/version-dependent and should be re-tested instead of assumed.
141
+
>
128
142
> It's also possible to **bypass the Local Network requirements** if you use the **public IP address of a local endpoint** (like the public IP of the router). Because in several occasions, even if the **public IP** is being accessed, if it's **from the local network**, access will be granted.
Recent updates to PortSwigger's cheat sheet added more **Safari-oriented domain splitting** payloads that are worth fuzzing when the target validates the `Origin` header using regexes or home-grown URL parsers:
276
+
277
+
```text
278
+
https://example.com.{.attacker.com/
279
+
https://example.com.}.attacker.com/
280
+
https://example.com.`.attacker.com/
281
+
```
282
+
283
+
These are useful when the backend only checks whether the supplied origin *starts with* or *contains* the trusted hostname, while the browser still treats the attacker-controlled suffix as the effective origin boundary.
284
+
285
+
Also remember that modern origin fuzzing should not stop at hostname suffixes. The current PortSwigger cheat sheet includes payload families for:
286
+
287
+
-**Domain allow-list bypasses**: attacker-controlled domains that still satisfy naive prefix/suffix/substring checks.
288
+
-**Fake-relative absolute URLs**: browser-valid absolute URLs that application code may parse as relative.
289
+
-**Loopback/IP normalizations**: alternative IPv4/IPv6 forms useful when CORS logic tries to block `localhost`, `127.0.0.1`, or cloud metadata endpoints by string comparison.
290
+
261
291
### **Other funny URL tricks**
262
292
263
293
@@ -455,6 +485,7 @@ DoH simply tunnels the classic RFC1035 DNS wire format inside HTTPS (usually a P
455
485
**Fuzz possible misconfigurations in CORS policies**
-[NCC Group - Impact of DNS over HTTPS (DoH) on DNS Rebinding Attacks](https://www.nccgroup.com/research-blog/impact-of-dns-over-https-doh-on-dns-rebinding-attacks/)
0 commit comments