HTTP Requests
The Hyper Text Transfer Protocol (HTTP) contains main different standards that work together to give us the protocol we know today. One of the major standards of HTTP are HTTP Methods. Methods are simply a way of transmitting data over HTTP. A client can send the server various GET, POST, HEAD or other requests to perform a certain action with the server. It is ultimately up to the server to interpret the following data requests as they see fit, but existing server software is highly encouraged to follow the standards set in place by various RFCs.
Common Requests
GET Requests
GET Requests are the most common form of HTTP Methods. The name comes from the idea that a GET Requests is used to “get” a resource from a server such as a page or document. These types of requests are generally submitting through browser’s URL bar where their parameters are visible in the requests such as: https://x9security.com/test.php?arg1=a&arg2=b. In this URL the x9security.com is being contacted over HTTP Secure, test.php is being passed a GET request and the resource is being requested with arguments arg1=a and arg2=b.
POST Requests
POST Requests are very similar to GET Requests in that they post query a resource from a server with arguments. The two big differences between POST and GET requests are 1) POST Requests do not pass arguments as part of the URL, the pass arguments as part of the data being transmitted to a page in the request.
This can make it harder for an attacker to leverage a page’s resources for a XSS attack. They no longer can send the payload as part of a URL to the victim, it must be somehow injected into the page where the victim is visiting. 2) The accepted standard for dealing with POST Requests is that GET Requests ask for data and POST Requests send data. This is not a hard rule, but it is the general logic that most web developers will follow.
HEAD Requests
HEAD Requests are very similar to GET Requests. They will both query the server for a resource, but a HEAD Request is only interested in the header and status of the resource. A GET Request on the other hand will attempt to retrieve the resource along with the header and status. HEAD Requests can be an odd corner case in some scenarios. As most web developers will expect GET and POST Requests, they will tailor their web application’s logic around those two main types.
If an attacker is clever and sends a HEAD Request to a resource that is normally accessed via GET Request and is limited to specific users then the attacker may retrieve useful information about the page they would otherwise never receive. As shown below, the victim machine is set up to deny any GET requests and to redirect the user to the error.php. Error.php only contains the message “File not found.”.
x9-victim@X9-Victim:/var/www/html$ cat .htaccess RewriteEngine On RewriteCond %{REQUEST_METHOD} GET RewriteRule ^.*$ error.php
x9-victim@X9-Victim:/var/www/html$ cat error.php File not found.
When the attacker performs a GET request they are greeted with the “File not found.” error message.
root@X9-Attacker:~# curl http://192.168.17.132/head.php File not found.
However, when a HEAD request is made to the head.php resource, we get a HTTP 200 response.
root@X9-Attacker:~# curl --head http://192.168.17.132/head.php HTTP/1.1 200 OK Date: Fri, 07 Dec 2018 02:56:16 GMT Server: Apache/2.4.29 (Ubuntu) Content-Type: text/html; charset=UTF-8
Though this is not just an issue with HEAD Requests, by the above .htaccess, any request other than GET will return the correct response. Such as:
root@X9-Attacker:~# curl -X POST http://192.168.17.132/head.php This is head.php root@X9-Attacker:~# curl -X PUT http://192.168.17.132/head.php This is head.php
Uncommon Requests
PUT Requests
PUT Requests are interesting as they do just that, they put data specified by the request onto a server. On the server’s side, this should be validated to ensure the user sending the request has the proper authorization to be making a PUT Request and uploading information to the server. Following a PUT Request, a GET Request should return an HTTP 200 (OK) response. If the data fed to the server by the user does not already exist, the server should return HTTP 201 (Created). If the content does exist, it should return an HTTP 200 (OK).
DELETE Requests
DELETE Requests function very similarly to PUT Requests with the exception that the data specified is removed from the server following the request. If successful, the server should return HTTP 202 (Accepted), HTTP 204 (No Content) or HTTP 200 (OK).
CONNECT Requests
CONNECT Requests are interesting as they react very similarly to GET Requests. The purpose of CONNECT Requests is to establish a proxy connection between the client and a remote resource. This is used with SSL/TLS to establish a secure connection between the client and the remote resource. Colloquially CONNECT can be thought of as GET Requests over SSL/TLS.
OPTIONS Requests
OPTIONS Requests are designed to return a list of possible HTTP Requests a specific server or page can respond with. In theory, this request is very useful as it may given information on specific requests that are a user or attacker may not think are being used on the page such as PUT or PATCH. The issue comes that not all pages support the OPTIONS Requests and infact many do not at all.
TRACE Requests
Similar to OPTIONS Requests, TRACE Requests are not always implemented. Testing this on our dummy Ubuntu host gives us a 405 Method not allowed.
root@X9-Attacker:~# curl -X TRACE http://192.168.17.132 -i HTTP/1.1 405 Method Not Allowed Date: Sat, 08 Dec 2018 20:53:18 GMT Server: Apache/2.4.29 (Ubuntu) Allow: Content-Length: 303 Content-Type: text/html; charset=iso-8859-1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> <html><head> <title>405 Method Not Allowed</title> </head><body> <h1>Method Not Allowed</h1> <p>The requested method TRACE is not allowed for the URL /.</p> <hr> <address>Apache/2.4.29 (Ubuntu) Server at 192.168.17.132 Port 80</address> </body></html>
TRACE Requests are designed to test the connection between the user and the remote resource. This was created as a form of debugging tool to ensure that remote connections could be made, but it is not terribly common to find in the wild.
PATCH Requests
PATCH Requests are very similar to PUT Requests. However, a PATCH Request does not necessarilly have to update the entirety of an entry. For example: If a page can receive a PUT Request with
{
“Entry1”: 1,
“Entry2”: 2,
“Entry3”: 3
}
Then that page might also accept a PATCH Request
{
“Entry2”: 7,
}
This has the benefit of severely reducing the overhead from requests sent to the server. Only the parts that have been changed need to be updated and the rest can remain implicitly.
Really Uncommon Requests
While we have already explained a lot of different types of HTTP Requests, these are far from the only requests that exist. Given that HTTP Requests are inherently abstract and up to the Web Server’s interpretation, it is possible that any form of request could be handled. Some more obscure requests that are still considered “official” by RFC standards are:
- ACL Request
- Baseline-Control Request
- Bind Request
- Checkin Request
- Checkout Request
- Copy Request
- Label Request
- Link Request
- Lock Request
- Merge Request
- MKActivity Request
- MKCalendar Request
- MKCol Request
- MKRediretRef Request
- MKWorkspace Request
- Move Request
- OrderPatch Request
- PRI Request
- Rebind Request
- Report Request
- Search Request
- Unbind Request
- Uncheckout Request
- Unlink Request
- Unlock Request
- UpdateRediretRef Request
- Version-Control Request
Wrapping Up
While it seems there are a crazy amount of HTTP Requests it is best to remember that all of these are arbitrary. It is up to the Web Server how it wants to handle each of these and in some cases it may even choose to handle completely custom HTTP Requests. While this is not advised a security measure, using custom HTTTP Requests like “ABCDEF” can lead to a Security by Obscurity effect.