ASVS 5.0 V4.1.4 (level 3) requires that only HTTP methods the application or API explicitly supports can be used, including OPTIONS for CORS preflight, and that every other method is blocked.
If a route serves GET and POST, then PUT, DELETE, PATCH, TRACE and anything exotic should return 405 Method Not Allowed, ideally with an Allow header listing the valid ones.
Why it matters
Frameworks and servers often accept more than you wrote handlers for. A catch all route may treat DELETE as GET. A proxy may let TRACE through. Method override headers like X-HTTP-Method-Override can turn a harmless POST into a destructive call. Each unused method is surface you never reviewed, tested or put behind authorization.
Authorization bugs love this gap. A team protects DELETE /orders/42 with a role check, but a PUT on the same path hits a generic update handler that was never meant to be public.
How to implement it
Declare methods per route and reject everything else. In Express with a small guard:
const allow = (...methods) => (req, res, next) => {
if (methods.includes(req.method)) return next();
res.set('Allow', methods.join(', '));
res.status(405).json({ error: 'method_not_allowed' });
};
app.all('/orders', allow('GET', 'POST', 'OPTIONS'), ordersHandler);
At the proxy, add a global deny for methods no route uses:
if ($request_method !~ ^(GET|POST|PUT|DELETE|OPTIONS)$) {
return 405;
}
Turn off TRACE in the web server, and disable method override middleware unless you truly need it. For CORS, answer OPTIONS only on routes that need preflight and return the narrow Access-Control-Allow-Methods list.
How to test it
Loop through methods against a handful of routes and record the status codes.
for m in GET POST PUT PATCH DELETE TRACE HEAD OPTIONS FOO; do
printf "%s " $m
curl -s -o /dev/null -w "%{http_code}\n" -X $m https://api.example.com/orders
done
Compare the result with your route table. Any method you did not implement must give 405 (or 404 where the resource is hidden). Add the same loop to a test suite so a new route cannot ship with open methods.
Common mistakes
- Using
app.allor a wildcard route and forgetting to filter methods. - Authorizing only the methods you expected and leaving the others on a default handler.
- Honoring
X-HTTP-Method-Overridefrom public clients. - Letting HEAD run full handlers with side effects.
- Blocking OPTIONS everywhere and then breaking legitimate CORS preflight.
Try it yourself
Click through it at your own pace, or open it full screen.
Quick check
What should a route return when it gets a method it does not support?
A 405 Method Not Allowed response, with an Allow header listing the methods that are supported.
Sources
- OWASP Application Security Verification Standard, requirement V4.1.4 (level 3)
- RFC 9110, HTTP Semantics, 405 status