Unsafe HTTP methods permitted
CWE-650CWE-749OWASP A05:2021Updated September 4, 20264 min read
Web servers accept more HTTP methods by default than an application uses. TRACE echoes the request back including headers, PUT and DELETE can write or remove files under a wrong configuration, and OPTIONS reveals which methods are available. Limit the permitted set to what you genuinely need.
A web server accepts a wider range of HTTP methods by default than the application behind it uses. That is rarely an acute problem and often an indicator: the gap between what is configured and what is needed says something about how carefully the environment was set up. A few methods matter more than the rest, and in some setups they lead to something considerably more serious.
Which methods exist and which should be off?
HTTP knows a number of methods, each with its own purpose. GET retrieves, POST submits, PUT and DELETE write and remove, HEAD requests only the headers, OPTIONS states what is permitted and TRACE echoes the received request.
We speak of unsafe HTTP methods when the server accepts methods the application does not use. That is not a vulnerability in itself, but it enlarges the attack surface without any return. Every enabled method is behaviour someone can examine and whose handling is implemented somewhere, sometimes by your application, sometimes by the web server, sometimes by a module you did not know existed.
Think of a building with doors leading to rooms nobody uses. Nothing happens in itself. But you have to keep them all locked, and that is a task you could have spared yourself.
Where do unsafe HTTP methods lead?
Vulnerable:
OPTIONS / HTTP/1.1
Host: portal.example
HTTP/1.1 200 OK
Allow: GET, POST, PUT, DELETE, OPTIONS, HEAD, TRACE, PATCH
This response gives away in one line what is open. TRACE echoes the request in full, including headers added by intermediate proxies:
TRACE / HTTP/1.1
Host: portal.example
HTTP/1.1 200 OK
Content-Type: message/http
TRACE / HTTP/1.1
Host: portal.example
X-Forwarded-For: 10.0.4.12
X-Internal-Route: cluster-b-node3
Cookie: sid=8f42c19ade7b3f5c
The internal network structure and the routing headers of your infrastructure now sit in the response. It becomes more serious when PUT is actually implemented by a web server module rather than by your application:
PUT /uploads/shell.jsp HTTP/1.1
Host: portal.example
Content-Length: 51
<% Runtime.getRuntime().exec(request.getParameter("c")); %>
On a misconfigured server with write permissions on that folder, this is a direct route to code execution. That is rare, but it occurs on older installations and on default configurations that were never closed off.
Safe:
# Only what the application uses
location / {
limit_except GET POST {
deny all;
}
proxy_pass http://application;
}
// And in the application itself, explicitly per route
app.route('/api/invoices/:id')
.get(requireLogin, showInvoice)
.put(requireLogin, updateInvoice)
.all((req, res) => res.status(405).set('Allow', 'GET, PUT').send());
The web server only lets through what is needed, and the application answers everything outside that with a 405 and a correct Allow header. That last part is both tidy and informative without giving away too much: it states what this endpoint supports, not what the server can handle in general.
GET and POST lets a request with a different or unknown method pass unhindered to the application behind it, bypassing authorisation without any flaw in your code. Always define rules on the basis of what is permitted.What is the impact of unsafe HTTP methods?
The severity is usually low, which reflects reality: in most cases it concerns superfluous functionality with no direct abuse. Two situations change that.
The first is a writing method that actually works. If a file can be placed on the server through PUT, the impact is comparable to an unrestricted file upload and therefore high. That requires a specific combination of an enabled module and write permissions, but that combination exists in practice.
The second is bypassing access control. Where restrictions are written per method, a differing method can go around them. A known pattern is an admin page shielded for GET but still processed through HEAD or an unknown method by the application behind it.
Beyond that there is the information value. What an OPTIONS response and a wide method offering mainly reveal is that the environment runs on default settings. To an attacker that is an indication that more has probably been left unclosed.
How do you detect unsafe HTTP methods?
A tester asks with OPTIONS which methods the server claims to support, and then checks that in practice, because the stated list and the actual behaviour regularly diverge. Every method is tried separately to see which gives a meaningful response instead of a 405.
With TRACE they check whether the request is echoed and whether headers added by intermediate systems appear in it. With PUT and DELETE they carefully test whether anything is actually written or removed. Beyond that, unknown and invented methods are tried, because some servers pass those to the application without restricting them, a known way to bypass access rules. Mechanisms for method override through a header or parameter get attention too. AssistSec explicitly tests whether a shielded route is still reachable with a differing method, because that is the scenario in which this finding shifts from hardening to genuine access control.
How do you prevent unsafe HTTP methods?
- Permit only the methods the application genuinely uses on every route.
- Disable
TRACE; there is no production use for it. - Disable
PUTandDELETEon the web server when only your application handles them. - Define access rules on the basis of what is permitted, never as a list of exceptions.
- Answer unsupported methods with
405and a correctAllowheader for that endpoint. - Let
OPTIONSname only the methods that exist on that endpoint. - Disable method override through headers or parameters when you do not need it.
- Check that the restrictions also apply behind a reverse proxy, load balancer or CDN.
- Repeat the check after a server migration, because default configurations return then.
Sources
Frequently asked questions
Is TRACE still dangerous?
The classic attack, where script code used TRACE to bypass HttpOnly protection, no longer works in modern browsers because they block the method. The method remains pointless in production, though, and can reveal internal proxy headers. Disabling costs nothing and removes the discussion.
Should I disable OPTIONS?
Usually not: browsers need the method for the preflight request in CORS. Do make sure the response names only the methods genuinely supported on that endpoint, rather than a full list from the server's default configuration.
Why can a method bypass authorisation?
Because some configurations define access rules per method. A rule restricting only GET and POST lets a request with, say, HEAD or an unknown method pass unhindered to the application behind it. Define access rules on the basis of what is permitted, not what is forbidden.
What is method override?
A mechanism where a POST request indicates through a header or parameter that it should be treated as PUT or DELETE. Useful with old clients, but it bypasses restrictions at method level. Disable it when you do not need it.
Related articles
- VulnerabilitiesCWE-284A01:2021Broken access controlBroken access control explained: horizontal and vertical privilege escalation, forced browsing, and how deny by default fixes it server-side.
- VulnerabilitiesCWE-1188A05:2021Default web server files reachableSample pages, admin consoles and installation files left after setup reveal your platform and are sometimes directly abusable.
- VulnerabilitiesCWE-200A01:2021Information disclosureInformation disclosure explained: how stack traces, .git directories, source maps and over-sharing API responses leak data, and how to stop it.
- VulnerabilitiesCWE-16A05:2021Security misconfigurationSecurity misconfiguration explained: how default passwords, debug modes and open cloud buckets let attackers in, and how to harden your systems.