Zum Hauptinhalt springen

6 Posts getaggt mit "security"

Alle Tags anzeigen

Uni-Verein 1.8.2 – Sicherere Mails, maskierte IBANs und Vereinslogo 🛡️✉️

· 4 Minuten Lesezeit
René Herrmann
Senior developer

Veröffentlicht am 30. September 2026

Uni-Verein 1.8.2 setzt die Sicherheitsarbeit aus 1.8.1 fort: Mail-Inhalte werden serverseitig bereinigt, IBANs sind für reguläre User maskiert und der Passwortwechsel verlangt das aktuelle Passwort. Dazu kommen ein eigener Absendername für Mails und das Vereinslogo in der Seitenleiste.

Highlights​

  • 🛡️ Sicherere Mails: Mail-Inhalte werden auf dem Server bereinigt. Es bleibt nur die Formatierung erhalten, die der Mail-Editor erzeugen kann, Skripte, Event-Handler, javascript:-Links, Formulare und iframes werden entfernt
  • 🔒 IBANs für reguläre User maskiert: Nur ADMIN und FINANCIAL_MANAGER sehen vollständige IBANs, die Rolle USER sieht sie bis auf die letzten 6 Zeichen maskiert
  • 🔑 Passwortwechsel nur mit aktuellem Passwort: Falsche Eingaben zählen zur Login-Sperre
  • ✉️ Absendername für Mails: Neues Feld "Absendername" in den Mail-Einstellungen, damit Mails z. B. als Vorstand <vorstand@verein.de> erscheinen
  • 🖼️ Vereinslogo in der Seitenleiste: Die Seitenleiste zeigt das Logo aus den allgemeinen Einstellungen

Neue Funktionen​

  • ✉️ Absendername (UV-47): Die Mail-Einstellungen haben ein neues optionales Feld "Absendername", das Empfänger als Absender sehen. Bisher wurde "Absender Email (From)" gleichzeitig als Name und Adresse verwendet, sodass die Eingabe eines Namens dort den Mailversand scheitern ließ. Das Feld für die Absender-E-Mail akzeptiert jetzt nur noch eine gültige Adresse
  • 🖼️ Vereinslogo in der Seitenleiste (UV-24): Das Logo aus den allgemeinen Einstellungen erscheint oben links in der Seitenleiste, sowohl aufgeklappt als auch eingeklappt. Ist kein Logo hochgeladen, wird weiterhin der erste Buchstabe des Vereinsnamens angezeigt

Sicherheit​

  • 🛡️ Mail-Inhalte bereinigen (UV-17): Der Text von Mails, die über /mail/send verschickt werden, wird serverseitig mit HtmlSanitizer bereinigt. Erhalten bleiben Text, Überschriften, Listen, Links, Bilder, Farben und Ausrichtung. Skripte, Event-Handler, javascript:-Links, Formulare und iframes werden entfernt, data:-URLs sind nur für Inline-Bilder erlaubt (kein SVG). Markdown-Release-Notes in Firmware-Update-Mails rendern außerdem kein rohes HTML mehr
  • 🔒 IBANs maskieren (UV-26): Vollständige IBANs der Mitglieder erhalten nur ADMIN und FINANCIAL_MANAGER. Die Rolle USER bekommt sie bis auf die letzten 6 Zeichen maskiert (Mitgliederliste, Antworten beim Anlegen/Ändern von Mitgliedern und die Warteschlange "Ausstehende Mitglieder"). So lässt sich eine IBAN weiterhin prüfen und durch eine neue ersetzen. Eine maskierte IBAN, die zurück an die API geschickt wird, gilt als unverändert und wird nie gespeichert
  • 🔑 Aktuelles Passwort erforderlich (UV-30): Wer sein eigenes Passwort ändert, muss das aktuelle eingeben, sowohl in den Profileinstellungen als auch, wenn ein Admin in der Benutzerverwaltung seinen eigenen Account bearbeitet. Falsche Versuche zählen zur Login-Sperre. Admins können die Passwörter anderer Benutzer weiterhin ohne das alte Passwort zurücksetzen
  • 🧰 Die transitive Build-Abhängigkeit serialize-javascript wurde auf 7.1.2 angehoben, um GHSA-gfhx-hw2g-v5hg zu beheben (XSS durch nicht maskiertes </script> in serialisierten Funktionskörpern, Schweregrad niedrig)

