From 4ddbf1608294e1864d4a8b574a2cc8bc233d0567 Mon Sep 17 00:00:00 2001 From: Greg Dubicki Date: Mon, 5 Dec 2022 23:18:25 +0000 Subject: [PATCH 1/2] Start warning about upcoming SECRET_KEY default removal Related to #721 --- README.md | 5 ++--- puppetboard/app.py | 3 ++- puppetboard/default_settings.py | 2 +- puppetboard/docker_settings.py | 2 +- puppetboard/utils.py | 21 +++++++++++++++++++++ 5 files changed, 27 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index bed493d2..6c3c3e12 100644 --- a/README.md +++ b/README.md @@ -175,9 +175,8 @@ Other settings that might be interesting, in no particular order: Defaults to `friendly`. - `CODE_PREFIX_TO_REMOVE`: what code path that should be shortened in "Friendly errors" to "…" for readability. A regexp. Defaults to `/etc/puppetlabs/code/environments(/.*?/modules)?`. -- `SECRET_KEY`: Refer to [Flask documentation](https://flask.palletsprojects.com/en/1.1.x/quickstart/#sessions), - section "How to generate good secret keys" for more info. Defaults to a random 24-char string generated by - `os.random(24)`. +- `SECRET_KEY`: Refer to [Flask documentation](https://flask.palletsprojects.com/en/2.0.x/quickstart/#sessions), + section "How to generate good secret keys" for more info. Defaults to a random 24-char string generated by `os.random(24)`, prepended with a `default-` string. **Warning** Leaving SECRET_KEY set to a default value WILL cause issues when the app is restarted or has more than 1 replica (f.e. uWSGI workers, k8s replicas etc.) and some features (in particular: queries) are used. Please set SECRET_KEY to your own value, the same for all app replicas. This will be REQUIRED starting with Puppetboard 5.x which will NOT contain the default value anymore. Please see [#721](https://github.com/voxpupuli/puppetboard/issues/721) for more info. - `PUPPETDB_TIMEOUT`: Defaults to 20 seconds, but you might need to increase this value. It depends on how big the results are when querying PuppetDB. This behaviour will change in a future release when pagination will be introduced. - `UNRESPONSIVE_HOURS`: The amount of hours since the last check-in after which a node is considered unresponsive. diff --git a/puppetboard/app.py b/puppetboard/app.py index 0a466a97..f5611497 100644 --- a/puppetboard/app.py +++ b/puppetboard/app.py @@ -35,13 +35,14 @@ from puppetboard.core import get_app, get_puppetdb from puppetboard.version import __version__ -from puppetboard.utils import check_db_version +from puppetboard.utils import check_db_version, check_secret_key app = get_app() puppetdb = get_puppetdb() running_as = os.path.basename(sys.argv[0]) if running_as not in ['pytest', 'py.test']: check_db_version(puppetdb) +check_secret_key(app.config.get('SECRET_KEY')) logging.basicConfig(level=app.config['LOGLEVEL'].upper()) log = logging.getLogger(__name__) diff --git a/puppetboard/default_settings.py b/puppetboard/default_settings.py index 16be3e82..9b804a5b 100644 --- a/puppetboard/default_settings.py +++ b/puppetboard/default_settings.py @@ -8,7 +8,7 @@ PUPPETDB_CERT = None PUPPETDB_TIMEOUT = 20 DEFAULT_ENVIRONMENT = 'production' -SECRET_KEY = os.urandom(24) +SECRET_KEY = f"default-{os.urandom(24)}" UNRESPONSIVE_HOURS = 2 ENABLE_QUERY = True # Uncomment to restrict the enabled PuppetDB endpoints in the query page. diff --git a/puppetboard/docker_settings.py b/puppetboard/docker_settings.py index c6049a6b..b1ef559f 100644 --- a/puppetboard/docker_settings.py +++ b/puppetboard/docker_settings.py @@ -59,7 +59,7 @@ def coerce_bool(v, default): PUPPETDB_PROTO = os.getenv('PUPPETDB_PROTO', None) PUPPETDB_TIMEOUT = int(os.getenv('PUPPETDB_TIMEOUT', '20')) DEFAULT_ENVIRONMENT = os.getenv('DEFAULT_ENVIRONMENT', 'production') -SECRET_KEY = os.getenv('SECRET_KEY', os.urandom(24)) +SECRET_KEY = os.getenv('SECRET_KEY', f"default-{os.urandom(24)}") UNRESPONSIVE_HOURS = int(os.getenv('UNRESPONSIVE_HOURS', '2')) ENABLE_QUERY = coerce_bool(os.getenv('ENABLE_QUERY'), True) # Uncomment to restrict the enabled PuppetDB endpoints in the query page. diff --git a/puppetboard/utils.py b/puppetboard/utils.py index deae218c..7ee1405c 100644 --- a/puppetboard/utils.py +++ b/puppetboard/utils.py @@ -48,6 +48,27 @@ def check_db_version(puppetdb): sys.exit(2) +def check_secret_key(secret_key_value): + """ + Check if the secret key value is set to a default value, that will stop + being accepted in v5.x of the app. + """ + if secret_key_value.startswith("default-"): + log.warning( + "Leaving SECRET_KEY set to a default value WILL cause issues" + " when the app is restarted or has more than 1 replica" + " (f.e. uWSGI workers, k8s replicas etc.) and some features" + " (in particular: queries) are used.\n" + "Please set SECRET_KEY to your own value, the same for all app" + " replicas.\n" + "This will be REQUIRED starting with Puppetboard 5.x which" + " will NOT contain the default value anymore.\n" + "Please see" + " https://github.com/voxpupuli/puppetboard/issues/721" + " for more info." + ) + + def parse_python(value: str): """ :param value: any string, number, bool, list or a dict From f5d29f5697d34ccb7ecdf5d13f7a469ecc68b40f Mon Sep 17 00:00:00 2001 From: Greg Dubicki Date: Mon, 5 Dec 2022 23:46:24 +0000 Subject: [PATCH 2/2] Use a random string, not bytes to prevent warnings --- README.md | 2 +- puppetboard/default_settings.py | 4 ++-- puppetboard/docker_settings.py | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6c3c3e12..372a9b31 100644 --- a/README.md +++ b/README.md @@ -176,7 +176,7 @@ Other settings that might be interesting, in no particular order: - `CODE_PREFIX_TO_REMOVE`: what code path that should be shortened in "Friendly errors" to "…" for readability. A regexp. Defaults to `/etc/puppetlabs/code/environments(/.*?/modules)?`. - `SECRET_KEY`: Refer to [Flask documentation](https://flask.palletsprojects.com/en/2.0.x/quickstart/#sessions), - section "How to generate good secret keys" for more info. Defaults to a random 24-char string generated by `os.random(24)`, prepended with a `default-` string. **Warning** Leaving SECRET_KEY set to a default value WILL cause issues when the app is restarted or has more than 1 replica (f.e. uWSGI workers, k8s replicas etc.) and some features (in particular: queries) are used. Please set SECRET_KEY to your own value, the same for all app replicas. This will be REQUIRED starting with Puppetboard 5.x which will NOT contain the default value anymore. Please see [#721](https://github.com/voxpupuli/puppetboard/issues/721) for more info. + section "How to generate good secret keys" for more info. Defaults to a random 64-char string generated by `secrets.token_hex(32)`, prepended with a `default-` string. **Warning** Leaving SECRET_KEY set to a default value WILL cause issues when the app is restarted or has more than 1 replica (f.e. uWSGI workers, k8s replicas etc.) and some features (in particular: queries) are used. Please set SECRET_KEY to your own value, the same for all app replicas. This will be REQUIRED starting with Puppetboard 5.x which will NOT contain the default value anymore. Please see [#721](https://github.com/voxpupuli/puppetboard/issues/721) for more info. - `PUPPETDB_TIMEOUT`: Defaults to 20 seconds, but you might need to increase this value. It depends on how big the results are when querying PuppetDB. This behaviour will change in a future release when pagination will be introduced. - `UNRESPONSIVE_HOURS`: The amount of hours since the last check-in after which a node is considered unresponsive. diff --git a/puppetboard/default_settings.py b/puppetboard/default_settings.py index 9b804a5b..072ecc87 100644 --- a/puppetboard/default_settings.py +++ b/puppetboard/default_settings.py @@ -1,4 +1,4 @@ -import os +import secrets PUPPETDB_HOST = 'localhost' PUPPETDB_PORT = 8080 @@ -8,7 +8,7 @@ PUPPETDB_CERT = None PUPPETDB_TIMEOUT = 20 DEFAULT_ENVIRONMENT = 'production' -SECRET_KEY = f"default-{os.urandom(24)}" +SECRET_KEY = f"default-{secrets.token_hex(32)}" UNRESPONSIVE_HOURS = 2 ENABLE_QUERY = True # Uncomment to restrict the enabled PuppetDB endpoints in the query page. diff --git a/puppetboard/docker_settings.py b/puppetboard/docker_settings.py index b1ef559f..742dcfcd 100644 --- a/puppetboard/docker_settings.py +++ b/puppetboard/docker_settings.py @@ -1,5 +1,6 @@ import json import os +import secrets import tempfile import base64 import binascii @@ -59,7 +60,7 @@ def coerce_bool(v, default): PUPPETDB_PROTO = os.getenv('PUPPETDB_PROTO', None) PUPPETDB_TIMEOUT = int(os.getenv('PUPPETDB_TIMEOUT', '20')) DEFAULT_ENVIRONMENT = os.getenv('DEFAULT_ENVIRONMENT', 'production') -SECRET_KEY = os.getenv('SECRET_KEY', f"default-{os.urandom(24)}") +SECRET_KEY = os.getenv('SECRET_KEY', f"default-{secrets.token_hex(32)}") UNRESPONSIVE_HOURS = int(os.getenv('UNRESPONSIVE_HOURS', '2')) ENABLE_QUERY = coerce_bool(os.getenv('ENABLE_QUERY'), True) # Uncomment to restrict the enabled PuppetDB endpoints in the query page.