From 2b74f95e684d489150398396280d759c0c88b08f Mon Sep 17 00:00:00 2001 From: patrick Date: Tue, 23 Jun 2026 13:56:01 +0200 Subject: [PATCH] =?UTF-8?q?fix(security):=20K-5=20=E2=80=93=20LDAP/CalDAV/?= =?UTF-8?q?SMTP-Verschl=C3=BCsselung=20auf=20zentralen=20Datenschl=C3=BCss?= =?UTF-8?q?el?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ldap_service/caldav_service/email_service hatten je eine eigene _fernet()/ _decrypt_password(), die am JWT-SECRET_KEY hing. Damit honorierten sie das in core/crypto bereits umgesetzte SECRET_KEY_DATA NICHT – eine JWT-Key-Kompromittierung hätte weiterhin LDAP-/CalDAV-/SMTP-Passwörter offengelegt. Jetzt delegieren alle drei an core.crypto.get_fernet_key()/decrypt_value. Da auf beiden Servern SECRET_KEY_DATA nicht gesetzt ist, ist die Ableitung heute identisch (sha256(SECRET_KEY)) → bestehende verschlüsselte Werte bleiben lesbar, kein Bruch. Sobald SECRET_KEY_DATA gesetzt wird, gilt die Trennung dann konsistent für ALLE Datenverschlüsselung (TOTP + LDAP + CalDAV + SMTP). 190/190 Tests grün. Deployed 137 + 164. Co-Authored-By: Claude Opus 4.8 --- backend/app/services/caldav_service.py | 5 +++-- backend/app/services/email_service.py | 10 +++------- backend/app/services/ldap_service.py | 5 +++-- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/backend/app/services/caldav_service.py b/backend/app/services/caldav_service.py index 3c22cfd..4d84ee4 100644 --- a/backend/app/services/caldav_service.py +++ b/backend/app/services/caldav_service.py @@ -34,9 +34,10 @@ log = logging.getLogger(__name__) # ── Crypto (shared with SMTP/LDAP) ──────────────────────────────────────────── def _fernet(): + # K-5: zentraler Datenschlüssel (nutzt SECRET_KEY_DATA wenn gesetzt, sonst SECRET_KEY). from cryptography.fernet import Fernet - key = hashlib.sha256(settings.secret_key.encode()).digest() - return Fernet(base64.urlsafe_b64encode(key)) + from app.core.crypto import get_fernet_key + return Fernet(get_fernet_key()) def encrypt_password(plain: str) -> str: diff --git a/backend/app/services/email_service.py b/backend/app/services/email_service.py index 9eb2532..aec291c 100644 --- a/backend/app/services/email_service.py +++ b/backend/app/services/email_service.py @@ -44,13 +44,9 @@ def _html_wrapper(title: str, body: str) -> str: def _decrypt_password(encrypted: str) -> str: - """Fernet-Entschlüsselung (gleiche Implementierung wie ldap_service).""" - import base64 - import hashlib - from cryptography.fernet import Fernet - key = hashlib.sha256(settings.secret_key.encode()).digest() - f = Fernet(base64.urlsafe_b64encode(key)) - return f.decrypt(encrypted.encode()).decode() + """Fernet-Entschlüsselung über den zentralen Datenschlüssel (K-5).""" + from app.core.crypto import decrypt_value + return decrypt_value(encrypted) def _smtp_send_sync(cfg: SmtpConfig, to: str, subject: str, html: str) -> None: diff --git a/backend/app/services/ldap_service.py b/backend/app/services/ldap_service.py index 4b1750e..947722d 100644 --- a/backend/app/services/ldap_service.py +++ b/backend/app/services/ldap_service.py @@ -23,9 +23,10 @@ logger = logging.getLogger(__name__) def _fernet(): + # K-5: zentraler Datenschlüssel (nutzt SECRET_KEY_DATA wenn gesetzt, sonst SECRET_KEY). from cryptography.fernet import Fernet - key = hashlib.sha256(settings.secret_key.encode()).digest() - return Fernet(base64.urlsafe_b64encode(key)) + from app.core.crypto import get_fernet_key + return Fernet(get_fernet_key()) def encrypt_password(plain: str) -> str: