The document discusses the vulnerabilities and inconsistencies that arise when using reverse proxies in web architecture, emphasizing the importance of proper configuration to prevent security issues. It details various types of attacks, including server-side and client-side attacks, and explores how different web servers and proxies handle URL parsing and normalization inconsistently. The author highlights the risks of cache misconfiguration and presents examples of how attackers can exploit these weaknesses to bypass security restrictions and manipulate cached responses.
Server side attacks
Wecan send it:
GET //test/../%2e%2e%2f<>.JpG?a1=”&?z#/admin/ HTTP/1.1
Host: victim.com
13.
Client side attacks
<imgsrc=”//test/../%2e%2e%2f<>.JpG?a1=”&?z#/admin/”>
GET //..%2f%3C%3E.jpg?a1=%22&?z HTTP/1.1
Host: victim.com
- Browser parses, decodes and normalizes.
- Differences between browsers
- Doesn’t normalize %2f (/..%2f -> /..%2f)
- <> " ' - URL-encoded
- Multiple ? in query
14.
Possible attacks
Server-side attacks:
-Bypassing restriction (403 for /app/)
- Misrouting/Access to other places (/app/..;/another/path/)
Client-side attacks:
- Misusing features (cache)
- Misusing headers modification
Nginx as revproxy. C2
- Configuration 2. Without trailing slash
location / {
proxy_pass http://origin_server;
}
- urldecodes/normalizes/applies,
- but sends unprocessed path
19.
Nginx + Weblogic
-# is an ordinary symbol for Weblogic
Block URL: location /Login.jsp
GET /#/../Login.jsp HTTP/1.1
Nginx: / (after parsing), but sends /#/../Login.jsp
Weblogic: /Login.jsp (after normalization)
20.
Nginx + Weblogic
-Weblogic knows about path-parameters (;)
- there is no path after (;) (unlike Tomcat’s /path;/../path2)
location /to_app {
proxy_pass http://weblogic;
}
/any_path;/../to_app
Nginx:/to_app (normalization), but sends /any_path;/../to_app
Weblogic: /any_path (after parsing)
21.
Nginx. Wrong config
-Location is interpreted as a prefix match
- Path after location concatenates with proxy_pass
- Similar to alias trick
location /to_app {
proxy_pass http://server/app/;
}
/to_app../other_path
Nginx: /to_app../
Origin: /app/../other_path
Haproxy/nuster
acl restricted_page path_beg,url_dec/admin
block if restricted_page !network_allowed
url_dec urldecodes path
No access?
url_dec sploils path_beg
path_beg includes only /admin
Bypass: /admin/
35.
Varnish or Haproxy
Hostcheck bypass:
if (req.http.host == "safe.example.com" ) {
set req.backend_hint = foo;
}
Only "safe.example.com" value?
Bypass using (malformed) Absolute-URI:
GET httpcococo://unsafe-value/path/ HTTP/1.1
Host: safe.example.com
36.
Varnish
GET httpcoco://unsafe-value/path/ HTTP/1.1
Host:safe.example.com
Varnish: safe.example.com, resends whole request
Web-server(Nginx, Apache, …): unsafe-value
- Most web-server supports and parses Absolute-URI
- Absolute-URI has higher priority that Host header
- Varnish understands only http:// as Absolute-URI
- Any text in scheme (Nginx, Apache) tratata://unsafe-value/
37.
Client Side attacks
Ifproxy changes response/uses features for specific paths,
an attacker can misuse it due to inconsistency of parsing of web-
server and reverse proxy server.
38.
Misusing headers
modification
location /iframe_safe/{
proxy_pass http://origin/iframe_safe/;
proxy_hide_header "X-Frame-Options";
}
location / {
proxy_pass http://origin/;
}
- only /iframe_safe/ path is allowed to be framed
- Tomcat sets X-Frame-Options deny automatically
Caching
- Who iscaching? browsers, proxy...
- Cache-Control in response (Expires)
- controls what and where and for how long a response can be cached
- frameworks sets automatically (but not always!)
- public, private, no-cache (no-store)
- max-age, ...
- Cache-Control: no-cache, no-store, must-revalidate
- Cache-Control: public, max-age=31536000
- Cache-Control in request
- Nobody cares? :)
43.
Implementation
- Only GET
-Key: Host header + unprocessed path/query
- Nginx: Cache-Control, Set-Cookie
- Varnish: No Cookies, Cache-Control, Set-Cookie
- Nuster(Haproxy): everything?
- CloudFlare: Cache-Control, Set-Cookie, extension-
based(before ?)
- /path/index.php/.jpeg - OK
- /path/index.jsp;.jpeg - OK
44.
Aggressive caching
- WhenCache-Control check is turned off
- *or CC is set incorrectly by web application (custom session?)
45.
Misusing cache
- Webcache deception
- https://www.blackhat.com/docs/us-17/wednesday/us-17-Gil-Web-
Cache-Deception-Attack.pdf
- Force a reverse proxy to cache a victim’s response from origin server
- Steal user’s info
- Cache poisoning
- https://portswigger.net/blog/practical-web-cache-poisoning
- Force a reverse proxy to cache attacker’s response with malicious
data, which the attacker then can use on other users
- XSS other users
46.
Misusing cache
- Whatif Aggressive cache is set for specific path /images/?
- Web cache deception
- Cache poisoning with session
47.
Path-based
Web cache deception
location/images {
proxy_cache my_cache;
proxy_pass http://origin;
proxy_cache_valid 200 302 60m;
proxy_ignore_headers Cache-Control Expires;
}
Web cache deception:
- Victim: <img src=”http://victim.com/images/..;/index.jsp”>
- Attacker: GET /images/..;/index.jsp HTTP/1.1
48.
Cache poisoning
with session
nustercache on
nuster rule img ttl 1d if { path_beg /img/ }
Cache poisoning with session:
- Web app has a self-XSS in /account/attacker/
- Attacker sends /img/..%2faccount/attacker/
- Nuster caches response with XSS
- Victims opens /img/..%2faccount/attacker/ and gets XSS
49.
Varnish
sub vcl_recv {
if(req.url ~ ".(gif|jpg|jpeg|swf|css|js)(?.*|)$") {
set req.http.Cookie-Backup = req.http.Cookie;
unset req.http.Cookie;
}
sub vcl_hash {
if (req.http.Cookie-Backup) {
set req.http.Cookie = req.http.Cookie-Backup;
unset req.http.Cookie-Backup;
}
Varnish
if (bereq.url ~".(gif|jpg|jpeg|swf|css|js)(?.*)$") {
Web cache deception:
<img src=”http://victim.com/admin.php?q=1&.jpeg?xxx”>
Cache poisoning:
- /account/attacker/?.jpeg?xxx
52.
- Known implementations
-Headers:
- CF-Cache-Status: HIT (MISS)
- X-Cache-Status: HIT (MISS)
- X-Cache: HIT (MISS)
- Age: d+
- X-Varnish: d+ d+
- Changing values in headers/body
- Various behaviour for cached/passed (If-Range, If-Match, …)
What is cached?
53.
Conclusion
- Inconsistency betweenreverse proxies and web servers
- Get more access/bypass restrictions
- Misuse reverse proxies for client-side attacks
- Everything is trickier in more complex systems
- Checked implementations:
https://github.com/GrrrDog/weird_proxies