⚠️ Hinweise zum Update​

  • Immer mit docker-compose-update.yml aktualisieren, wie in der README beschrieben
  • Die Datenbank-Migration (AddMailFromName) läuft beim Start automatisch. Bestehende Mail-Einstellungen funktionieren weiter, der neue Absendername ist zunächst leer
  • Wer als Workaround einen Namen in "Absender Email (From)" eingetragen hatte, sollte ihn in das neue Feld "Absendername" verschieben. Das Feld für die Absender-E-Mail akzeptiert nur noch eine gültige Adresse

Warum diese Updates wichtig sind​

Mails sind ein sensibler Weg: Wer Inhalte aus dem Editor versendet, soll sich darauf verlassen können, dass dabei kein aktiver Code mitreist. Maskierte IBANs sorgen dafür, dass Bankdaten nur diejenigen vollständig sehen, die sie wirklich brauchen, und die Abfrage des aktuellen Passworts schützt Accounts auch dann, wenn jemand kurz an einem entsperrten Rechner sitzt. Absendername und Logo machen den Verein zudem im Postfach und in der Oberfläche besser erkennbar.

Wie geht es weiter?​

Weiteres Feedback aus der Praxis ist wie immer herzlich willkommen, gerne über GitHub Issues. Schaut auch weiterhin gerne hier vorbei!

Uni-Verein 1.8.1 – HTTPS inklusive und umfassende Sicherheitshärtung 🔐🛡️

· 5 Minuten Lesezeit
René Herrmann
Senior developer

Veröffentlicht am 26. September 2026

Uni-Verein 1.8.1 ist ein Sicherheits-Release: Die Installation bekommt HTTPS direkt ab Werk, der Login wird deutlich robuster gegen Angriffe, Uploads werden strenger geprüft und alle Container laufen ohne Root-Rechte.

Highlights​

  • 🔐 HTTPS ab Werk: Eine neue docker-compose-tls.yml samt Caddyfile stellt Caddy vor den Stack und holt automatisch ein Let's-Encrypt-Zertifikat. Das ist jetzt der empfohlene Installationsweg
  • 🛡️ Gehärteter Login: Rate-Limiting pro IP, keine Rückschlüsse mehr darauf, ob ein Benutzername existiert, und Sperren dauern höchstens 15 statt bis zu 24 Stunden
  • 🔑 Kein Standard-Admin-Passwort mehr im Einsatz: Wer sich mit admin123 anmeldet, muss zuerst ein neues Passwort setzen
  • 📦 Sicherere Uploads und Container: Belegdateien werden anhand ihres tatsächlichen Inhalts geprüft, Upload-Größen sind begrenzt, alle Container laufen als Nicht-Root-User

Neue Funktionen​

  • 🔐 HTTPS mit Let's Encrypt (UV-27): docker-compose-tls.yml und Caddyfile richten automatisches HTTPS ein (erfordert einen DNS-Eintrag sowie die Ports 80 und 443). Der Selbst-Update-Ablauf erkennt und unterstützt beide Varianten und aktualisiert auch das Caddyfile. nginx ermittelt die echte Client-IP hinter Caddy, damit Rate-Limiting und Audit-Logs weiter funktionieren
  • 🚦 Rate-Limiter für den Login (UV-31): /auth/login ist pro IP-Adresse begrenzt (Standard 20 Anfragen pro Zeitfenster, konfigurierbar über RateLimiting:AuthLogin:PermitLimit)
  • 🔑 Passwortwechsel erzwungen (UV-25): Beim Login mit dem Standardpasswort admin123 erscheint ein Dialog, der sich erst nach dem Setzen eines neuen Passworts schließen lässt
  • 🔍 Automatische Abhängigkeitsprüfung (UV-42): npm audit --audit-level=high läuft in der CI, dazu kommt Dependabot (ein gebündelter wöchentlicher PR, keine Major-Updates)

