Last time I have showcased a three interesting headers that can be used as attack vector. This time I will showcase a three more, however they will be more exotic that the previous examples. If you haven’t seen part 1, view it first here. Without further ado, let’s buckle up!
Forcing HTTP Verb Tunneling
In standard HTTP, a client (like a web browser) can send requests using methods like GET, POST, PUT, DELETE, PATCH, etc. However, HTML forms – commonly used for submitting data on the web – only support the GET and POST methods.
This limitation presents a problem when a developer needs to handle more complex HTTP methods (like PUT, DELETE, or PATCH) in a web application where the client-side functionality is limited to just GET and POST.
The X-HTTP-Method-Override header was introduced to overcome this limitation. It allows a client to send a POST request but indicate to the server that the request should be processed as another HTTP method (like PUT, DELETE, etc.). This header doesn’t modify the actual HTTP method of the request, but instead, it sends an extra piece of information to the server indicating the intended method.
Moreover some RESTful APIs may require actions like DELETE or PUT, but the client may not be able to directly send these methods due to client-side restrictions. The X-HTTP-Method-Override header allows the client to use POST while specifying the true desired HTTP method.
Imagine a web application that uses X-HTTP-Method-Override to allow GET or POST requests to be treated as PUT, DELETE, or PATCH. While this can be a useful feature for supporting different HTTP methods in environments with restrictions (e.g., HTML forms), if it is not properly secured, it can create serious security vulnerabilities.
I will present malicious usage of this header on simple API endpoint which allows to show matches of in football league:

As it can be observed it does not honor POST / DELETE, but backs with HTTP response 500 Internal Server Error, which is strange:


However as I’ve sent request with PUT method, it shows 405 Method Not Allowed HTTP response which draws attention that something is hiding here:

From attacker’s perspective when such situation occurs it is wised to try all methods and aforementioned X-HTTP-Method-Override, as error 500 on certain endpoints can suggest use of it by the application.
Although enumerating methods in X-HTTP-Method-Override can sounds like fine approach, it is not recommended, as it can mess up application, especially if it honors PUT or DELETE. In this case I tried POST method in X-HTTP-Method-Override, supplementing random data:

Surprisingly it worked and it added new record

Moreover as it was shown before, the application seems to honor DELETE, so I’ve tried and it worked:

Matches results are gone, and so called disaster happened:

As you can see, improperly handling X-HTTP-Method-Override header can lead to even critical vulnerability, overriding any data served from susceptible endpoint.
Link Me Something Else
There are many interesting cases of using resource loading mechanisms out there, one is very peculiar, which is used with Link header.
The Link header in HTTP provides metadata about a resource by defining relationships between the requested resource and other resources. It is commonly used for pagination, preloading, alternate representations, and linking related documents.
The Link header consists of one or more <URL> values followed by rel=”relationship” attributes, specifying the nature of the relationship. Let’s dive into example:
Link: <https://example.com/page/2>; rel="next"
This tells the client that the next page of results is available at https://example.com/page/2.
There are many uses cases, one of them is used by API. APIs that return paginated results often use the Link header to indicate the next and previous pages:
Link: <https://api.example.com/users?page=2>; rel="next",
<https://api.example.com/users?page=5>; rel="last"
Where rel=”next” points to the next page of results and rel=”last” points to the last page.
The Link header can be also used to preload or prefetch resources to improve page performance, as it shown on example below:
Link: <https://cdn.example.com/styles.css>; rel="preload"; as="style",
<https://cdn.example.com/script.js>; rel="preload"; as="script"
Where rel=”preload” informs the browser to start loading the resource early and as=”style” / as=”script” specifies the type of resource.
Since the Link header can contain external URLs, an improperly configured server could be vulnerable to Server-Side Request Forgery (SSRF) if it processes the URL without validation.
However Link header is often used as response header not request, although there are cases where Link header is used in request, although it is not very common. Sometimes attacker can add Link header as request header (on server which reflect Link header in response), and it can lead to issues.
Like with all this types of vulnerabilities, if user can supply own value into Link request header and server will support it and process, we can read information from local infrastructure, reaching to admin servers and secrets that should not be available to user from Internet perspective.
Following application is used as video streaming platform. It has and endpoint /check that checks for new available streams as it is presented below:

