Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to mask the http response header Server attribute #825

Closed
diwu1989 opened this issue Jul 24, 2014 · 36 comments
Closed

Ability to mask the http response header Server attribute #825

diwu1989 opened this issue Jul 24, 2014 · 36 comments

Comments

@diwu1989
Copy link

Right now, all responses have the http header
server: gunicorn/19.0.0

For security reasons, I would like to be able to mask that so that people won't know to search for security vulnerabilities in gunicorn. Is there any way to mask it? via a setting perhaps?

@georgexsh
Copy link
Contributor

georgexsh commented Jul 25, 2014

Typically gunicorn is deployed behind a reverse proxy server like nginx in production environment, and nginx would output its own Server tag.

@wong2
Copy link
Contributor

wong2 commented Jul 25, 2014

upstair plus one

@matrixise
Copy link
Collaborator

with @benoitc we can propose an option on the command line, what do you think? otherwise, we will close this ticket as explained by @georgexsh , in production mode, you can use a reverse proxy (nginx, apache, ...).

@tilgovi
Copy link
Collaborator

tilgovi commented Jul 25, 2014

Couldn't one just modify the environ in a post_request hook?

@benoitc
Copy link
Owner

benoitc commented Jul 26, 2014

@tilgovi that would work I guess... not sure then if we need to create another option...

@tilgovi
Copy link
Collaborator

tilgovi commented Jul 26, 2014

Doesn't work. The request is sent already at that point.

@georgexsh
Copy link
Contributor

@tilgovi middleware wont work too, because Server is in default headers.

@collinanderson
Copy link
Contributor

What if we just remove the Server header altogether?

@wojcikstefan
Copy link

+1

If we allow you to set the header's value to a random string, we should also allow you to remove the header completely.

@NicolasLM
Copy link
Contributor

+1

@benoitc
Copy link
Owner

benoitc commented Dec 4, 2015

why do you want to remove the header?

@tilgovi
Copy link
Collaborator

tilgovi commented Dec 4, 2015

In the past, I've removed the header from deployments to hide the server software and version so that it doesn't get picked up by someone crawling for servers with a known exploit.

@wojcikstefan
Copy link

Yup. Security is one of the reasons. Of course, you can change the Server value to something random, but why send extra bytes that aren't really necessary?

@tilgovi tilgovi added this to the 20.0.0 milestone Dec 31, 2015
@benoitc benoitc removed this from the 20.0.0 milestone Oct 16, 2016
@mathiasverhoeven
Copy link

I took the liberty to make a PR for this feature: #1384 . It has been on my wanted list for some time.

To add to the discussion: I would argue that while some reverse proxy servers modify the Server header, some add a Via header like described in https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.38

@tuukkamustonen
Copy link

Unfortunately, @mathiasverhoeven closed his PR for some reason and hasn't had activity lately.

Would it be impossible to have more generic option here, as in --set-headers where you can specify any amount of headers as key-value pairs? Empty value would omit the header completely.

At the moment, I would like to adjust Server, but I would also like to add one more response header, e.g. X-Product: MyProduct.

I can throw something together based on @mathiasverhoeven's PR. @benoitc and @tilgovi what do you think?

@wojcikstefan
Copy link

Just going to leave this here: https://www.fastly.com/blog/headers-we-dont-want. As you can read in the article, the Server header is both very common AND completely unnecessary.

@DavidOliver
Copy link

DavidOliver commented Oct 24, 2018

I would also like to be able to omit the Server header. I use a security-focused webserver called Hiawatha to reverse proxy, set not to add a Server header of its own, so gunicorn's Server header is currently making it to clients.

@tuukkamustonen's idea sounds good to me. :)

Edit: just seen #1617. server_tokens = true|false|string would be great.

@javabrett
Copy link
Collaborator

Anyone running Flask? https://stackoverflow.com/a/46858238/452210 suggests wrapping and overriding process_response, replacing or removing the header.

mkgs added a commit to mkgs/gunicorn that referenced this issue Nov 29, 2018
mkgs added a commit to mkgs/gunicorn that referenced this issue Nov 29, 2018
@fillest
Copy link
Contributor