Verbesserungen​

  • 🔒 Authentifizierung als Standard (UV-41): Alle Endpunkte erfordern jetzt standardmäßig eine Anmeldung. Bewusst öffentliche Endpunkte (Login, Selbstregistrierung, öffentliche Seitenkonfiguration, /health) sind ausdrücklich freigegeben
  • ⏱️ Fairere Sperren (UV-45): Fehlversuche beim Login verfallen nach 15 Minuten, und die Sperre ist auf maximal 15 Minuten begrenzt (vorher bis zu 24 Stunden)
  • 👤 Admin-Schutz (UV-25): Der Standard-Admin wird nur noch angelegt, wenn noch gar kein Benutzer existiert. Admins können sich nicht mehr selbst löschen oder ihre eigene Rolle ändern
  • 🧾 Uploads nach Inhalt prüfen (UV-32): Belegdateien werden anhand der Magic Bytes (PNG, JPEG, GIF, WebP, PDF) validiert statt anhand des vom Browser gemeldeten Typs. SVG und unbekannte Formate werden abgelehnt. Downloads senden X-Content-Type-Options: nosniff und Content-Disposition: attachment
  • 📏 Upload-Limits (UV-43): Das globale Request-Limit sinkt von 10 GB auf 100 MB, nur die Backup-Wiederherstellung behält 10 GB. Belegdateien und der CSV-Import der Mitglieder sind auf 10 MB pro Datei begrenzt, zu große PDFs werden schon im Browser abgelehnt
  • 🧱 Security-Header (UV-33): Beide nginx-Konfigurationen senden CSP, X-Frame-Options, nosniff, Referrer-Policy und Permissions-Policy
  • 🌐 CORS (UV-28): Erlaubte Origins werden über Cors:AllowedOrigins konfiguriert (in Produktion leer), statt jeden localhost-Origin zuzulassen
  • 🔗 Sichere Bestätigungslinks (UV-35): Die Links der Selbstregistrierung nutzen eine gespeicherte PublicBaseUrl statt des Host-Headers der Anfrage, sodass keine Phishing-Links über gefälschte Hosts möglich sind
  • 📦 Container ohne Root (UV-37): Alle Container laufen als Nicht-Root-User, mit cap_drop: [ALL] und no-new-privileges, wo es möglich ist
  • 🗝️ Geheimnisse (UV-38, UV-39): Das Init-Skript erzeugt zufällige Datenbank-Passwörter und gibt nur noch die Namen der .env-Schlüssel aus, nicht deren Werte. .env.example enthält nur Platzhalter statt echter Schlüssel
  • 🧰 Abhängigkeiten (UV-40): Serilog.Sinks.File ist auf die stabile Version 7.0.0 festgelegt, das ungenutzte BCrypt.Net-Next wurde entfernt, dazu Minor-/Patch-Updates für Backend und Frontend

Fehlerbehebungen​

  • 🖥️ Weißer Bildschirm nach dem Login (UV-18): Nach einem Update konnten veraltete, nachgeladene Programmteile einen leeren Bildschirm verursachen. Die App lädt jetzt automatisch neu, sobald ein neuer Service Worker übernimmt
  • 🔔 Firmware-Hinweis (UV-46): Der Hinweis auf ein Firmware-Update vergleicht jetzt echte Versionsnummern und erscheint nur, wenn tatsächlich eine neuere Version existiert
  • 🕵️ Benutzernamen-Enumeration (UV-44): Die Antwortzeit beim Login verrät nicht mehr, ob ein Benutzername existiert. Rohe Benutzernamen werden nicht mehr ins Log geschrieben
  • 🌍 Gefälschte IP-Header (UV-34): X-Real-IP wird nur noch aus privaten bzw. internen Netzen akzeptiert, damit sich IP-basierte Limits nicht mit einem gefälschten Header umgehen lassen

⚠️ Hinweise zum Update​

  • Immer mit docker-compose-update.yml aktualisieren, wie in der README beschrieben. Proxy und Frontend lauschen im Container jetzt auf Port 8080 (der Host-Port bleibt 80), daher müssen nginx.conf und die Compose-Datei gemeinsam ersetzt werden. Das Update-Skript erledigt das für dich
  • logs/ und receipts/ müssen für das Nicht-Root-Backend (UID 1654) beschreibbar sein. Das Update-Skript kümmert sich über docker-compose-ini.yml darum. Bei einer manuellen Installation: chown -R 1654:1654 logs receipts
  • Wer die Selbstregistrierung nutzt: War sie schon vor dem Update aktiviert, muss ein Admin einmal die allgemeinen Einstellungen öffnen und speichern. Dabei wird die öffentliche URL für die Bestätigungslinks hinterlegt. Bis dahin schlagen neue Anmeldungen fehl
  • Die Datenbank-Migration (AddLastFailedLoginAttemptAndPublicBaseUrl) läuft beim Start automatisch

