Labs Covered
This write-up focuses on the following PRACTITIONER-level labs from the PortSwigger Web Security Academy related to Host Header Attacks and related HTTP parsing vulnerabilities:
3 Web cache poisoning via ambiguous requests
This lab demonstrates how ambiguous HTTP requests can be used to poison web caches and serve malicious content to users.
4 Routing-based SSRF
This lab shows how improper routing based on Host headers can lead to Server-Side Request Forgery (SSRF) vulnerabilities.
5 SSRF via flawed request parsing
This lab demonstrates how flawed parsing of HTTP requests can be exploited to perform SSRF attacks.
6 Host validation bypass via connection state attack
This lab demonstrates how attackers can bypass host validation mechanisms by manipulating connection states.
LAB 3 - Web cache poisoning via ambiguous requests
Lab Description
Solution
Firstly, send a request to the “/” endpoint and observe the behavior. Everythings as it expected. Next, let’s proceed to manipulate the host header and analyze the response.
Also we can see that manipulated host header give us error in and reflected in reponse
Randomly add :90 and I can see tha Xcachehit, age,Cache control header and our host is also reflected in reponse
As you can observe, when a malformed Host header is used, it is reflected in the response body with a 504 response code. I attempted various methods such as adding a port or using single quotes, but I was unable to modify the response. Whatever I typed in the Host header was reflected in the response exactly. The next testing approach is duplicating the Host header, which seems OK given the lab’s name. However, it’s crucial to monitor the Age and X-Cache headers for the cache mechanism. These headers can provide valuable insights during the attack.
• Cache-Control: max-age=30: This tells browsers to cache the content for up to 30 seconds before checking with the server for an update.
• Age: 17: This indicates the content has been in the server’s cache for 10 seconds.
• X-Cache: hit: This is likely a custom header from the server software, informing you that the content was retrieved from the server’s cache (not freshly generated).
So we have send this request Host: test.net”></script><script>alert(1)</script> in host,and I can see that alert is reflected in reponse
Note: you have to send request multiple time due to cache used by server
And we can see reponse of above request in our browser
To solve the lab we have to alert cookie then lab is solved
And we can see the alert in reponse of documet.cookie and then lab is solved
LAB 4 - Routing-based SSRF
Lab Description
Overview: Accessing Internal Websites with Virtual Host Brute-Forcing & Routing-Based SSRF
1. Virtual Host Brute-Forcing
Some companies host both public and private/internal websites on the same server. Although the internal hostname might resolve to a private IP address, attackers can still access these internal virtual hosts if they can guess the hostname.
Example scenario:
www.example.com→12.34.56.78(public)intranet.example.com→10.0.0.132(private)
Even if there is no public DNS record for intranet.example.com, it may still be reachable by directly sending HTTP requests with a Host header set to the guessed name.
Attack technique:
- Use tools like Burp Intruder to brute-force hostnames.
- Use a wordlist of common subdomains (e.g.,
admin,internal,dev,portal,intranet). - Send requests to the target server, modifying the
Hostheader with each candidate.
This technique helps identify hidden applications that are not meant to be externally accessible.
2. Routing-Based SSRF (Host Header SSRF)
Routing-based SSRF occurs when reverse proxies or load balancers route traffic based on the Host header, and the server does not validate or restrict it properly.
Key targets:
- Load balancers
- Reverse proxies
- Internal routing systems
These intermediaries may forward requests based on the Host header value, which an attacker can manipulate to route the request to internal-only services or other unintended systems.
How the attack works:
-
Attacker crafts an HTTP request with a custom
Hostheader, such as:Host: internal.example.local - If the intermediary component uses the
Hostheader for routing, it may forward the request to the internal service. - This gives the attacker indirect access to internal services.
Detection:
- Use Burp Collaborator to detect external interactions.
- Set the
Hostheader to a Burp Collaborator domain. - If the server performs a DNS lookup or HTTP request to this domain, SSRF via the
Hostheader is likely possible.
3. Accessing Internal IP Addresses
Once you’ve confirmed that routing-based SSRF is possible, the next step is to target internal IPs.
Ways to find internal IPs:
- Look for internal IP leaks in HTTP responses or JavaScript.
- Check if internal hostnames resolve to private IPs.
- Brute-force common internal IP ranges using tools or manual requests.
Common private IP ranges:
10.0.0.0/8→ 10.0.0.0 to 10.255.255.255172.16.0.0/12→ 172.16.0.0 to 172.31.255.255192.168.0.0/16→ 192.168.0.0 to 192.168.255.255
CIDR Notation Quick Summary
CIDR notation describes IP address ranges using this format:
<base IP>/<prefix length>
10.0.0.0/8= all IPs starting with 10.x.x.x192.168.0.0/16= all IPs from 192.168.0.0 to 192.168.255.255
Solution
There’s not much to see but a /GET call to request the home page.
Now, let’s check for host header injection by entering any other Hosts in the field. Let’s enter our burp collaborator’s IP to listen for any request that is made from the web application.
On doing so, we got a 200 OKresponse from the server.
Let’s check what our collaborator has received.
DNS request
Now looking at http request we can see that the application tried to fetch our collaborator IP which is the Host that we provided. So, we could verify that the application was vulnerable to host header injection.
Now, let’s try to perform SSRF leveraging this host header injection attack. Here, we can FUZZ the internal IP in the host field to figure out where the application is running. In a real world scenario, we can fuzz all A, B and C classes of private IP to determine the location of the service running internally. However, in this lab we are provided that the admin page is hosted within 192.168.0.0/24 network. The /24 range contains total of 256 IPs. So, let’s take the request to the burp’s intruder and fuzz the whole range of /24 subnet.
Select the Numbers List up from 0 to 255 (256 iterations) as payload and start the attack.
As we can see that 206 last adress ip is redirecting us
Now using internal ip and going to /admin will reveal the admin panel
In the admin page we could see a user deletion form. Sending POST request to /admin/delete with the csrf token and username parameter could delete any user. This is how we could perform SSRF leveraging the host header injection.
Finally, the request to delete the user is sent, and the user is deleted. We were able to forge the request on behalf of the application or the server to perform unauthorized and high-privilege actions. This is how we can perform SSRF by chaining it with host header injection.and then lab is solved.
LAB 5 - SSRF via flawed request parsing
Lab Description
Solution
Send the GET / request and intercept it received a 200 response to Burp Repeater
We can see in below image website validates the Host header and blocks any requests in which it has been modified.
Observe that we can also access the home page by supplying an absolute URL in the request line as follows:
GET https://YOUR-LAB-ID.web-security-academy.net/
Notice that when you do this, modifying the Host header no longer causes your request to be blocked. Instead, you receive a timeout error. This suggests that the absolute URL is being validated instead of the Host header. Use Burp Collaborator to confirm that you can make the website’s middleware issue requests to an arbitrary server in this way. For example, the following request will trigger an HTTP request to your Collaborator server: GET https://YOUR-LAB-ID.web-security-academy.net/ Host: BURP-COLLABORATOR-SUBDOMAIN
We can see that above url is sending request to our server
Use the Host header to scan the IP range 192.168.0.0/24 to identify the IP address of the admin interface. Send this request to Intuder
And we can see that in beloiw image 137 stand out valid internal ip
We can see that it is redirecting us to /admin
In Burp Repeater, append /admin to the absolute URL in the request line and send the request. Observe that we now have access to the admin panel, including a form for deleting users. and we have used internal ip in host header
Change the absolute URL in your request to point to /admin/delete. Copy the CSRF token from the displayed response and add it as a query parameter to your request. Also add a username parameter containing carlos. The request line should now look like this but with a different CSRF token:
GET https://YOUR-LAB-ID.web-security-academy.net/admin/delete?csrf=QCT5OmPeAAPnyTKyETt29LszLL7CbPop&username=carlos
Copy the session cookie from the Set-Cookie header in the displayed response and add it to your request. Right-click on your request and select “Change request method”. Burp will convert it to a POST request. Send the request to delete carlos and solve the lab.
LAB 6 - Host validation bypass via connection state attack
Lab Description
Solution
Now, we can try to modify the Host HTTP header in Burp Repeater:
CHANGE HOST HEADER TO TEST.COM
However, it redirects me to the lab domain. What if I supply multiple Host header?
Duplicate header names are not allowed. How about indenting HTTP headers with a space character?
Hmm… Still the same. In the lab’s background, it said: Hmm… What if I send a normal Host header on the first request, then in the second request I send a malicious Host header, which points to 192.168.0.1? To do so, I’ll use 2 Burp Repeater tabs:
This lab is vulnerable to routing-based SSRF via the Host header. Although the front-end server may initially appear to perform robust validation of the Host header, it makes assumptions about all requests on a connection based on the first request it receives.
• Tab 1: GET /, normal Host header:
• Tab 2: GET /admin, Host header change to 192.168.0.1:
• Add both tabs to a new group:
Change the send mode to Send group in sequence (single connection):
Change the Connection header to keep-alive:
Click Send group (single connection):
you can see, the second request has successfully accessed the admin panel!
Now, in order to delete user carlos, we need to send a POST request to /admin/delete, with parameter csrf, and username.
Let’s modify the second tab:
• Change the location to /admin/delete:
Now we can see in below image respones highlighted that to delete user carlso we have to submit post request with csrf and username
And now carlos useor is deleted and lab is solved it is giving us 302
Note:
Above request will not work until change request to get and show all the csrf and username in front of get i am stuck here