fillest commented Apr 30, 2019

Yes please at least remove version. Version adds nothing to fame and saves a lot of time for attackers.

@benoitc
Copy link
Owner

benoitc commented Sep 27, 2019

I am thinking to just remove the version. @tilgovi any thoughts on it?

@tilgovi
Copy link
Collaborator

tilgovi commented Oct 10, 2019

Fine for me!

leohemsted added a commit to alphagov/notifications-api that referenced this issue Oct 23, 2019
All our requests identify the web server they were served with via the
`server` response header. This opens us up to potential attackers who
might be crawling the internet looking for specific versions with known
vulnerabilities. As our dependencies are open source, this doesn't
affect any targeted attacks as they can just look at our repos on
github, but this theoretically will marginally improve security.

Regardless, the header isn't useful [1], we're not the first people to
want to get rid of it, and gunicorn are in the process of at least
amending it to remove the version information [2].

This shouldn't have any impact on us, though an empty string will be
passed through to debug information in event of a crash. That's fine
though, as we already know what version we're running.

[1] https://www.fastly.com/blog/headers-we-dont-want
[2] benoitc/gunicorn#825
leohemsted added a commit to alphagov/notifications-api that referenced this issue Oct 23, 2019
All our requests identify the web server they were served with via the
`server` response header. This opens us up to potential attackers who
might be crawling the internet looking for specific versions with known
vulnerabilities. As our dependencies are open source, this doesn't
affect any targeted attacks as they can just look at our repos on
github, but this theoretically will marginally improve security.

Regardless, the header isn't useful [1], we're not the first people to
want to get rid of it, and gunicorn are in the process of at least
amending it to remove the version information [2].

This shouldn't have any impact on us, though an empty string will be
passed through to debug information in event of a crash. That's fine
though, as we already know what version we're running.

[1] https://www.fastly.com/blog/headers-we-dont-want
[2] benoitc/gunicorn#825
@benoitc benoitc modified the milestones: 20.0, 20.1 Nov 9, 2019
@Sytten
Copy link
Contributor

Sytten commented Nov 14, 2019

Any progress on this one? This seems like a quick win for security.

@benoitc
Copy link
Owner

benoitc commented Nov 14, 2019

that will be part of the next 20.1

@DavidOliver
Copy link

I am thinking to just remove the version.

Is the configuration file-only setting to remove the Server header altogether still planned?

@benoitc
Copy link
Owner

benoitc commented Dec 15, 2019

@DavidOliver why the question?

@DavidOliver
Copy link

@benoitc Your comment which I quoted could be interpreted to mean that it's "just"/only the version number which will be removed, whereas earlier in the conversation the setting to remove the Server header altogether (which I'd like to do) was being considered.

Thanks.

@tilgovi
Copy link
Collaborator

tilgovi commented Dec 29, 2019

If we can just remove the server header altogether, we should do it.

@benoitc
Copy link
Owner

benoitc commented Dec 29, 2019 via email

@kmichel2
Copy link
Contributor

kmichel2 commented Dec 29, 2019

Hi,

I'm using gunicorn to serve responses over a connection where data
is expensive, anything I can remove is anything I don't have to pay.

The Server header is small, but small things add up, and sometimes
small things means you can fit everything in one-less packet: the
server header with version is 24 bytes, about 1.7% of the payload
with a MSS of 1460 and TLS headers. Even without the extra packet,
a larger packet is much more likely to need to be entirely resent
when the connection is bad (like a cellular network in a remote place).

On a fresh HTTPS connection, the handshake and certificate
exchange make most of the payload and small things can be
ignored. For small repeated requests using keep-alive, redundant
headers become a much larger part of the request/response.

This might also matter for people who care more about client
performance (latency more than throughput) than cost.

For this use case, the most useful option is to be able to
entirely remove the header, not simply removing the value
or the version part.

@javabrett
Copy link
Collaborator

javabrett commented Dec 30, 2019

This comment is mostly limited to adding relevant reference/spec/RFC information, and (hopefully) mostly unopinionated interpretation/commentary.

