Restricting HTTP methods at the Nginx edge prevents unexpected verbs from reaching an application, shrinking the exposed surface area and cutting down noisy scanner traffic. A tight method allow-list also makes behavior predictable for static sites, reverse proxies, and APIs that only support a small set of verbs.
Nginx selects a server block for a request, then routes the URI into the best matching location block. The limit_except directive applies an allow-list of methods in a location, and its nested access rules run only when the request method is not in that allow-list.
Method filtering belongs as close as possible to the endpoint that needs it, since broad blocks can break APIs, WebDAV-style clients (PROPFIND), and browser CORS preflight requests (OPTIONS). Always run nginx -t before reloading the service to avoid taking the site offline due to a syntax error.
Related: How to secure Nginx web server
Related: How to configure CORS headers in Nginx
Steps to restrict HTTP methods in Nginx:
- Choose an allow-list of methods that matches the endpoint behavior.
Common allow-lists: GET + HEAD for static content, GET + HEAD + POST for form handlers, GET + HEAD + POST + PUT + PATCH + DELETE for APIs. Add OPTIONS on endpoints that must pass browser preflight checks.
- Open the site’s server block configuration file in /etc/nginx/sites-available.
$ sudoedit /etc/nginx/sites-available/example.conf
Layouts without /etc/nginx/sites-available commonly use /etc/nginx/conf.d or edit /etc/nginx/nginx.conf directly.
- Add a limit_except block inside the target location to deny every method not on the allow-list.
location / { limit_except GET HEAD { deny all; } }Blocking POST breaks logins, forms, and many APIs. Blocking OPTIONS breaks browser CORS preflight.
- Save the configuration file.
- Test the updated Nginx configuration for syntax errors.
$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
- Reload Nginx to apply the change without dropping active connections.
$ sudo systemctl reload nginx
Use
sudo systemctl restart nginx
when reload fails due to a module or binary change.
- Send a HEAD request to confirm allowed methods succeed.
$ curl -I https://example.com/ HTTP/1.1 200 OK Server: nginx ##### snipped #####
- Send a blocked method request to confirm the restriction triggers.
$ curl -i -X PUT https://example.com/ HTTP/1.1 403 Forbidden Server: nginx ##### snipped #####
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
Comment anonymously. Login not required.
