aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fietsboek/__init__.py2
-rw-r--r--fietsboek/config.py20
2 files changed, 21 insertions, 1 deletions
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`.