From ae1af1f8d21e86e7dc8258fc17e66c8f61b71293b3fe07a540df86bcc703fe7d Mon Sep 17 00:00:00 2001 From: jhkaktus Date: Sun, 11 Oct 2026 00:07:06 +0200 Subject: [PATCH] refactor: drop built-in HTTPS, serve plain HTTP behind reverse proxy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TLS termination belongs to the trusted reverse proxy in front (nginx/caddy/...), not the app. run.py now binds plain HTTP to 127.0.0.1 (HOST/PORT configurable) and the dirty rollback of the reverted self-signed-cert logic was cleaned up. README updated. Verified: all endpoints 200 over HTTP, integrity tests 3/3 passing. 🤖 Generated with Codebuff Co-Authored-By: Codebuff --- README.md | 16 +++++++++------- run.py | 21 ++++++++++----------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 173e5a7..15a69b3 100644 --- a/README.md +++ b/README.md @@ -8,18 +8,19 @@ Alle Datensätze werden **im Browser** verschlüsselt Der Server sieht ausschließlich Chiffretext – auch bei vollständiger Serverkompromittierung bleiben die Inhalte ohne Passphrase vertraulich. -## Starten (HTTPS, Dev mit self-signed Zertifikat) +## Starten (HTTP; TLS über Reverse Proxy) ```bash python3 -m venv venv ./venv/bin/pip install -r requirements.txt ./venv/bin/python run.py -# → https://127.0.0.1:8443 +# → http://127.0.0.1:5000 ``` -Ein selbstsigniertes Zertifikat wird bei Bedarf automatisch erzeugt -(`certs/`). Zertifikatswarnungen im Browser sind in der Entwicklung -erwartet und zu bestätigen. +Die App lauscht auf dem lokalen HTTP-Port (default `127.0.0.1:5000`, +überschreibbar via `HOST`/`PORT`). Ein vertrauenswürdiger Reverse Proxy +(nginx, caddy, …) beendet HTTPS und reicht intern an die App weiter. +Die App selbst muss von außen nicht erreichbar sein. ## Tests @@ -36,7 +37,7 @@ node .e2e.mjs # optional: End-to-End (siehe unten) | API | `backend/app.py` | Flask REST API, Validierung nur von Form/Größe, Versions-Konfliktprüfung | | Krypto (Client) | `backend/static/crypto.js` | Argon2id-KDF + XChaCha20-Poly1305, uuid+salt als AEAD-AAD gebunden | | UI | `backend/static/ui.js` + `index.html`/`style.css` | Tabelle, Erstellen, Bearbeiten, Löschen; Passphrase bleibt im RAM | -| Server | `run.py` | HTTPS (self-signed Dev-Zertifikat), DB-Init | +| Server | `run.py` | HTTP intern hinter Reverse Proxy, DB-Init | ## Sicherheitsmodell @@ -49,7 +50,8 @@ node .e2e.mjs # optional: End-to-End (siehe unten) (Replay alter Stände) → `409`, Duplikate → `409`. - Klartexte werden clientseitig nie persistiert; beim Sperren/Beenden wird der Schlüssel verworfen (`wipeKey`). -- HTTPS (Dev: self-signed; Prod: eigenes Zertifikat hinterlegen). +- HTTPS wird außen vom vertrauenswürdigen **Reverse Proxy** beendet + (nginx/caddy/…); die App lauscht nur intern auf HTTP. ## Bekannte Grenzen diff --git a/run.py b/run.py index c3298d3..1e66fc0 100644 --- a/run.py +++ b/run.py @@ -1,7 +1,12 @@ -"""Dev/Prod entry point. Runs the Flask app, over TLS when certs exist.""" +"""Entrypoint. Runs the Flask app over plain HTTP on a local port. + +TLS is NOT terminated here: a trusted reverse proxy (nginx/caddy/...) +in front handles HTTPS and forwards to this internal HTTP port. The +proxy must be the only thing reachable from outside; bind this app to +127.0.0.1 (or a private interface) only. +""" import os -import ssl from backend.app import app from backend import storage @@ -10,16 +15,10 @@ from backend import storage def main(): storage.init_db() - cert = os.path.join("certs", "cert.pem") - key = os.path.join("certs", "key.pem") + host = os.environ.get("HOST", "127.0.0.1") + port = int(os.environ.get("PORT", "5000")) - if os.path.exists(cert) and os.path.exists(key): - context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) - context.load_cert_chain(cert, key) - app.run(host="127.0.0.1", port=8443, ssl_context=context) - else: - print("WARNING: no certs/ found, running WITHOUT TLS (dev only!).") - app.run(host="127.0.0.1", port=5000) + app.run(host=host, port=port) if __name__ == "__main__":