modified: web/app.py

modified:   web/blueprints/auth.py
	modified:   web/blueprints/group_admin.py
	modified:   web/blueprints/panel.py
	modified:   web/blueprints/site_admin.py
	modified:   web/config.py
	new file:   web/templates/404.html
	modified:   web/templates/admin/base.html
	modified:   web/templates/admin/group_edit.html
	modified:   web/templates/admin/group_members.html
	modified:   web/templates/admin/groups.html
	modified:   web/templates/admin/user_edit.html
	modified:   web/templates/admin/users.html
	modified:   web/templates/auth/admin_login.html
	modified:   web/templates/auth/login.html
	modified:   web/templates/base.html
	modified:   web/templates/group_admin/base.html
	modified:   web/templates/group_admin/database.html
	modified:   web/templates/group_admin/member_edit.html
	modified:   web/templates/group_admin/members.html
	modified:   web/templates/login.html
	modified:   web/templates/panel/dashboard.html
This commit is contained in:
simon
2026-04-13 09:55:50 +02:00
parent 486aa2ff18
commit 935dc3f909
22 changed files with 260 additions and 50 deletions

View File

@@ -5,12 +5,29 @@ Alle Einstellungen über ENV-Variablen (Coolify-kompatibel).
import os
def _as_bool(value: str | None, default: bool = False) -> bool:
if value is None:
return default
return value.strip().lower() in {"1", "true", "yes", "on"}
class Config:
DEFAULT_SECRET_KEY = "change-me-use-a-long-random-string-min-32-chars"
DEFAULT_PASSWORD_PEPPER = "change-me-global-pepper-secret-never-change"
# ── Flask ──────────────────────────────────────────────────
SECRET_KEY = os.getenv("SECRET_KEY", "change-me-use-a-long-random-string-min-32-chars")
SECRET_KEY = os.getenv("SECRET_KEY", DEFAULT_SECRET_KEY)
HOST = os.getenv("HOST") or "0.0.0.0"
PORT = int(os.getenv("PORT") or "5000")
DEBUG = (os.getenv("DEBUG") or "false").lower() == "true"
DEBUG = _as_bool(os.getenv("DEBUG"), default=False)
# Session-Cookie-Hardening
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = os.getenv("SESSION_COOKIE_SAMESITE") or "Lax"
SESSION_COOKIE_SECURE = _as_bool(os.getenv("SESSION_COOKIE_SECURE"), default=not DEBUG)
# Erzwingt sichere Secrets in Nicht-Debug-Umgebungen
ENFORCE_SECURE_CONFIG = _as_bool(os.getenv("ENFORCE_SECURE_CONFIG"), default=True)
# ── Panel-Datenbank (Nutzer, Gruppen, Mitgliedschaften) ────
PANEL_DB_HOST = os.getenv("PANEL_DB_HOST") or "localhost"
@@ -27,7 +44,7 @@ class Config:
CREDS_DB_NAME = os.getenv("CREDS_DB_NAME") or "mclogger_creds"
# ── Sicherheit ────────────────────────────────────────────
PASSWORD_PEPPER = os.getenv("PASSWORD_PEPPER", "change-me-global-pepper-secret-never-change")
PASSWORD_PEPPER = os.getenv("PASSWORD_PEPPER", DEFAULT_PASSWORD_PEPPER)
# Generieren: python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
FERNET_KEY = os.getenv("FERNET_KEY", "")
@@ -44,3 +61,20 @@ class Config:
"view_server_events": False,
"view_perms": False,
}
@classmethod
def validate_security(cls):
"""Fail-fast, damit unsichere Defaults nicht in Produktion laufen."""
if not cls.ENFORCE_SECURE_CONFIG or cls.DEBUG:
return
issues = []
if cls.SECRET_KEY == cls.DEFAULT_SECRET_KEY:
issues.append("SECRET_KEY must be set to a strong random value.")
if cls.PASSWORD_PEPPER == cls.DEFAULT_PASSWORD_PEPPER:
issues.append("PASSWORD_PEPPER must be set to a strong secret value.")
if not cls.FERNET_KEY:
issues.append("FERNET_KEY must be configured.")
if issues:
raise RuntimeError("Invalid security configuration: " + " ".join(issues))