Signup/Sign In
PUBLISHED ON: MARCH 9, 2023

HTTP methods Nginx

Every HTTP request is made with a default or custom request method which are mostly GET & POST, these are enabled by default. When you provide https://www.studytonight.com/ as URL to the browser it initiates a HTTP GET request and waits for server response. And when you submit a form it uses a HTTP POST method. Now, for security reasons, you can/should edit Nginx configuration to only allow an HTTP request with desired method. So, the Attacker would not be able to intercept and alter the request method. In this tutorial, we will learn three useful method to allow/restrict an HTTP request method.

Edit configuration file

The default configuration file for Nginx is /etc/nginx/nginx.conf. You can add domains to this configuration but it will become harder to manage. So, it is recommended to add another configuration file (in /etc/nginx/sites-available directory) and add a new domain to it.

Open the configuration for your website :

$ sudo vi /etc/nginx/sites-available/example-domain.com.conf

Method 1: Disable unnecessary HTTP methods using IF statement

So it is important to allow only GET, POST and HEAD requests and disable all other requests. Add the following lines in your server block to send an empty response code 444 to any request other than GET, POST and HEAD.

if ($request_method !~ ^(GET|POST|HEAD|PURGE|PUT)$) {
   return 444;
}

Restart NGINX server to apply changes. Now if you try sending a DELETE request to NGINX server, you will get an empty response.

$ curl -X DELETE http://172.18.0.5/api.php
curl(52) : Empty response from server //output

Method 2: Disable unnecessary HTTP methods using verbs

Create a root level conf file for these verbs

Open the configuration for your website to edit configuration.

$ sudo vim /etc/nginx/http-verbs-root-context.conf

add into the file this line using:

dav_methods PUT DELETE;

Add the verbs to the “more_set_headers” directive in this config.

$ sudo vim /etc/nginx/extra.d/headers-http-context.conf

Add PUT DELETE PATCH to the more_set_headers allow directive and into the if guard block.

more_set_headers "allow: DELETE, PATCH" always;

if ($request_method !~ ^(DELETE|PATCH)$) {
  return 405;
}

Method 3: Disable unnecessary HTTP methods without using the if statement.

Here is an alternative that works without if. The trick is to use "GET" and "POST" as part of the upstream names, so these can be addressed by variable substitution:

http {
  ....
  upstream other_GET {
    server 157.33.19.1;
  }
  upstream other_POST {
    server 157.33.19.2;
  }
  server {
    location /service {
      proxy_pass http://other_$request_method;
    }
  }
  ....
}

You can also use the map block for the same purpose.

map $request_method $upstream_location {
   DELETE  domain.com:8081;
   POST    domain.com:8081;
   default domain.com:8082;
}
server {
   location / {
      proxy_pass https://$upstream_location;
   }
}

Finally, save the configuration file and exit the text editor.

Verify configuration, then launch Nginx.

It is a recommended practice to test new configurations before loading them to the production server because a single syntax mistake will prevent the Nginx service from running, which will prevent users from accessing your website.

Finally, Start/Restart/Reload the server to load the changes:

$ sudo systemctl restart nginx

or

$ sudo service nginx restart


About the author:
Pradeep has expertise in Linux, Go, Nginx, Apache, CyberSecurity, AppSec and various other technical areas. He has contributed to numerous publications and websites, providing his readers with insightful and informative content.