ratchetphp / Ratchet

Asynchronous WebSocket server
http://socketo.me
MIT License
6.28k stars 743 forks source link

Omit `X-Powered-By` HTTP response header to avoid exposing Ratchet version to potential attackers #999

Open clue opened 1 year ago

clue commented 1 year ago

Right now, Ratchet always includes an X-Powered-By HTTP response header exposing the specific Ratchet version. This could potentially be used during reconnaissance to gain more information to prepare following attacks (see #932 and others).

At the moment, there does not appear to be a way to configure Ratchet to control this behavior. I would like to use this ticket as an opportunity to see if the default behavior makes sense, if we should remove this header in its entirety, if we should only include the major version or if we really need an option to control this.

For example, nginx always sends the Server: nginx header with an option to exclude the specific version (server_tokens off). For ReactPHP, we always send the Server: ReactPHP/1 header with only the major version included (https://github.com/reactphp/http/pull/374). PHP always sends the X-Powered-By: PHP/6.0.0 header unless expose_php is off.

In the meantime, you can always avoid this header by configuring your reverse proxy to remove this header. For nginx this should be as easy as:

proxy_hide_header X-Powered-By;

Note that irrespective of this header, the fact that Ratchet is serving the HTTP request can always be determined through other means, such as specific HTTP headers, timing attacks and additional implementation quirks. I do not currently see that this HTTP header alone constitutes a security issue on its own, but I definitely agree that this could contribute to seeing more targeted attacks should any security issues arise.

Any input is welcome :+1:

Rezyan commented 1 year ago

I will try to describe my opinion on all your solutions.

if we should remove this header in its entirety

This is definitely the best solution, although it is radical. I can understand that you might not agree to use such a solution. But I think that this HTTP header does not add anything useful to Ratchet. Indeed, it is more likely to bring harms than benefits.

if we should only include the major version

Surely a good compromise, easy to change. But, it still provides useful information to attackers.

if we really need an option to control this

This would work somewhat similarly to PHP (with expose_php). In my humble opinion, I think it's better to fix the problem at the source, and prevent the developer from using an HTTP header that exposes information about the server technologies that are used. So in my opinion, this is the least good solution.


Note that irrespective of this header, the fact that Ratchet is serving the HTTP request can always be determined through other means, such as specific HTTP headers, timing attacks and additional implementation quirks. I do not currently see that this HTTP header alone constitutes a security issue on its own, but I definitely agree that this could contribute to seeing more targeted attacks should any security issues arise.

I agree with you, you are absolutely right. But leaving this header only makes it easier for potential attacks (e.g. in future updates). For example, it is easier to look at HTTP headers than to do a timing attack.


If this HTTP header is intended to remain in the code, perhaps we could add a section in the README.md file that would indicate how to remove the HTTP header, both on Nginx and Apache. What do you think about this?

SimonFrings commented 1 year ago

This is definitely the best solution, although it is radical. I can understand that you might not agree to use such a solution. But I think that this HTTP header does not add anything useful to Ratchet. Indeed, it is more likely to bring harms than benefits.

@Rezyan I agree with you, not sure tho how many users will be affected by this change (BC-break). This is something we want to evaluate here, but I think finding a temporary solution and completely removing it later may be the right way to go about this.

If this HTTP header is intended to remain in the code, perhaps we could add a section in the README.md file that would indicate how to remove the HTTP header, both on Nginx and Apache. What do you think about this?

I think adding this as part of a documentation should be at least one solution here, completely agreed :+1:

NkazimuloMvundla commented 1 year ago

@Rezyan , have you come right with this? was planning on using Ratchet but if it has this sort of issue might look away

Rezyan commented 1 year ago

@Rezyan , have you come right with this? was planning on using Ratchet but if it has this sort of issue might look away

There's no relevant solution at the moment. But it may be possible to fork the repositority and fix the vulnerable parts of the code...

SimonFrings commented 1 year ago

@NkazimuloMvundla There are a few options in @clue's description of this ticket, for example you can also avoid this header by configuring your reverse proxy to remove this header. If you're using nginx, this looks something like this:

proxy_hide_header X-Powered-By;

If you have any input on how we should handle the situation with the X-Powered-By header, we're happy about your input and your reasoning on this :+1:

FYI: I will mark these last answers as off-topic (mine included) as we didn't really progress in finding a good solution for the overall topic.