runsisi's

technical notes

CherryPy 隐藏版本信息

2019-05-30 runsisibe

CherryPy 默认会在响应的头部带上服务器的版本号,但一些安全扫描软件会认为这是一个漏洞:

# https://github.com/cherrypy/cherrypy/blob/v18.1.1/cherrypy/_cprequest.py#L839
class Response(object):
    def __init__(self):
        dict.update(self.headers, {
            'Content-Type': 'text/html',
            'Server': 'CherryPy/' + cherrypy.__version__,
            'Date': httputil.HTTPDate(self.time),
        })

针对每个请求的处理修改返回的服务器信息字段,有如下两种方式:

@cherrypy.expose
@cherrypy.tools.response_headers(headers=[("Server", "wtf")])
def index(self):
    return self.health()
@cherrypy.expose
def index(self):
    cherrypy.serving.response.headers['Server'] = "wtf"
    return self.health()

但比较坑爹的是,favicon 使用了 staticfile 进行处理,同样会返回版本信息:

# https://github.com/cherrypy/cherrypy/blob/v18.1.1/cherrypy/_cptree.py#L234
def mount(self, root, script_name='', config=None):
    # If mounted at "", add favicon.ico
    needs_favicon = (
        script_name == ''
        and root is not None
        and not hasattr(root, 'favicon_ico')
    )
    if needs_favicon:
        favicon = os.path.join(
            os.getcwd(),
            os.path.dirname(__file__),
            'favicon.ico',
        )
        root.favicon_ico = tools.staticfile.handler(favicon)

此外,404 之类的错误也会返回版本信息。

显然,上面提到的通过给每个请求单独修改响应的方式行不通,不过 CherryPy 的 hook 机制比较强大,可以通过配置的方式给所有的响应都添加处理:

cherrypy.config.update({
    'tools.response_headers.on': True,
    'tools.response_headers.headers': [("Server", "wtf")]
})

但是,还一个更坑爹的是 CherryPy 直接在错误页面返回了版本信息:

https://github.com/cherrypy/cherrypy/blob/v18.1.1/cherrypy/_cperror.py#L467

<body>
  <h2>%(status)s</h2>
  <p>%(message)s</p>
  <pre id="traceback">%(traceback)s</pre>
<div id="powered_by">
  <span>
    Powered by <a href="http://www.cherrypy.org">CherryPy %(version)s</a>
  </span>
</div>
</body>

可以通过如下的方式进行修改:

from cherrypy import _cperror as cperror

cperror._HTTPErrorTemplate = "wtf"

参考资料

CherryPy — A Minimalist Python Web Framework

https://docs.cherrypy.org/en/latest/index.html

CherryPy Extend

https://docs.cherrypy.org/en/latest/extend.html

Hook into Cherry Pys Core Engine

https://www.pythonstudio.us/cherrypy-guide/hook-into-cherrypys-core-engine.html