RFC7231 Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content https://tools.ietf.org/html/rfc7231#section-7.4.2

...An origin server MAY generate a Server field in its responses.

An origin server SHOULD NOT generate a Server field containing needlessly fine-grained detail and SHOULD limit the addition of subproducts by third parties. Overly long and detailed Server field values increase response latency and potentially reveal internal implementation details that might make it (slightly) easier for attackers to find and exploit known security holes.

https://tools.ietf.org/html/rfc7231#section-9.6

9.6. Disclosure of Product Information
The User-Agent (Section 5.5.3), Via (Section 5.7.1 of [RFC7230]), and Server (Section 7.4.2) header fields often reveal information about the respective sender's software systems. In theory, this can make it easier for an attacker to exploit known security holes; in practice, attackers tend to try all potential holes regardless of the apparent software versions being used. Proxies that serve as a portal through a network firewall ought to take special precautions regarding the transfer of header information that might identify hosts behind the firewall. The Via header field allows intermediaries to replace sensitive machine names with pseudonyms.

From (deprecated) RFC2616:

15.1.2 Transfer of Sensitive Information
Like any generic data transfer protocol, HTTP cannot regulate the content of the data that is transferred, nor is there any a priori method of determining the sensitivity of any particular piece of information within the context of any given request. Therefore, applications SHOULD supply as much control over this information as possible to the provider of that information. Four header fields are worth special mention in this context: Server, Via, Referer and From.
Revealing the specific software version of the server might allow the server machine to become more vulnerable to attacks against software that is known to contain security holes. Implementors SHOULD make the Server header field a configurable option.

PEP3333 Python Web Server Gateway Interface v1.0.1 https://www.python.org/dev/peps/pep-3333/#the-start-response-callable

In general, the server or gateway is responsible for ensuring that correct headers are sent to the client: if the application omits a header required by HTTP (or other relevant specifications that are in effect), the server or gateway must add it. For example, the HTTP Date: and Server: headers would normally be supplied by the server or gateway.

  • The Server response header is optional according to HTTP 1.1
  • The RFC recognises that overly-detailed Server fields can make it easier to scan sites for vulnerable servers. Clearly this is a make-it-one-step-harder, obscurity provision, and how-much-detail is too much is circumstantial.
  • Deprecated HTTP 1.1 RFC2616 is a little bolder in the value of hiding the Server header.
  • PEP3333 seems to overstep slightly when mentioning the Server header in the context of required or normal headers.

@javabrett
Copy link
Collaborator

Plenty of opinion on this, such as in Apache HTTPD ServerTokens: https://httpd.apache.org/docs/2.4/mod/core.html#servertokens

Setting ServerTokens to less than minimal is not recommended because it makes it more difficult to debug interoperational problems. Also note that disabling the Server: header does nothing at all to make your server more secure. The idea of "security through obscurity" is a myth and leads to a false sense of safety.

@tilgovi
Copy link
Collaborator

tilgovi commented Dec 30, 2019

Changing the server header to just say gunicorn is a practical solution and I think we should do that, with no configuration.

People like @kmichel-sereema, who want to optimize the size of every transfer, I think this is not the place to perform such micro-optimization. If the HTTP headers are too much overhead, HTTP 1.x is the not the ideal protocol to use, and I don't think we should add additional configuration to allow changing or disabling the server header.

@jamadden
Copy link
Collaborator

The suggestion of @tilgovi seems like a good compromise to me.

In many environments this may even be moot. The gunicorn deployment documents recommend having a proxy server like nginx in front of gunicorn. nginx automatically strips the Server response header from the proxied server before it goes to the client, and can be configured to strip more headers. Surely more security-focused proxies can do the same.

@benoitc
Copy link
Owner

benoitc commented Jan 10, 2020

following my suggestion and comments from @tilgovi & @jamadden I'm closing this issue favor of #2233. Thanks all for the code and comments!

@benoitc benoitc closed this as completed Jan 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
No open projects
Development

Successfully merging a pull request may close this issue.