Warum diese Updates wichtig sind​

Ein Vereinssystem verwaltet Namen, Adressen und Bankdaten und sollte daher so sicher betrieben werden wie möglich. Mit HTTPS ab Werk, einem robusteren Login und strengeren Prüfungen bei Uploads und Netzwerkzugriffen schließt 1.8.1 gleich eine ganze Reihe möglicher Angriffsflächen. Dass die Container jetzt ohne Root-Rechte laufen, begrenzt zudem den Schaden, falls doch einmal etwas schiefgeht.

Wie geht es weiter?​

Weiteres Feedback aus der Praxis ist wie immer herzlich willkommen, gerne über GitHub Issues. Schaut auch weiterhin gerne hier vorbei!

Uni-Verein 1.7.0 – Selbstregistrierung für neue Mitglieder 📝

· 2 Minuten Lesezeit
René Herrmann
Senior developer

Veröffentlicht am 5. September 2026

Uni-Verein 1.7.0 macht die Mitgliederaufnahme einfacher: Interessierte können sich ab sofort über ein öffentliches Formular selbst anmelden, ganz ohne eigenen Account. Dazu bringt dieses Release wichtige Sicherheitsupdates für einige Abhängigkeiten.

Neue Funktionen​

  • 📝 Selbstregistrierung: Ein neues, öffentlich erreichbares Formular erlaubt es Interessierten, sich selbst als Mitglied anzumelden (ganz ohne eigenen Account)
  • 🔒 Serverseitig geschützte Felder: Daten, die nur der Nutzer setzen darf oder die automatisch vergeben werden (Aufgabe im Verein, Datumsfelder, SEPA-Zustimmung), sind im öffentlichen Formular ausgeblendet und werden serverseitig erzwungen
  • 🚫 Duplikatsprüfung: E-Mail-Adresse und IBAN werden wie beim Anlegen durch einen User auf Duplikate geprüft und im Fall eines Treffers abgelehnt
  • 🔗 "Selbstregistrierung"-Schalter: Neue Einstellung in den allgemeinen Vereinseinstellungen, die das öffentliche Formular ein- oder ausschaltet, inklusive Button zum direkten Teilen des Links

Verbesserungen​

  • 🧩 Die Logik zum Anlegen von Mitgliedern wurde in einem gemeinsamen MemberService.CreateMemberAsync gebündelt, statt dupliziert für Nutzer-Erstellung und Selbstregistrierung vorzuliegen
  • 🧩 Wiederkehrende EF-Core-Abfragen wurden hinter einem neuen ReferenceDataService vereinheitlicht
  • 🌐 frontend/nginx.conf liefert die SPA jetzt mit einem try_files-Fallback auf index.html aus