Although not visible in plain sight, this application loads information about streams from other server, so it is always worth testing against various headers if they are not reflected in response. This can be validated with inserting Link header with random value in request:

Error itself is revealing enough, so it is wised to test with injecting an existing resource such as loading http://example.com:

It worked, so naturally the best approach would be to try enumerate whole network and all ports, which can be of course noise and inefficient, especially if there would be WAF or throttling mechanism. For showcase purpose I had enumerate ports starting from port 80 on localhost to check if there is any other web service active on vulnerable server:

As it can be observed applications on ports 80, 8899 and 8008 has been discovered, where 80 and 8899 are ports serving vulnerable application and 8008 being something different – Admass Controller, looking like an admin panel of some kind. The above screenshot also presents a href to /dashboard endpoints, I tried to fetch it via SSRF with success:

A dashboard with system information, that should be only available to internal administrators.
Redirects Go Wrong (Nginx Edition)
This issue will be exclusive to Nginx, a header that is used often normally but as always, misconfiguration of it can lead to security vulnerability.
X-Accel-Redirect is an HTTP header used by the Nginx web server to redirect internal requests to a file without exposing the file path to the client. It allows the server to internally redirect a request to a specific location or resource on the server while keeping the original URL intact from the client’s perspective.
This header is often used in scenarios like serving large files, where the file path should remain private. Nginx will handle the redirect internally, bypassing usual routing mechanisms, and directly serve the requested file from a specific location on the server.
X-Accel-Redirect is a response header. It is sent by the server to the client, instructing the server to internally redirect the request to a different file or resource. This happens after the server has processed the request, and the client is unaware of the internal redirect, as the file is served directly by the server.
In some situations, if the server or application does not properly validate or sanitize input headers, an attacker might be able to manipulate the X-Accel-Redirect header in a request to attempt to access unauthorized resources or files on the server.
This is especially true if the server is using the X-Accel-Redirect header for file serving or other internal routing mechanisms.
For instance, if the application relies on this header to direct the server to specific files and it does not validate or sanitize the value of the header, an attacker might inject a malicious value in the header to try to read arbitrary files on the server.
Such issues could lead to Local File Inclusion (LFI) vulnerabilities or unauthorized access to sensitive files, depending on how the application handles the header.
Following example showcase the same application as before – the streaming platform. Authenticated user watch streaming videos and also saved videos that are stored on server. To avoid being accessed by anonymous users, the developers wanted to store it locally in protected path that would be accessible and served to authenticated users based on their subscription plan.
As It shown below video is loaded for authenticated user:

The request and response looks like following:

Although the “file” parameter looks promising for LFI vulnerability, this is not the case. As with previous situation, X-Accel-Redirect is or not is not revealed in response, depending on configuration. In this case it is not.
Malicious user can try injecting path values to see what happens, in example below X-Accel-Redirect request header was injected with “/” value which lead to 403 Forbidden:

This showcase the server honors it. On this stage, it should be the best to brute-force paths, hoping that some path will land different result. During the path brute-forcing, a path “/protected” responded with slightly different 403 Forbidden response, making a possible found path, but could not be loaded:

If we dive further we will find more and more, however for this example it was possible to load following resource: /protected/keys/admin.key:

As it was observed on above example, it was possible to load an internal resource admin.key which has admin secret.
One more interesting think about exploiting this issue is, how to it looks in basics nginx logs:

There is no information on loaded resource by attacker, just information about status on /video?file=default.mp4 endpoint, which can be an additional trouble for investigating such issues, at least with basic logging.
Recap
For penetration testers and security researchers:
- Try experimenting with injecting response headers as requests.
- Try all headers from available resources with various values, it is always worth a try.
- Never give up in testing headers, even if you could not found any presented issue at the time, there might be once a web application that will be vulnerable.
For blue teamers and developers:
- Sanitize all user input, including HTTP headers.
- With X-Method-Override header, remember of checking all endpoints that use it, never enable it for all without testing.
- If you are using Link and X-Accel-Redirect, always define a list of resources that can be accessed (whitelisting).
- Be aware of potential header abuse and enforce strict validation.