What is the X-HTTP-Method-Override header?
X-HTTP-Method-Override lets a client send a request as POST while asking the server to process it as a different method: X-HTTP-Method-Override: DELETE on a POST means “treat this as a DELETE”. It dates from clients and networks that could only send GET and POST: HTML forms, old browser plugins, and corporate proxies or firewalls that blocked anything else.
It has never been standardized and is not in the IANA HTTP Field Name Registry. Variants include X-HTTP-Method, X-Method-Override and a _method form or query parameter, which several web frameworks read. A second use is tunneling a long read: Google’s APIs document sending a POST with X-HTTP-Method-Override: GET when the query string would exceed the URL length limit.
API Usage & Best Practices
- Do not support it in new APIs. Every client and proxy worth supporting today sends
PUT,PATCHandDELETEwithout help. For a read that does not fit in a URL, use theQUERYmethod, or a documentedPOSTsearch endpoint as the fallback, rather than aPOSTthat pretends to be aGET. - Understand why it is a security problem. The override creates two answers to “what method is this?”. Your WAF, gateway, rate limiter, audit log and authorization rules may all see
POST, while the application executesDELETE. A rule like “this API key may onlyPOSTto/v1/users” is bypassed by any client that adds the header. This is a form of HTTP verb tampering. - It can open CSRF holes. A cross-site HTML form can send a
POSTwith arbitrary form fields, so a framework that honors a_methodbody or query parameter lets another site issue aDELETEwith the victim’s cookies. The header form is safer in browsers, because a custom header makes a cross-origin request need a CORS preflight. Honoring the override onGETis worse still: a link or an<img>is enough. - If you must support it, constrain it hard. Honor it only on
POST, which is also the default in Express’smethod-overridemiddleware. Allowlist the target methods (PUT,PATCH,DELETE), and rejectGET,HEAD,CONNECT,TRACEand anything unknown. Read it from the header only, never from the query string. Apply authorization, rate limiting and logging to the effective method, and record both methods in your logs. - Resolve it in one place. If the gateway does not understand the override and the application does, they disagree about every overridden request. Either resolve it at the edge, rewriting the method before anything else sees the request, or strip the header at the edge so the application never acts on it.
- Strip or reject it if you do not support it. Frameworks sometimes honor it by default or behind a single setting. Check yours. If you do not intend to support overrides, remove the header (and the
_methodparameter) at the edge, or reject requests that carry it with a400 Bad Request, so a framework upgrade cannot quietly turn it on. Rejecting is kinder to clients, which otherwise get aPOSTprocessed when they asked for something else. - Watch your caches. An overridden request is still a
POSTto every cache and proxy on the path, so an override toGETloses the caching a realGETwould get, and anything keyed on the method sees the wrong one.
Examples
A client behind a proxy that only allows GET and POST, deleting a resource:
POST /v1/orders/ord_9 HTTP/1.1Host: api.example.comX-HTTP-Method-Override: DELETEContent-Length: 0A long read tunneled through POST. Prefer QUERY or a search endpoint where you control the API:
POST /v1/orders HTTP/1.1Host: api.example.comX-HTTP-Method-Override: GETContent-Type: application/x-www-form-urlencoded
status=open&customer_id=cus_1&customer_id=cus_2&customer_id=cus_3An API that does not support overrides rejecting the attempt instead of silently processing a POST:
HTTP/1.1 400 Bad RequestContent-Type: application/problem+json
{ "type": "about:blank", "title": "Bad Request", "status": 400, "detail": "X-HTTP-Method-Override is not supported. Send the intended method directly."}