Asking for a web server’s version
There are many ways in which an attacker can find a vulnerability in a website. One of them is by knowing the version of the web server that the site uses and then looking up known vulnerabilities for that version. How can they find out the version? It’s surprisingly easy, actually. They just need to ask.
Most web servers are glad to tell you who they are and what version they are in each response. Below is a response header from an Nginx web server running locally in a container. It is using all of the default Nginx configurations.
If you want to follow along, you can run a container as shown below. This will use the nginx.conf
file that is packaged with Nginx.
$ docker run --rm -d -p 8080:80 nginx
$ curl -v localhost:8080
...
< HTTP/1.1 200 OK
< Server: nginx/1.15.3
< Date: Fri, 14 Sep 2018 19:33:26 GMT
< Content-Type: text/html
< Content-Length: 612
< Last-Modified: Tue, 28 Aug 2018 13:32:13 GMT
< Connection: keep-alive
< ETag: "5b854edd-264"
< Accept-Ranges: bytes
...
In the response above, the Server
header contains the type of server (nginx
) as well as the version (1.15.3
).
Removing the version from Nginx responses
Luckily, Nginx provides a directive to remove the version: server_tokens
. By default, the version appears in a response, as demonstrated above. To remove it, add server_tokens off;
to the http
, server
, or location
context.
If you aren’t familiar with the terminology, directives are how you control behavior (server_tokens
in this case) and contexts define the scope in which a directive is used; an area within { }
is a context. Contexts are hierarchical so location
is a child of server
, which is a child of http
. If you’re still confused, and it’s ok if you are, you can find a great tutorial on DigitalOcean on Nginx configuration. You won’t need it for the rest of this post but I recommend reading it later.
Below is an example configuration file (nginx.conf
) that contains the server_tokens off
directive in the http
context. By applying it to the http
context, any server
, and consequently any location
, will also inherit it. If for some reason you wish to change the behavior in a server
or location
context, you can override the directive by adding server_tokens on
.
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
server_tokens off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
If you’re still following along, stop the first container and start a new one that volume mounts the new configuration file and replaces the existing one.
$ docker run --rm -d -p 8080:80 --name=ngnix -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf nginx
Verify version is absent
With the new configuration in place, and Nginx restarted, make another request to the same endpoint.
$ curl -v localhost:8080
...
< HTTP/1.1 200 OK
< Server: nginx
< Date: Fri, 14 Sep 2018 19:52:51 GMT
< Content-Type: text/html
< Content-Length: 612
< Last-Modified: Tue, 28 Aug 2018 13:32:13 GMT
< Connection: keep-alive
< ETag: "5b854edd-264"
< Accept-Ranges: bytes
Now, the Server
header contains nginx
but the version has been removed. And that’s it. This is something you can do today to help improve the security of your web server. Be sure to reload Nginx in order for the directive to be applied.
Conclusions
Removing the version of the web server in responses is one way to help decrease the likelihood of an attacker discovering a vulnerability in the web server. It is not a panacea but should be part of a defense-in-depth strategy. Nginx makes it easy to remove the version by setting server_tokens off
in the http
, server
, or location
context.
If you have questions or comments about this post, please leave them below. Thank you for taking time to learn more with Influential Code LLC.