tornado icon indicating copy to clipboard operation
tornado copied to clipboard

web: Remove version from server header

Open Carl7189 opened this issue 3 years ago • 6 comments

Hi all

I would like to know how I can hide the http headers of Jupyterhub since it appears in Server: Tornado 5.1.1, I do not want the tornado version to appear

Thanks a lot

Carl7189 avatar Oct 13 '20 21:10 Carl7189

You can override set_default_headers() in the RequestHandler sub-classes, and set or clear the Server response header there. This would have to be done in the Jupyter code base.

You could perhaps request that project to provide a config option, but they are probably not interested: https://github.com/jupyterhub/jupyterhub/issues/1674 - you probably want to put it behind a reverse-proxy: https://jupyterhub.readthedocs.io/en/stable/reference/config-proxy.html

ploxiln avatar Oct 14 '20 00:10 ploxiln

set_default_headers is awkward to use for this purpose because you'd need to use subclasses of StaticFileHandler, RedirectHandler, etc. If you care about the server header, you should really be running behind a proxy that gives you a centralized place to control it.

This request comes up periodically - security compliance checklists often say you should hide version numbers here. I think that's generally silly, but on the other hand there's no strong reason to include the version in the first place. I think we should probably at least remove the version from the server header, and maybe just remove it completely.

bdarnell avatar Oct 26 '20 00:10 bdarnell

Use a custom tornado.web.OutputTransform to customize or remove the default Server header. It will apply to all outgoing responses.

from tornado import ioloop, web


class ServerHeaderTransform(web.OutputTransform):
    def transform_first_chunk(self, status_code, headers, chunk, finishing):
        headers.pop('Server')
        return status_code, headers, chunk


app = web.Application(transforms=[ServerHeaderTransform])
app.listen(8000)
ioloop.IOLoop.current().start()
$ curl -v localhost:8000
*   Trying ::1:8000...
* Connected to localhost (::1) port 8000 (#0)
> GET / HTTP/1.1
> Host: localhost:8000
> User-Agent: curl/7.73.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 404 Not Found
< Content-Type: text/html; charset=UTF-8
< Date: Tue, 17 Nov 2020 21:18:02 GMT
< Content-Length: 69
<
* Connection #0 to host localhost left intact
<html><title>404: Not Found</title><body>404: Not Found</body></html> 

nvllsvm avatar Nov 17 '20 21:11 nvllsvm

Oh, I had forgotten all about OutputTransforms. That would work, although OutputTransform is undocumented and I've never really considered them as part of the web module's public API so I wouldn't want to encourage this (the HTTPMessageDelegate interfaces would be a supported way to do the same thing). Better to just change the source to stop emitting the server header completely.

bdarnell avatar Nov 19 '20 02:11 bdarnell

Hi,

I'm using Tornado 6.0.4 and I tried the solution above but I've noticed that my Content-Encoding: gzip disappeared together with the Server header:

class ServerHeaderTransform(OutputTransform):
    def transform_first_chunk(self, status_code, headers, chunk, finishing):
        headers.pop('Server')
        return status_code, headers, chunk


class MyApplication(Application):
    def __init__(self, *args, **kwargs) -> None:
        kwargs['compress_response'] = True
        kwargs['transforms'] = [ServerHeaderTransform]
        super().__init__(*args, **kwargs)

app = MyApplication()
app.listen(8000)
ioloop.IOLoop.current().start()

Without the kwargs['transforms'] = [ServerHeaderTransform] line I'm getting gzip responses as expected (when asking for a compressed response.

Any idea why it doesn't work together with the compress_response flag?

itayB avatar Jul 12 '21 11:07 itayB

@itayB

Specifying the transforms kwarg is overrides the compress_response flag. https://github.com/tornadoweb/tornado/blob/aa9d32d5e89b290dad69e0c6655b7497ea492e45/tornado/web.py#L2040-L2045

Use self.add_transform instead. https://github.com/tornadoweb/tornado/blob/aa9d32d5e89b290dad69e0c6655b7497ea492e45/tornado/web.py#L2128-L2129

nvllsvm avatar Jul 12 '21 14:07 nvllsvm