-
Notifications
You must be signed in to change notification settings - Fork 0
Security
Diese Seite beschreibt das Sicherheitsmodell der OpenSchichtplaner5-API.
Das System kennt drei Rollen, die hierarchisch aufgebaut sind:
| Rolle | Level | Berechtigungen |
|---|---|---|
| Leser | 1 | Lesezugriff auf Dienstplan, Mitarbeiter, Schichten, Abwesenheiten, Statistiken |
| Planer | 2 | Alles wie Leser + Schreiben: Dienstplan, Abwesenheiten, Notizen, Schichtwünsche, Besetzungsanforderungen |
| Admin | 3 | Alles wie Planer + Benutzerverwaltung, Stammdaten (Schichten, Gruppen, Mitarbeiter), Backup/Restore, Jahresabschluss |
Endpunkte prüfen die Mindestrolle über einen Dependency-Mechanismus in FastAPI:
-
require_auth→ Leser oder höher -
require_planer→ Planer oder höher -
require_admin→ nur Admin
Anfragen mit zu niedriger Rolle erhalten HTTP 403 Forbidden.
POST /api/auth/login
Body: { "username": "...", "password": "..." }
→ 200 OK
{ "token": "<hex-token>", "user": {...}, "expires_at": <unix-timestamp> }
→ Alle folgenden Anfragen mit Header:
X-Auth-Token: <hex-token>
-
Login —
POST /api/auth/loginmit Benutzername und Passwort - Token erhalten — Der Server legt eine Session an und gibt ein zufälliges Hex-Token zurück
-
Token verwenden — Alle geschützten Endpunkte erwarten den Header
X-Auth-Token -
Logout —
POST /api/auth/logoutinvalidiert das Token serverseitig
Tokens werden in einem In-Memory-Dictionary (_sessions) gespeichert. Ein Neustart des Servers invalidiert alle Sessions.
- Standard-Laufzeit: 8 Stunden (konfigurierbar via Umgebungsvariable
TOKEN_EXPIRE_HOURS) - Abgelaufene Tokens werden bei jeder Anfrage geprüft und gelöscht
- Nach Ablauf: HTTP 401, erneuter Login erforderlich
# Token-Laufzeit anpassen (z.B. 4 Stunden):
TOKEN_EXPIRE_HOURS=4 uvicorn sp5api.main:app ...Der Login-Endpunkt ist durch zwei Mechanismen geschützt:
-
5 Anfragen pro Minute pro IP-Adresse auf
POST /api/auth/login - Bei Überschreitung: HTTP 429 Too Many Requests
- Nach 5 fehlgeschlagenen Loginversuchen wird das Konto gesperrt (
_LOCKOUT_MAX = 5) - Gesperrte Konten können nur durch einen Admin entsperrt werden (
POST /api/auth/unlock/{user_id}) - Fehlversuche werden pro Benutzer im Speicher gezählt
Cross-Origin Resource Sharing (CORS) ist über Umgebungsvariablen konfigurierbar:
# Erlaubte Origins (kommagetrennt):
ALLOWED_ORIGINS="https://mein-schichtplaner.example.com,https://admin.example.com"Standardwerte (Entwicklungsmodus):
-
http://localhost:5173(Vite Dev Server) -
http://localhost:8000(lokale API)
CORS-Einstellungen in der API:
allow_credentials: trueallow_methods: ["*"]allow_headers: ["*"]
⚠️ Produktion:ALLOWED_ORIGINSimmer explizit auf die eigene Domain beschränken!
Passwörter werden mit bcrypt gehasht (via passlib). Klartext-Passwörter werden nie gespeichert.
- Interne Fehlermeldungen werden im Production-Modus nicht an den Client weitergegeben
- Alle
500-Fehler werden durch_sanitize_500()bereinigt - Logs auf dem Server enthalten den vollen Stack-Trace für Debugging
Seit v1.0.0-rc3 unterstützt die Anwendung TOTP-basierte 2FA (Time-based One-Time Password):
- Authenticator-Apps: Google Authenticator, Authy, etc.
- QR-Code-basiertes Setup
- 10 einmalige Backup-Codes
- Admins können 2FA für andere Benutzer zurücksetzen
→ Details: Zwei-Faktor-Authentifizierung
API-Endpunkte sind gegen Brute-Force und Missbrauch gesichert:
| Endpunkt | Limit |
|---|---|
POST /api/auth/login |
5 Anfragen/Minute |
| Alle anderen API-Endpunkte | 100 Anfragen/Minute |
Bei Überschreitung: HTTP 429 Too Many Requests mit Retry-After-Header.
- JWT-basierte Token mit konfigurierbarer Laufzeit
- Frontend erkennt ablaufende Tokens und zeigt Notification-Toast
- Automatischer Logout vor Token-Ablauf
- HTTPS erzwingen (z.B. via nginx Reverse Proxy mit Let's Encrypt)
-
ALLOWED_ORIGINSauf eigene Domain einschränken -
TOKEN_EXPIRE_HOURSje nach Sicherheitsanforderung reduzieren (z.B.4) - API nicht direkt exponieren — immer hinter einem Reverse Proxy betreiben
- Regelmäßige Backups über
/api/backupeinrichten
⚠️ Nur für Entwicklung! Dev-Mode darf niemals in Produktionsumgebungen aktiviert werden.
Der Entwicklungsmodus ermöglicht vereinfachtes Testen ohne vollständige Auth-Flows:
# Entwicklungsmodus aktivieren:
SP5_DEV_MODE=true uvicorn sp5api.main:app --reloadIm Dev-Mode:
- Ein fester Dev-Token wird akzeptiert (konfigurierbar via
SP5_DEV_TOKEN) - Brute-Force-Schutz ist deaktiviert
- Ausführlichere Fehlermeldungen werden zurückgegeben
In Production (SP5_DEV_MODE nicht gesetzt oder false):
- Der Dev-Token wird strikt abgelehnt (HTTP 401)
- Alle Sicherheitsmechanismen sind aktiv
CSV-Import-Endpunkte sind ab v0.3.21 durch zusätzliche Validierung geschützt:
| Schutz | Details |
|---|---|
| Dateigröße | Maximale Upload-Größe: 10 MB pro Datei |
| MIME-Type | Nur text/csv und application/csv akzeptiert |
| Dateiname-Sanitierung | Dateinamen werden beim Photo-Upload bereinigt (keine Path-Traversal-Angriffe) |
Uploads mit ungültigem MIME-Type oder zu großer Datei werden mit HTTP 400 Bad Request abgewiesen.
Ab v1.0.0 werden Content-Security-Policy (CSP) Header und Subresource Integrity (SRI) eingesetzt:
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'
Subresource Integrity (SRI):
- Alle statischen Assets (JS, CSS) erhalten Integrity-Hashes
- Browser verweigern das Laden manipulierter Dateien
- Schutz gegen CDN-Kompromittierung und Man-in-the-Middle
Die API sendet folgende Security-Header:
| Header | Wert (Standard) | Zweck |
|---|---|---|
X-Content-Type-Options |
nosniff |
Verhindert MIME-Sniffing |
X-Frame-Options |
DENY |
Verhindert Clickjacking |
X-XSS-Protection |
1; mode=block |
XSS-Filter (ältere Browser) |
Referrer-Policy |
strict-origin-when-cross-origin |
Kontrolliert Referrer-Info |
Permissions-Policy |
camera=(), microphone=(), geolocation=() |
Deaktiviert Browser-APIs |
Home — Startseite
- Installation — Installation & Setup
- Erste-Schritte — Quick Start Guide
- Onboarding-Wizard — 🧭 Ersteinrichtung
- Onboarding-Checkliste — ✅ Setup-Fortschritt
- Dashboard — Charts, Widgets & Performance
- Dienstplan — Dienstplan, Einsatzplan
- Kalender-Ansicht — 🗓️ Monatskalender
- Drag-and-Drop — 🖱️ Drag & Drop im Kalender
- Recurring-Shifts — 🔁 Wiederkehrende Schichten
- Schichtplan-Kommentare — 📝 Tagesnotizen
- Dienstplan-Vorlagen — 📋 Templates
- Undo-Redo — ↩️ Rückgängig/Wiederherstellen
- Jahresuebersicht — Jahresübersicht (Tagesraster)
- Personaltabelle — 📋 Kennzahlen-Auswertung
- Personalbedarf — 📌 Min/Max & Besetzungsampel
- Schichtwunsch-Kalender — 💬 Persönlicher Schichtkalender
- Schichtwuensche — Schichtwünsche & Sperrtage
- Verfuegbarkeit — 📅 Mitarbeiter-Verfügbarkeit
- Tauschboerse — 🔄 Schicht-Tauschbörse
- Urlaubsverwaltung — Urlaub & Abwesenheiten
- Jahresabschluss — 🎯 Überträge & Resturlaub-Verfall
- Ueberstunden — Überstunden-Dashboard & Tracking
- Arbeitszeit-Regelwerk — ⚖️ Arbeitszeitregeln
- Team-Kalender — 🗓️ Team-Kalender
- Team-Uebersicht — 👥 Team-Übersicht
- Berichte — Alle Berichte (20+)
- Scheduled-Reports — 📤 Automatische Berichte
-
Konflikt-Report —
⚠️ Konflikterkennung - Abwesenheits-Statistiken — 📊 Abwesenheitsauswertung
- Mitarbeiter-Timeline — 📅 Zeitachse
- Fairness-Score — 📐 Fairness-Score
- Mitarbeiter-Vergleich — ⚖️ Mitarbeiter-Vergleich
- Analytics-Charts — 📈 Analytics & Charts
- Jahresrueckblick — 🗓️ Jahresrückblick
- Import-Export — CSV/XLSX Import & Export
- Bulk-Import — 📦 Massenimport (Drag&Drop)
- Export-Scheduler — 📅 Automatischer Berichtsversand
- iCal-Export — 📅 iCal & Kalender-Abo
- Drucken — Drucken & PDF-Export
- Druckvorschau — Interaktive Print-Vorschau
- Mitarbeiter — Personal & Gruppen
- Foto-Upload — 📸 Mitarbeiter-Profilfotos
- Stammdaten — Schichten, Modelle, Zuschläge
- Feiertage — 🎉 Feiertage & Österreich-Import
- Kompetenz-Matrix — 📊 Qualifikations-Matrix
- API-Versionierung — 🔀 Versionierte API-Routes
- Webhook-System — 🔗 Webhooks
- Echtzeit-Updates — 📡 SSE Live-Updates
- Notification-Settings — 🔔 E-Mail-Einstellungen
- Multi-Tenant — 🏢 Mandantenverwaltung
- Benutzerverwaltung — Benutzer & Rechte
- Zwei-Faktor-Authentifizierung — 🔐 2FA (TOTP)
- Administration — Backup & Wartung
- Datenbank-Backup — 💾 Backup & Restore
- Rate-Limit-Dashboard — 🚦 Rate-Limit Monitoring
- Protokoll — Aktivitätsprotokoll
- Keyboard-Shortcuts — ⌨️ Tastaturkürzel
- Keyboard-Navigation — ⌨️ Vollständige Tastatur-Bedienbarkeit
- Security — 🔒 Sicherheit, CSP, CORS
- Health-Check — 🏥 Systemmetriken
- Konfiguration — ⚙️ ENV-Variablen
- PostgreSQL-Support — 🐘 PostgreSQL-Datenbank
- Auto-Migration — 🔄 Auto-Schema-Migration
- Datenbankformat — Technisches: DBF & SQLite
- ORM-Spiegel — 🪞 ORM-Spiegel (Admin)
- Error-Monitoring — 🔍 Logging & Monitoring
- Self-Service-Portal — 👤 Mitarbeiter Self-Service
- Dark-Mode — 🌙 Dark Mode (System-Preference)
- Command-Palette — 🔍 Schnellsuche (Ctrl+K)
- In-App-Changelog — 🔔 Changelog
- PWA — 📲 Progressive Web App
- Sprachumschalter — 🌍 DE/EN i18n
- Library (lib) — Datenbankformat & CLI
- REST-API — Endpunkt-Referenz