security: H-1 settings-Whitelist + H-5 UUID-Guard + H-6 DNS-Pinning + H-7 Heartbeat-Timing

H-1: company.settings als typisiertes Sub-Schema
- schemas/company.py: CompanySettingsUpdate mit extra=forbid
- Nur bekannte Keys (carryover_expires_month/day) erlaubt
- Unbekannte Keys → HTTP 422

H-5: SQL-Injection defensiv absichern
- dependencies.py: UUID-Round-Trip str(_uuid.UUID(...)) + Sicherheitskommentar

H-6: CalDAV DNS-Rebinding-Schutz
- caldav_service.py: PinnedIPTransport — IP einmal auflösen, beim Request fixieren
- _validate_caldav_url gibt aufgelöste IP zurück
- Alle HTTP-Methoden nutzen PinnedIPTransport

H-7: Heartbeat-Timestamp nach Route-Logik
- kiosk_security.py: last_heartbeat_at-Update aus Dependency entfernt
- kiosk_service.py: Update erst in process_heartbeat() nach erfolgreicher Auth

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-26 11:35:18 +02:00
parent 654258f13e
commit 4dc69137dd
7 changed files with 152 additions and 24 deletions
+7 -4
View File
@@ -177,9 +177,10 @@ async def verify_kiosk_request(
3. Gerät laden + Status prüfen
4. IP-Whitelist (falls konfiguriert)
5. Ed25519-Signatur verifizieren
6. last_heartbeat_at aktualisieren
Gibt das verifizierte KioskDevice zurück.
Hinweis: last_heartbeat_at wird NICHT hier gesetzt (H-7) nur der Heartbeat-
Endpoint setzt es, nach erfolgreicher Route-Logik.
"""
# 1. Timestamp-Check
try:
@@ -259,8 +260,10 @@ async def verify_kiosk_request(
except InvalidSignature:
raise HTTPException(status_code=401, detail="Ungültige Signatur.")
# 6. Heartbeat-Zeitstempel aktualisieren
device.last_heartbeat_at = datetime.now(timezone.utc)
await db.flush()
# Hinweis: last_heartbeat_at wird NICHT hier gesetzt, sondern erst im
# Heartbeat-Route-Handler (process_heartbeat). So wird der Timestamp nur
# committed wenn die gesamte Route-Logik erfolgreich war, nicht bereits
# bei jedem signierten Request. Andere Endpunkte (auth/pin etc.) aktualisieren
# last_heartbeat_at bewusst nicht nur echter Heartbeat zählt als Liveness-Signal.
return device