fix: werkzeug >= 0.15.0 compatibility (fix #303)

This commit is contained in:
ziirish 2019-05-07 17:35:53 +02:00
parent ec6e305f2f
commit 384e88d2c6
No known key found for this signature in database
GPG key ID: 72DB229A64B54E46
8 changed files with 116 additions and 48 deletions

View file

@ -7,6 +7,7 @@ Current
- **BREAKING**: the *single* and *version* options within the ``[Global]`` section have been removed in favor of a new unified *backend* option - **BREAKING**: the *single* and *version* options within the ``[Global]`` section have been removed in favor of a new unified *backend* option
- **BREAKING**: a change introduced by `#284 <https://git.ziirish.me/ziirish/burp-ui/issues/284>`_ may return wrong timestamps for backups made with burp-server <= 2.1.10 if your current burp-server is >= 2.1.10 - **BREAKING**: a change introduced by `#284 <https://git.ziirish.me/ziirish/burp-ui/issues/284>`_ may return wrong timestamps for backups made with burp-server <= 2.1.10 if your current burp-server is >= 2.1.10
- **BREAKING**: the authentication backends section have been renamed with the ``:AUTH`` suffix - **BREAKING**: the authentication backends section have been renamed with the ``:AUTH`` suffix
- **BREAKING**: the ``prefix`` option has been moved from the ``[Global]`` configuration section to the ``[Production]`` one
- Add: new `audit logging <https://git.ziirish.me/ziirish/burp-ui/issues/260>`_ system - Add: new `audit logging <https://git.ziirish.me/ziirish/burp-ui/issues/260>`_ system
- Add: new ``bui-monitor`` processes pool + ``async`` backend to parallelize some requests `#278 <https://git.ziirish.me/ziirish/burp-ui/issues/278>`_ - Add: new ``bui-monitor`` processes pool + ``async`` backend to parallelize some requests `#278 <https://git.ziirish.me/ziirish/burp-ui/issues/278>`_
- Add: new `listen` and `listen_status` options in burp-2.2.10 `#279 <https://git.ziirish.me/ziirish/burp-ui/issues/279>`_ - Add: new `listen` and `listen_status` options in burp-2.2.10 `#279 <https://git.ziirish.me/ziirish/burp-ui/issues/279>`_

View file

@ -10,6 +10,7 @@ jQuery/Bootstrap
.. moduleauthor:: Ziirish <hi+burpui@ziirish.me> .. moduleauthor:: Ziirish <hi+burpui@ziirish.me>
""" """
import os import os
import json
import time import time
import logging import logging
@ -148,9 +149,14 @@ def create_app(conf=None, verbose=0, logfile=None, **kwargs):
# Manage reverse_proxy special tricks & improvements # Manage reverse_proxy special tricks & improvements
if reverse_proxy: # pragma: no cover if reverse_proxy: # pragma: no cover
from werkzeug.contrib.fixers import ProxyFix from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app) kwargs = {}
if app.config['NUM_PROXIES'] > 0:
kwargs = app.config['PROXY_FIX_ARGS'].format(num_proxies=app.config['NUM_PROXIES'])
kwargs = json.loads(kwargs)
logger.debug(f"Using {kwargs} as ProxyFix parameters")
app = ProxyFix(app, **kwargs)
if app.storage and app.storage.lower() == 'redis': if app.storage and app.storage.lower() == 'redis':
try: try:
@ -373,10 +379,10 @@ def create_app(conf=None, verbose=0, logfile=None, **kwargs):
g.date_format = session.get('dateFormat', 'llll') g.date_format = session.get('dateFormat', 'llll')
# make sure to store secure cookie if required # make sure to store secure cookie if required
if app.config['BUI_SCOOKIE']: if app.config['BUI_SCOOKIE']:
criteria = [ criteria = (
request.is_secure, request.is_secure,
request.headers.get('X-Forwarded-Proto', 'http') == 'https' request.headers.get('X-Forwarded-Proto', 'http') == 'https'
] )
app.config['SESSION_COOKIE_SECURE'] = \ app.config['SESSION_COOKIE_SECURE'] = \
app.config['REMEMBER_COOKIE_SECURE'] = any(criteria) app.config['REMEMBER_COOKIE_SECURE'] = any(criteria)
if '_extra' in request.args: if '_extra' in request.args:

View file

