Lesson 7 · Reading · 25 min
HTTP methods and how they surprise you
You have spent your whole life sending two HTTP methods: GET to fetch a page and POST to submit a form. But HTTP defines several more, and servers often handle them in ways nobody thought about, because nobody was supposed to send them. Probing the methods a URL accepts is a quick, high-value recon step and the last one in this path.
The verbs, and what they are for
A method (or verb) tells the server what you want to do with a resource, not just which resource. The common set:
- GET: fetch it. Should not change anything.
- POST: submit data, create something, trigger an action.
- PUT: write or replace a resource at this URL.
- DELETE: remove the resource at this URL.
- PATCH: partially update it.
- HEAD: like GET but headers only, no body. A quiet way to check a page exists.
- OPTIONS: ask the server which methods this URL allows.
- TRACE: echo the request back, a diagnostic method.
Most sites are built around GET and POST. The others are frequently left enabled by the framework or server default, wired to code nobody hardened, and that gap is the finding.
Start by asking what is allowed
The single most useful move is OPTIONS, because a well-behaved server answers it with an Allow header listing the methods that URL accepts:
curl -i -X OPTIONS https://example.com/api/reports
HTTP/1.1 204 No Content Allow: GET, POST, PUT, DELETE, OPTIONS
That response is a gift. It just told you /api/reports accepts PUT and DELETE: write and remove, and now you ask whether those are actually protected or merely present.
Why each verb is worth probing
PUT lets a client write a resource at a URL. If a server or upload directory allows PUT without proper checks, you may be able to write a file of your choosing to the web root, including a script that the server will then execute. Historically, "PUT is enabled on the uploads folder" has meant "upload a webshell and run commands." Always worth checking where you see it allowed.
DELETE removes a resource. An open DELETE is destructive, so you probe for its presence carefully and report it rather than firing it, proving the method is accepted (via OPTIONS, or a 405 versus a 200) is usually enough, and actually deleting someone's data is both harmful and, on a real target, out of bounds.
PATCH and POST to unexpected endpoints can update fields you were never shown, which is the doorway to mass-assignment bugs, sending role=admin in an update the UI never offered. You will meet this properly in the Access path; for now, note that a method the interface does not use may still be wired up behind it.
TRACE echoes your request, including headers, back to you. Combined with other tricks this enabled an old attack called Cross-Site Tracing (XST) to read headers a script normally cannot. It is mostly historical, but an enabled TRACE is still flagged as a misconfiguration.
HEAD is your quiet friend: it checks whether a path exists and reads its headers without pulling the body, useful for low-noise existence checks.
Method-based access control bypasses
Here is the subtle, high-value idea, and the reason this lesson closes the recon path rather than the injection ones. Some applications enforce access control per method and get it wrong. A rule might block GET /admin/users for non-admins but forget to block POST or HEAD on the same path. Frameworks that treat HEAD as "a GET with no body" have been tricked into running the GET handler while skipping a filter that only watched for GET. So when a method is refused, it is always worth asking: is the refusal about who I am, or only about the verb I used? Swapping the verb is one of the cheapest access-control tests there is, and you will use it constantly in the next path.
Doing it in practice
Probe methods by hand with curl -X, and compare responses:
curl -i -X OPTIONS https://example.com/resource # what does it admit to? curl -i -X HEAD https://example.com/resource # exists? headers? curl -i -X PUT https://example.com/resource -d 'test' # writable?
Read the status codes together. A 200 where you expected a 405 is a live method. A 405 Method Not Allowed that still carries an Allow header hands you the map anyway. A 501 Not Implemented means the server does not support that verb at all.
Keep it honest
Sending arbitrary methods, especially PUT and DELETE, is active and can change or destroy data. Use OPTIONS and HEAD freely to map; be very deliberate with PUT, DELETE and PATCH, prove the minimum needed to show the flaw, and never run them against a target you are not authorised to test. On this Academy's labs, experiment freely.
You have finished the recon path
Look at what you can now do with a target you have never seen: find its hosts, learn from public sources without a footprint, read what each app volunteers, name its stack and its versions, uncover pages nobody linked, and map which methods each endpoint answers. That is a real map, and it is the difference between testing whatever is nearest and testing the whole target. The next path, Access control and authentication, takes this map and starts turning the soft spots into findings.
This lesson has 1 lab to try what you just read.