Option to hide "Server: Puma PUMA_VERSION" header
daisy1754 opened this issue · comments
Is your feature request related to a problem? Please describe.
Currently we use Puma 5.6.4. Our security auditor asks if we can remove Server: Puma 5.6.4
in HTTP response header because it can potentially give bad actor hints about exploiting our server, if vulnerability is found in certain puma version.
Describe the solution you'd like
Add configuration to allow suppressing "server" response header
Describe alternatives you've considered
Remove this header on our load balancer level could be another option but I prefer if we can omit on puma-level
Additional context
Add any other context or screenshots about the feature request here.
I am also working through a penetration test where this was flagged by a tester. While this seems like security through obscurity, the OWASP project recommends removing the header.
In my current Rails app with puma 6.0.0 it seems like the Sever header is not generally being sent, but I found a couple error responses where it is sent (my tester flagged this on a 408 error):
Line 128 in 7b63010
I am considering starting a PR for this, but I wanted to ask the maintainers if you have a preference for handling this:
- remove the header completely
- remove the version from the header completely
- honor an optional ENV VAR that removes the header (or version)
- ?
Maybe a config option to hide the version from the header? I've seen other web servers doing that
I'm ok with adding this as a configuration option.
Hi @nateberkopec , I've got a PR that addresses this here #3125 (if I'm on the right track).
I think the header should be hidden by default, following a "secure by default" mentality... Otherwise, this will be raised in every penetration test ever done on Puma.
I spent some time this afternoon looking at this issue. For a 'good' reponse from the app, Puma does not send a response server
header. The only place it's defined are the two below header values (status of 404 & 408) in Puma::Const::ERROR_RESPONSE
:
Lines 126 to 129 in 904b47a
Both of those strings date back ten plus years.
Puma::Const::ERROR_RESPONSE
is only used in Puma::Client#write_error
:
Lines 285 to 294 in 9436322
One call to Client#write_error
is in Client
(408, as shown above), and three calls are in Puma::Server#client_error
as shown below:
Lines 503 to 510 in 9436322
So, we have two key/value pairs in Puma::Const::ERROR_RESPONSE
with a server
header, but it appears that 404
isn't used, so the only response that is a problem is a 408 ('Request Timeout').
Re adding code to make this an option, it's messy. They are part of a constant hash, which could be modified in Puma::Launcher
and then the hash could be frozen. Client
doesn't have access to options, so it can't modify the values or have any conditionals based on a config option.
Hence, I think we should remove the server header from the 408 response, which is used, and the 404 response, which isn't used.
@dentarg & @nateberkopec thoughts?
Hence, I think we should remove the server header from the 408 response, which is used, and the 404 response, which isn't used.
Either that or just remove the version info in the header (less intrusive change). I support both :)
I'm wondering about an option for this. Some sites use a non-informative value, most GitHub responses set the server header value to 'GitHub.com'.
The issue here is what Puma returns in the response if it is generated wholly by Puma. The code indicates that may happen with various 'errors', and any of the following may be generated by Puma:
400 Bad Request
408 Request Timeout
500 Internal Server Error
501 Not Implemented
So, given that ENV values are used for config and the Puma::Const::ERROR_RESPONSE
values are set 'on load', I propose using an ENV variable PUMA_SERVER_HEADER_VALUE
, which, if it is set, is used in the responses defined in Puma::Const::ERROR_RESPONSE
. If not set, no server header is used.
This allows Puma generated responses to match responses generated by the app.
I'll submit a PR shortly.