Wie wir deine Daten schützen
Technische und organisatorische Maßnahmen nach Art. 32 DSGVO, samt der Punkte, die noch offen sind.
Die technischen und organisatorischen Maßnahmen nach Art. 32 DSGVO, gegliedert nach den üblichen Prüfkategorien. Was noch nicht umgesetzt ist, steht als offen dabei. Wir nennen Lücken lieber, als sie zu umschreiben.
Was nicht bei uns liegt, kann bei uns nicht abfließen
Noten, Stundenpläne und Prüfungsdaten liegen ausschließlich auf deinem Gerät. Aus den mobilen Apps erreicht dein Hochschul-Login unsere Server zu keinem Zeitpunkt.
Vertraulichkeit
- Wer an die Daten herankommt.
Physischer Zugang
Wir betreiben keine eigenen Rechenzentren. Die physische Sicherheit liegt bei den Hostern.
Supabase: verwaltetes PostgreSQL und Anmeldung, Standort EU.
Google Cloud Run: Anwendungsserver, Region europe-west1 (Belgien).
netcup: ein Server in Deutschland für die Workspace-Daten und ihre Datenbank. Hochgeladene Dateien liegen derzeit auf der Platte dieses Servers; ein Objektspeicher in der EU ist vorbereitet.
Anmeldung
Wer sich anmelden kann, und wie systematisches Passwortraten verhindert wird.
Anmeldung über Supabase Auth. Die Server prüfen jedes Token gegen den öffentlichen Schlüsselsatz (JWKS, RS256 bzw. ES256); die Schlüssel werden rotiert.
Sitzungstoken gelten eine Stunde. Refresh-Token werden bei jeder Verlängerung der Sitzung ausgetauscht.
Ab dem fünften Fehlversuch wächst die Wartezeit exponentiell, höchstens bis 15 Minuten. Der Zähler liegt in der Datenbank und wirkt über alle Serverinstanzen hinweg. Dazu kommt eine grobe Ratenbegrenzung je IP-Adresse.
Fehlversuche mit unbekannten Kennungen zählen mit. Sonst ließe sich an der Sperre ablesen, welche Benutzernamen es gibt.
Zugriff auf Daten
- Was eine angemeldete Person sehen kann.
Row-Level Security in PostgreSQL: Die Datenbank prüft selbst, wem eine Zeile gehört, anhand einer je Transaktion gesetzten Kontokennung. Ein Fehler im Anwendungscode hebt die Trennung nicht auf.
Die beiden Betreiber greifen nur über persönliche Konten zu, nie über geteilte Anmeldungen. Schlüssel und Zugangsdaten liegen in einem Secret Manager, nicht im Quellcode.
Kein Tracking. Absturzberichte sind standardmäßig aus und werden vor dem Versand um Tokens, iTAN-Codes, Anmeldezeilen des Mailzugangs und absolute Dateipfade bereinigt.
Trennung
Wie die Daten verschiedener Personen und Hochschulen getrennt bleiben.
Die Trennung nach Hochschule und nach Person setzt dieselbe Row-Level-Security-Schicht durch, nicht ein Filter in der Anwendung.
Änderungen an gemeinsam bearbeiteten Dokumenten werden nur angehängt, nie überschrieben. Eine Datenbankbedingung verhindert, dass ein Konto unter fremder Kennung schreibt.
Das Sicherheitsprotokoll nimmt keine Schreibvorgänge von Clients an und ist für Clients nicht lesbar. Einsehbar ist es nur für den Betrieb.
Integrität
Dass Daten unterwegs und im Nachhinein unverändert bleiben.
Übertragung und Speicherung
Verschlüsselt auf dem Weg, bei den Hostern und auf deinem Gerät.
TLS auf allen Verbindungen zwischen App, Servern, Datenbank und den Systemen deiner Hochschule.
Verschlüsselung im Ruhezustand durch die Hoster.
Zugangsdaten auf deinem Gerät verschlüsselt: mobil in iOS-Keychain bzw. Android-Keystore, im Browser mit AES-GCM unter einem Schlüssel, der mit Argon2id aus deinem Passwort abgeleitet oder als gerätegebundener, nicht exportierbarer WebCrypto-Schlüssel gehalten wird.
Hochschul-Login: aus den mobilen Apps nie an unsere Server; im Browser je Anfrage mitgesendet und für Moodle höchstens 24 Stunden im Arbeitsspeicher. Nie in einer Datenbank, nie in einer Protokolldatei.
Schutz der Web-App
- Browserseitige Schutzmechanismen.
CORS schließt in der Produktion im Zweifel: Eine nicht ausdrücklich zugelassene Herkunft wird abgewiesen, nicht durchgelassen.
Die Sicherheits-Header X-Content-Type-Options und X-Frame-Options sind aktiv.
Die Content-Security-Policy läuft derzeit nur im Report-Only-Modus: Sie meldet Verstöße, blockiert aber noch nicht.
Nachvollziehbarkeit
Sicherheitsrelevante Vorgänge landen in einem Protokoll, an das nur angehängt werden kann, jeweils mit IP-Adresse, Browserkennung, Aktion und Zeitpunkt. Clients können Einträge weder erzeugen noch ändern. IP-Adresse und Browserkennung werden nach 30 Tagen entfernt, die Einträge nach 12 Monaten gelöscht.
Verfügbarkeit
- Was passiert, wenn etwas kaputtgeht.
Nächtliche Sicherung
Jede Nacht eine vollständige Sicherung der Datenbank (pg_dump) auf dem Server, 14 Tage aufbewahrt.
Wiederherstellung geprüft
Ein vollständiger Test der Wiederherstellung wurde durchgeführt und bestanden. Eine Sicherung, die nie zurückgespielt wurde, ist für uns keine Sicherung.
Kein Handgriff ohne zweites Paar Augen
Wie Änderungen geprüft werden, bevor sie live gehen.
Zwei Personen betreiben UNI-fied, beide mit persönlichen Konten.
Der gesamte Quellcode steht unter Versionskontrolle. Jede Änderung sieht vor der Übernahme die jeweils andere Person durch.
Bei jeder Änderung laufen automatisierte Prüfungen (Continuous Integration), darunter Tests der Zugriffsregeln.
Ein automatischer Scanner verhindert, dass Schlüssel oder Passwörter in den Quellcode gelangen.
Datenbankmigrationen werden in der CI von Grund auf neu aufgebaut und auf Wiederholbarkeit geprüft. Der Stand der Datenbank ist reproduzierbar und nicht das Ergebnis von Handgriffen.
Offene Punkte
In Umsetzung. Sobald ein Punkt erledigt ist, wandert er nach oben.
Sicherungskopie außerhalb des Servers
Sicherung und gesicherter Bestand liegen derzeit auf demselben Server. Vorgesehen ist eine verschlüsselte Ablage in einem getrennten Objektspeicher in der EU.
Wiederherstellung auf einen beliebigen Zeitpunkt
Derzeit lässt sich nur der Stand der letzten Nacht wiederherstellen. Vorgesehen ist eine fortlaufende Sicherung des Transaktionsprotokolls (Point-in-Time-Recovery).
Automatische Alarmierung
Störungen fallen bislang bei der Durchsicht auf, nicht durch eine Meldung. Vorgesehen sind Schwellwerte für Fehlerrate, Antwortzeit und den Ausfall der Sicherung.
Content-Security-Policy durchsetzen
Läuft im Report-Only-Modus. Nach Auswertung der Meldungen wird sie blockierend geschaltet.