As already mentioned in other posts here at SideChannel (HENRIQUE, 2021; MORAIS, 2021; MULLER, 2021), as part of the internship program at Tempest’s consulting team, interns are required to conduct a security-focused survey by the end of each cycle. Thus, this publication results from what I discovered and developed during this study, which was conceived and supported by my guiding light, Rodolfo Tavares. Thank you so much for your help, master \0/.
What is this HTTP Method Override?
As it is already known by most people who work with IT, the Hypertext Transfer Protocol (HTTP) is, roughly speaking, the communication protocol used by the web for websites to be accessed by users.
In the first line of an HTTP request, the method to be used is specified. Basically, this method indicates what action the user wants to perform on the server. For example, the GET method is commonly applied to read a piece of certain information and the PUT method to add or modify data on the server.
Although there are several other HTTP methods, not all of them are supported on users’ devices. For example, very old or very simple browsers, or embedded devices with minimal resources, may not support all the methods available. So if the servers with which these devices communicate need to use one of these unsupported methods, communication would not be possible due to lack of compatibility.
In order to allow access to such clients, the solution found was to implement, on the server-side, functions that were capable of receiving a method but interpreting the request with another method. For example: receive a request with a POST method and interpret it with a PUT method. This concept of overriding the method that is being given defines quite well what Method Override is – receiving one method and interpreting another.
But how could the server know which requests should have their original methods overwritten? The solution found was for the client to pass information in the request, indicating that the method should be overridden. The information appears in the following forms:
- Headers: X-Http-Method-Override, X-HTTP-Method-Override, X-Http-Method, X-HTTP-Method, X-Method-Override;
- Parameters in the URL: _method, method, httpMethod, _HttpMethod, and also those in the previous item;
- Request body: any of the names mentioned above
Thus, if the server supports Method Override, the method will be changed, and the request will be processed accurately.
The developers have agreed that Method Override should only occur when the original method of the request is POST. However, this is not a rule. The developer is free to change this condition in his application.
In practice
Observing this behavior in practice, I created a lab with Method Override activated. The operation of the application is straightforward: it will reflect in the page’s response the method that is interpreted.
In this first example, I sent a GET method, and the page confirmed that it received it:
If we send POST, the page reflects POST:
And so on. However, if we add the X-Http-Method-Override header, let’s see what happens:
Although the original method was POST, the application interpreted the request as GET. This behavior repeats itself with any method that the application accepts.
From a security point of view
As we have seen, the only function of Method Override is to change the method of the request. With this, an attacker wouldn’t be able to do much.
It’s very likely that the device the attacker uses to perform the attack does not suffer from the same limitations as the ones mentioned above and thus supports all HTTP methods. So, in this case, he could simply send the request using the method accepted by the application and thus communicate directly with it.
With this in mind, the question emerges: Why would an attacker use Method Override instead of sending the method directly?
To answer this question, I created a very simple lab that seeks to show how this technique can be used in practice. The lab consists of a simple HTTP server created using the Express.js development framework, with an Nginx reverse proxy between the client and the server.
The Nginx has been configured to only accept requests with the GET, HEAD and POST methods for this lab. Any other method will be prevented from going through to the server. However, the HTTP server also accepts the PUT and DELETE methods. Knowing that it accepts these methods and that they usually perform some sensitive operations, it would be interesting for an attacker to test them and see what he could achieve.
Despite the previously mentioned changes, the lab is the same as the one I used to demonstrate the operation of Method Override. Therefore, the interpreted methods will be reflected on the screen.
As we have already seen, the application normally accepts GET and POST methods. But what if we test a slightly less traditional method, such as PUT?
What about DELETE?
As we can see, it was not possible to use the methods mentioned above due to the Nginx policy. Now what?
That is where Method Override can be used. We will use it to tunnel the forbidden methods into an allowed method and thus communicate directly with the server.
Since we know that Nginx accepts the POST method and that it is the method that supports Method Override, we will use it and pass the X-Http-Method-Override header with one of the forbidden methods to see what happens:
As we can see, we can use the PUT method in the application. And the same happens with DELETE:
This is the essence of Method Override: to communicate directly with the server, bypassing possible HTTP method filters that are in the way, such as an API gateway, a reverse proxy, or a firewall.
An actual attack scenario has been published via the write-up available at How I exploit the JSON CSRF with method override technique.
Although the publication focused on exploiting a JSON CSRF, the flaw could only be exploited thanks to Method Override because the endpoint only accepted the PUT method, and the HTML form only allowed the GET and POST methods.
Another possible exploitation scenario considers the current architecture of some applications, in which there are several components between the client and it. For example, let’s imagine a scenario where there is an API gateway responsible for authenticating and forwarding user requests to another server. In turn, the first one forwards the request to a second server, and so on. Because the only external communication takes place between the client and the API gateway, the components behind it tend to put more trust in the information passed between each other because, in theory, it is from trusted sources. This way, an attacker could use Method Override to perform improper actions on other servers by passing a method accepted by the API gateway and overriding it with another one, being able to perform actions that should only be performed by the other recognized components.
Although we have seen that it is possible to exploit some flaws using this technique, it cannot by itself be considered a security breach.
Going back to the JSON CSRF case, we can see that the security flaw is the JSON CSRF, not the Method Override. It was just a means used to exploit the flaw. If its support is removed from the application, the application would still be vulnerable to JSON CSRF; only now the attacker would need to use some other technique to exploit it.
Method Overrider
To help discover this technique, I decided to create a tool that would help detect it. I decided to call it Method Overrider. The tool in question is a plugin, or extension, to the Burp Suite proxy tool.
Basically, it analyzes all requests and their respective responses that go through the proxy, looking for keywords indicating the presence of Method Override. If it finds any, the user is notified, and it is up to him to evaluate what can be done with the information.
More implementation details can be found in my Github repository, available at [5].
Conclusion
One of the purposes of this study was to bring attention to this technique that is not very well-known by security professionals.
As we have seen, it can be fundamental to exploit some flaws in specific scenarios, especially when there are HTTP method filters.
Some CVEs involving this technique have already been registered, including:
- CVE-2017-16136 -> DoS using regex in Express.js;
- CVE-2020-35239 -> CSRF bypass checking in CakePHP;
- CVE-2019-19326 -> Web Cache Poisoning in SilverStrip CMS;
- CVE-2019-10913 -> Lack of input validation in Symfony.
Despite being a brief introduction to the subject, I hope it was enlightening and that Method Override can be useful at some point during your testing. It is a behavior worth testing and has few public reports available for us to rely on, being a technique not widely known and with great potential for expansion.
References
CAMPANHA, Fernando. Method overrider. Available at https://github.com/fernandocampanha/MethodOverrider. Accessed on January 08, 2022.
HENRIQUE, Ricardo. URL Filter Subversion. Available at https://sidechannel.blog/url-filter-subversio/index.html. Accessed on December 20, 2021.
MORAIS, Vinicius. A Saga do Cypher Injection. Available at https://www.sidechannel.blog/a-saga-do-cypher-injection/index.html. Accessed on December 21, 2021.
MULLER, Eduardo. Conversores de HTML para PDF, dá para hackear? Available at https://www.sidechannel.blog/conversores-de-html-para-pdf-da-para-hackear/index.html. Accessed on December 22, 2021.
SECUREITMANIA. How I exploit the JSON CSRF with method override technique. Available at https://infosecwriteups.com/how-i-exploit-the-json-csrf-with-method-override-technique-71c0a9a7f3b0. Accessed on January 04, 2022.