Sicherheit​

  • 🔐 Die Abhängigkeiten fast-uri und @tiptap/* wurden aktualisiert. Damit werden vier Sicherheitslücken mit hohem Schweregrad (SSRF/Host-Confusion) sowie eine mit mittlerem Schweregrad (Prototype-Pollution zu XSS) geschlossen

Warum diese Updates wichtig sind​

Die Selbstregistrierung nimmt Vorständen viel manuelle Arbeit ab: Statt jedes neue Mitglied einzeln anzulegen, teilt man einfach den Link zum Formular, Interessierte tragen sich selbst ein. Serverseitig geschützte Felder und die Duplikatsprüfung sorgen dabei dafür, dass die Datenqualität dieselbe bleibt wie bei einer Anmeldung durcheinen Nutzer. Die Sicherheitsupdates schließen zudem bekannte Schwachstellen in verwendeten Abhängigkeiten.

Wie geht es weiter?​

Wie immer freue ich mich über Feedback und Wünsche, gerne über GitHub Issues. Schaut auch weiterhin gerne hier vorbei!

Uni-Verein 1.3.1 – Schnellere Ladezeiten und wichtige Sicherheitslücke geschlossen ⚡

· 2 Minuten Lesezeit
René Herrmann
Senior developer

Veröffentlicht am 26. Juli 2026

Nur einen Tag nach 1.3.0 folgt bereits Uni-Verein 1.3.1 mit einem klaren Fokus: spürbar bessere Performance im Frontend sowie ein wichtiger Sicherheitsfix.

Verbesserungen​

  • 🚀 Lazy Loading der Frontend-Routen: Die Seiten-Komponenten (Mail, Mitglieder, SEPA, Beiträge, Nutzer-/Link-/Beitragsplan-/E-Mail-/Gläubiger-/Allgemein-/Mitgliedskategorie-Konfiguration, Audit, Backup) werden jetzt erst bei Bedarf nachgeladen, statt beim ersten Aufruf komplett mitzuladen, das Haupt-Bundle schrumpft dadurch von ca. 1,4 MB auf ca. 577 kB
  • 🖼️ Die Icon-Auswahl ("Symbol auswählen") zeigt jetzt maximal 250 Icons gleichzeitig an und bittet bei mehr Treffern um eine genauere Suche, statt alle ca. 8.600 Icons auf einmal zu rendern. Bisher fror die Oberfläche dadurch bei jedem Öffnen des Dialogs für über eine Sekunde ein
  • ⏳ Die Icon-Auswahl wartet jetzt, bis alle Icons vollständig geladen bzw. gecacht sind, und zeigt in der Zwischenzeit einen Ladeindikator statt eines leeren oder unvollständigen Dialogs
  • 🧹 IconPickerDialog.tsx importiert muiIcons für loadIconNames nicht mehr redundant dynamisch, da es an anderer Stelle bereits statisch importiert wird. Das behebt eine Vite-Build-Warnung und erlaubt korrektes Chunking des Moduls
  • ⚙️ Der enforce-source-branch-CI-Job aus 1.3.0 läuft jetzt auch für Pull Requests nach development, sodass das Zurückführen von main nach development nicht mehr an einem Status-Check scheitert, der bisher nur für PRs nach main ausgewertet wurde

Fehlerbehebungen​

  • 🐛 Vites Chunk-Größen-Warnung für das @mui/icons-material-Barrel (das die Icon-Auswahl bei Bedarf nachlädt) wird jetzt über chunkSizeWarningLimit unterdrückt, da dieser Chunk erwartungsgemäß groß ist und nie Teil des initialen Seitenladens ist

Sicherheit​

  • 🔐 Das npm-Override für brace-expansion wurde auf ^5.0.8 angehoben, um eine hochkritische ReDoS-Schwachstelle (exponentielle Laufzeit bei aufeinanderfolgenden, nicht-expandierenden {}-Gruppen) zu schließen. Die vorherige Override-Version war gegenüber der Lockfile in die Jahre gekommen, wodurch zusätzlich eine verwundbare Kopie verschachtelt unter filelist verblieben war

Warum diese Updates wichtig sind​

Gerade die Icon-Auswahl wurde bisher spürbar als träge wahrgenommen, durch das Lazy Loading und die Begrenzung der gerenderten Icons reagiert die Oberfläche jetzt deutlich flüssiger. Das kleinere Haupt-Bundle sorgt zudem dafür, dass Uni-Verein gerade auf mobilen Verbindungen schneller lädt. Der ReDoS-Fix schließt zusätzlich eine hochkritische Sicherheitslücke in einer transitiven Abhängigkeit.

Wie geht es weiter?​

Die Performance-Arbeit zahlt sich direkt auf die Nutzungserfahrung ein, als Nächstes stehen größere Funktionserweiterungen an. Schaut gerne wieder vorbei!

Uni-Verein 1.3.0 – Namenssuche im Rundmail-Versand und stabilere Infrastruktur 🔍

· 2 Minuten Lesezeit
René Herrmann
Senior developer

Veröffentlicht am 25. Juli 2026

Uni-Verein 1.3.0 bringt eine praktische neue Suchfunktion für den Rundmail-Versand sowie eine ganze Reihe an Verbesserungen unter der Haube, die die Zuverlässigkeit von Deployments und CI-Läufen erhöhen.

Neue Funktionen​

  • 🔍 Namenssuche im Empfänger-Tab der Rundmail: Empfänger lassen sich jetzt zusätzlich zum bestehenden Filter nach Mitgliedskategorie auch nach Vor- oder Nachnamen filtern (unscharfe Suche mittels Jaro-Winkler-Ähnlichkeit)

Verbesserungen​

  • ❤️ /health-Endpoint: Ein neuer, unauthentifizierter GET /health-Endpoint sowie Docker-HEALTHCHECKs für Backend und Frontend
  • 🩺 backend, frontend und proxy verfügen jetzt über richtige Health-Checks (zuvor nur die Datenbank), und jeder Dienst wartet in allen docker-compose*.yml-Dateien darauf, dass seine Abhängigkeiten tatsächlich bereit sind (service_healthy) statt nur gestartet
  • 🚦 Die CI bricht jetzt sofort mit angehängten Container-Logs ab, wenn der Stack nicht rechtzeitig gesund wird, statt stillschweigend fortzufahren und erst bei den Playwright-Tests ohne Diagnoseinformationen zu scheitern
  • ⏱️ Der Retry-timeout des Datenbank-Health-Checks wurde erhöht, um gelegentlich langsame Erstinitialisierungen auf CI-Runnern zu tolerieren
  • 📝 .env.example listet jetzt auch BACKUP_PATH, passend zu allen Werten, die docker-compose-ini.yml erzeugt
  • 🔒 Die CI erzwingt jetzt, dass Pull Requests nach main nur noch von development ausgehen dürfen (neuer enforce-source-branch-Job)

Fehlerbehebungen​

  • 🐛 Das Kategorie-Dropdown im Rundmail-Empfänger-Filter zeigte für individuelle (nicht standardmäßige) Mitgliedskategorien den rohen Übersetzungsschlüssel statt des Kategorienamens an
  • 🐛 Der proxy-Container konnte unbegrenzt "unhealthy" bleiben, weil sein Health-Check localhost per IPv6 auflöste, während nginx.conf nur auf IPv4 lauscht
  • 🐛 Der Docker-Image-Build des Backends schlug gelegentlich wegen kurzzeitiger Fehler des Paket-Mirrors bei apt-get install fehl

Sicherheit​

  • 🔐 sharp wurde per npm-overrides auf ^0.35.3 fixiert, um statt der verwundbaren transitiven Version eine gefixte Version zu beziehen

Warum diese Updates wichtig sind​

Die Namenssuche im Rundmail-Versand spart bei größeren Vereinen viel Zeit, wenn schnell einzelne Empfänger gefunden werden müssen. Mindestens genauso wichtig sind die Verbesserungen an den Health-Checks: Sie sorgen dafür, dass Deployments zuverlässiger anlaufen und Probleme in der CI sofort mit aussagekräftigen Logs sichtbar werden, statt erst spät und ohne Kontext aufzufallen.

Wie geht es weiter?​

Die Arbeit an Performance und Infrastruktur geht weiter, im nächsten Release liegt der Fokus bereits auf spürbar schnelleren Ladezeiten.

Uni-Verein 1.0.1 – Sicherheitsupdate für das Frontend 🔒

· Eine Minute Lesezeit
René Herrmann
Senior developer

Veröffentlicht am 12. Juli 2026

Nur wenige Tage nach dem großen Release der ersten Version folgt bereits das erste Update: Uni-Verein 1.0.1 ist da. Dieses Mal handelt es sich um ein kleines, aber wichtiges Sicherheitsupdate.

Was wurde geändert?​

Im Docker-Image des Frontends wurde eine Sicherheitslücke (CVE-2026-33630) identifiziert. Mit diesem Update wurde das zugrunde liegende Dockerfile angepasst, um die Schwachstelle zu schließen.

  • 🔒 Sicherheitsfix: Aktualisierung des Frontend-Dockerfiles zur Behebung von CVE-2026-33630

Warum ist das wichtig?​

Gerade weil Uni-Verein von Vereinen mit sensiblen Mitgliederdaten eingesetzt wird, hat die Sicherheit der Software für mich höchste Priorität. Sicherheitsupdates wie dieses werden daher so schnell wie möglich bereitgestellt, sobald bekannte Schwachstellen identifiziert werden.