@ -11,6 +11,7 @@ import os
import re import re
import sys import sys
import logging # noqa import logging # noqa
import warnings
from ..tools.logging import logger from ..tools.logging import logger
from ..misc.auth.handler import UserAuthHandler from ..misc.auth.handler import UserAuthHandler
@ -25,8 +26,8 @@ from flask import Flask
BUI_DEFAULTS = { BUI_DEFAULTS = {
'Global': { 'Global': {
'port': 5000, 'port': 0,
'bind': '::', 'bind': '',
'ssl': False, 'ssl': False,
'sslcert': '', 'sslcert': '',
'sslkey': '', 'sslkey': '',
@ -64,6 +65,8 @@ BUI_DEFAULTS = {
'database': '', 'database': '',
'limiter': False, 'limiter': False,
'ratio': '60/minute', 'ratio': '60/minute',
'num_proxies': 0,
'proxy_fix_args': "{'x_for': {num_proxies}, 'x_host': {num_proxies}, 'x_prefix': {num_proxies}}",
}, },
'WebSocket': { 'WebSocket': {
'enabled': True, 'enabled': True,
@ -137,40 +140,41 @@ class BUIServer(Flask):
self.conf.parse(conf, True, BUI_DEFAULTS) self.conf.parse(conf, True, BUI_DEFAULTS)
self.conf.default_section('Global') self.conf.default_section('Global')
self.config['BUI_PORT'] = self.conf.safe_get( self.config['BUI_BIND'] = self.conf.safe_get('bind')
'port', self.config['BUI_PORT'] = self.conf.safe_get('port', 'integer')
'integer' if self.config['BUI_BIND'] or self.config['BUI_PORT']:
) warnings.warn(
self.demo = self.config['BUI_DEMO'] = self.conf.safe_get( "The 'bind' and 'port' configuration options are now deprecated and "
'demo', "have no effect on burp-ui anymore unless you use the 'burp-ui-legacy' "
'boolean' "command.\n"
) "Please use the '-h' and '-p' command line flags instead.",
UserWarning
)
self.demo = self.config['BUI_DEMO'] = self.conf.safe_get('demo', 'boolean')
self.config['BUI_DSN'] = self.conf.safe_get('dsn') self.config['BUI_DSN'] = self.conf.safe_get('dsn')
self.config['BUI_PIWIK_URL'] = self.conf.safe_get('piwik_url') self.config['BUI_PIWIK_URL'] = self.conf.safe_get('piwik_url')
self.config['BUI_PIWIK_SCRIPT'] = self.conf.safe_get('piwik_script') self.config['BUI_PIWIK_SCRIPT'] = self.conf.safe_get('piwik_script')
self.config['BUI_PIWIK_ID'] = self.conf.safe_get('piwik_id', 'integer') self.config['BUI_PIWIK_ID'] = self.conf.safe_get('piwik_id', 'integer')
self.config['BUI_BIND'] = self.conf.safe_get('bind')
self.config['BACKEND'] = self.conf.safe_get('backend') self.config['BACKEND'] = self.conf.safe_get('backend')
# FIXME: this sucks, we need to test the burp2 backend as well!
if unittest: if unittest:
self.config['BACKEND'] = 'burp1' self.config['BACKEND'] = 'burp1'
self.config['BUI_SSL'] = self.conf.safe_get(
'ssl',
'boolean'
)
self.config['STANDALONE'] = self.config['BACKEND'] != 'multi' self.config['STANDALONE'] = self.config['BACKEND'] != 'multi'
self.config['BUI_SSLCERT'] = self.conf.safe_get( self.config['BUI_SSL'] = self.conf.safe_get('ssl', 'boolean')
'sslcert' self.config['BUI_SSLCERT'] = self.conf.safe_get('sslcert')
) self.config['BUI_SSLKEY'] = self.conf.safe_get('sslkey')
self.config['BUI_SSLKEY'] = self.conf.safe_get( if self.config['BUI_SSL'] or self.config['BUI_SSLCERT'] or \
'sslkey' self.config['BUI_SSLKEY']:
) warnings.warn(
prefix = self.config['BUI_PREFIX'] = self.conf.safe_get( "The 'ssl', 'sslcert' and 'sslkey' configuration options are deprecated "
'prefix' "as of v0.4.0. It means they have no effect on burp-ui anymore. "
) "If you really need them, consider using the 'burp-ui-legacy' command "
if prefix and not prefix.startswith('/'): "instead.",
if prefix.lower() != 'none': UserWarning
self.logger.warning("'prefix' must start with a '/'!") )
self.config['BUI_PREFIX'] = ''
# TODO: remove in 0.8.0
old_prefix = self.conf.safe_get('prefix')
self.plugins = self.config['BUI_PLUGINS'] = self.conf.safe_get( self.plugins = self.config['BUI_PLUGINS'] = self.conf.safe_get(
'plugins', 'plugins',
@ -274,6 +278,33 @@ class BUIServer(Flask):
else: else:
self.config['WITH_CELERY'] = self.use_celery and \ self.config['WITH_CELERY'] = self.use_celery and \
self.use_celery.lower() != 'none' self.use_celery.lower() != 'none'
self.config['NUM_PROXIES'] = self.conf.safe_get(
'num_proxies',
'integer',
section='Production'
)
self.config['PROXY_FIX_ARGS'] = self.conf.safe_get(
'proxy_fix_args',
section='Production'
)
prefix = self.conf.safe_get(
'prefix',
section='Production'
)
if not prefix and old_prefix:
# TODO: remove in a later version
prefix = old_prefix
warnings.warn(
"The 'prefix' option has been moved from the '[Global]' section to the "
"'[Production]' section",
UserWarning
)
if prefix and not prefix.startswith('/'):
if prefix.lower() != 'none':
self.logger.warning("'prefix' must start with a '/'!")
self.config['BUI_PREFIX'] = ''
elif prefix:
self.config['BUI_PREFIX'] = prefix
# WebSocket options # WebSocket options
self.ws_enabled = self.config['WS_ENABLED'] = self.conf.safe_get( self.ws_enabled = self.config['WS_ENABLED'] = self.conf.safe_get(

View file

@ -55,12 +55,6 @@ The `burpui.cfg`_ configuration file contains a ``[Global]`` section as follow:
# list the misc/audit directory to see the available backends # list the misc/audit directory to see the available backends
# default is no audit log # default is no audit log
audit = basic audit = basic
# You can change the prefix if you are behind a reverse-proxy under a custom
# root path. For example: /burpui
# You can also configure your reverse-proxy to announce the prefix through the
# 'X-Script-Name' header. In this case, the bellow prefix will be ignored in
# favour of the one announced by your reverse-proxy
prefix = none
# list of paths to look for external plugins # list of paths to look for external plugins
plugins = none plugins = none
@ -78,8 +72,6 @@ Each option is commented, but here is a more detailed documentation:
- *auth*: What `Authentication`_ backend to use. - *auth*: What `Authentication`_ backend to use.
- *acl*: What `ACL`_ module to use. - *acl*: What `ACL`_ module to use.
- *audit*: What `Audit`_ module to use. - *audit*: What `Audit`_ module to use.
- *prefix*: You can host `Burp-UI`_ behind a sub-root path. See the `gunicorn
<gunicorn.html#sub-root-path>`__ page for details.
- *plugins*: Specify a list of paths to look for external plugins. See the - *plugins*: Specify a list of paths to look for external plugins. See the
`Plugins <plugins.html>`_ page for details on how to write plugins. `Plugins <plugins.html>`_ page for details on how to write plugins.
@ -161,6 +153,30 @@ follow:
# limiter ratio # limiter ratio
# see https://flask-limiter.readthedocs.io/en/stable/#ratelimit-string # see https://flask-limiter.readthedocs.io/en/stable/#ratelimit-string
ratio = 60/minute ratio = 60/minute
# you can change the prefix if you are behind a reverse-proxy under a custom
# root path. For example: /burpui
# You can also configure your reverse-proxy to announce the prefix through the
# 'X-Script-Name' header. In this case, the bellow prefix will be ignored in
# favour of the one announced by your reverse-proxy
prefix = none
# ProxyFix
# number of reverse-proxy to trust in order to retrieve some HTTP headers
# All the details can be found here:
# https://werkzeug.palletsprojects.com/en/0.15.x/middleware/proxy_fix/#module-werkzeug.middleware.proxy_fix
num_proxies = 0
# alternatively, you can specify your own ProxyFix args.
# The default is: "{'x_for': {num_proxies}, 'x_host': {num_proxies}, 'x_prefix': {num_proxies}}"
# if num_proxies > 0, else it defaults to ProxyFix defaults
proxy_fix_args = "{'x_for': {num_proxies}, 'x_host': {num_proxies}, 'x_prefix': {num_proxies}}"
- *prefix*: You can host `Burp-UI`_ behind a sub-root path. See the `gunicorn
<gunicorn.html#sub-root-path>`__ page for details.
- *num_proxies*: This is useful only if you host `Burp-UI`_ behind a
`reverse-proxy <gunicorn.html#reverse-proxy>`__.
- *proxy_fix_args*: Same as above. Please refer to `Werkzeug's documentation
<https://werkzeug.palletsprojects.com/en/0.15.x/middleware/proxy_fix/#module-werkzeug.middleware.proxy_fix>`_
for details.
WebSocket WebSocket

View file

@ -257,10 +257,10 @@ Sub-root path
You can host `Burp-UI`_ behind a sub-root path. For instance ``/burpui``. You can host `Burp-UI`_ behind a sub-root path. For instance ``/burpui``.
To accomplish this, you can either setup your reverse-proxy to announce the To accomplish this, you can either setup your reverse-proxy to announce the
desired *prefix*, or you can use the ``prefix`` option in your `Burp-UI`_ desired *prefix*, or you can use the ``prefix`` option in your `Burp-UI`_
configuration file (see `usage <advanced_usage.html>`_ for details). configuration file (see `usage <advanced_usage.html#production>`_ for details).
If you want to configure this reverse-proxy side, you need to announce the HTTP If you want to configure this reverse-proxy side, you need to announce the HTTP
Header ``X-Script-Name``. Header ``X-Script-Name``. Alternatively, you can use the ``X_Forwarded_Prefix``.
Here is a sample configuration for Nginx: Here is a sample configuration for Nginx:
@ -280,6 +280,7 @@ Here is a sample configuration for Nginx:
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-For $remote_addr;
# Our service is hosted behind the "/burpui" prefix # Our service is hosted behind the "/burpui" prefix
# Alternatively you can use the "X_FORWARDED_PREFIX" instead
proxy_set_header X-Script-Name /burpui; proxy_set_header X-Script-Name /burpui;
proxy_read_timeout 300; proxy_read_timeout 300;

View file

@ -36,6 +36,9 @@ v0.7.0
and the burp-client used by burp-ui must be able to reach the burp-server). and the burp-client used by burp-ui must be able to reach the burp-server).
A new timeout has been added though in order for ``bui-agent`` to wait for the A new timeout has been added though in order for ``bui-agent`` to wait for the
burp-server to be ready. burp-server to be ready.
- **Breaking** - the ``prefix`` option has been moved from the ``[Global]``
configuration section to the ``[Production]`` one for consistency with the new
*Production* options introduced.
v0.6.0 v0.6.0
------ ------

View file

@ -14,3 +14,4 @@ pyOpenSSL==19.0.0
configobj==5.0.6 configobj==5.0.6
async_generator async_generator
Click==7.0 Click==7.0
werkzeug>=0.15.0

View file

@ -24,12 +24,6 @@ acl = basic
# list the misc/audit directory to see the available backends # list the misc/audit directory to see the available backends
# default is no audit log # default is no audit log
audit = basic audit = basic
# you can change the prefix if you are behind a reverse-proxy under a custom
# root path. For example: /burpui
# You can also configure your reverse-proxy to announce the prefix through the
# 'X-Script-Name' header. In this case, the bellow prefix will be ignored in
# favour of the one announced by your reverse-proxy
prefix = none
# list of paths to look for external plugins # list of paths to look for external plugins
plugins = none plugins = none
@ -88,6 +82,21 @@ limiter = false
# limiter ratio # limiter ratio
# see https://flask-limiter.readthedocs.io/en/stable/#ratelimit-string # see https://flask-limiter.readthedocs.io/en/stable/#ratelimit-string
ratio = 60/minute ratio = 60/minute
# you can change the prefix if you are behind a reverse-proxy under a custom
# root path. For example: /burpui
# You can also configure your reverse-proxy to announce the prefix through the
# 'X-Script-Name' header. In this case, the bellow prefix will be ignored in
# favour of the one announced by your reverse-proxy
prefix = none
# ProxyFix
# number of reverse-proxy to trust in order to retrieve some HTTP headers
# All the details can be found here:
# https://werkzeug.palletsprojects.com/en/0.15.x/middleware/proxy_fix/#module-werkzeug.middleware.proxy_fix
num_proxies = 0
# alternatively, you can specify your own ProxyFix args.
# The default is: "{'x_for': {num_proxies}, 'x_host': {num_proxies}, 'x_prefix': {num_proxies}}"
# if num_proxies > 0, else it defaults to ProxyFix defaults
proxy_fix_args = "{'x_for': {num_proxies}, 'x_host': {num_proxies}, 'x_prefix': {num_proxies}}"
[WebSocket] [WebSocket]
## This section contains WebSocket server specific options. ## This section contains WebSocket server specific options.