From 2fae8e0d39f436976d90cfb94ac31a1a4427771d Mon Sep 17 00:00:00 2001 From: Daniel Schadt Date: Thu, 8 Dec 2022 17:48:02 +0100 Subject: don't use session_key directly While it should be fine the way it was, we might want to introduce more "secret keys" (like for additional cookies), for which we would need more secrets. --- fietsboek/__init__.py | 2 +- fietsboek/config.py | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/fietsboek/__init__.py b/fietsboek/__init__.py index e208a61..8e82131 100644 --- a/fietsboek/__init__.py +++ b/fietsboek/__init__.py @@ -73,7 +73,7 @@ def main(_global_config, **settings): def pages(_request): return page_manager - my_session_factory = SignedCookieSessionFactory(settings['session_key']) + my_session_factory = SignedCookieSessionFactory(parsed_config.derive_secret('sessions')) with Configurator(settings=settings) as config: config.include('pyramid_jinja2') config.include('.routes') diff --git a/fietsboek/config.py b/fietsboek/config.py index c85fd8e..05fd4f6 100644 --- a/fietsboek/config.py +++ b/fietsboek/config.py @@ -12,6 +12,7 @@ Most of the logic is handled by pydantic_. .. _pydantic: https://pydantic-docs.helpmanual.io/ """ # pylint: disable=no-name-in-module,no-self-argument,too-few-public-methods +import hashlib import logging import re import typing @@ -199,6 +200,25 @@ class Config(BaseModel): raise ValueError(f"Unknown mailing scheme {parsed.scheme}".strip()) return value + def derive_secret(self, what_for): + """Derive a secret for other parts of the application. + + All secrets are derived from ``secret_key`` in a deterministic way. See + https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/security.html#admonishment-against-secret-sharing + on why ``secret_key`` should not be used directly. + + :param what_for: What the secret is used for. Passing the same "use + case" will generate the same secret. + :type what_for: str + :return: The generated secret. + :rtype: str + """ + hasher = hashlib.sha256() + hasher.update(f"{len(what_for)}".encode("utf-8")) + hasher.update(self.session_key.encode("utf-8")) + hasher.update(what_for.encode("utf-8")) + return hasher.hexdigest() + def parse(config): """Parses the configuration into a :class:`Config`. -- cgit v1.2.3