Audit 12.09.2026: Rechte, Gäste, Kalender, Push, SSO — 16 von 18 Befunden #2
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "audit-befunde"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Setzt die Gegenprüfung des externen Audits um (
claude/sote-audit-gegenpruefung.mdim Projekt). Basis istzuweisung-meldet(#1), weilpatch()dort die neue Signatur bekam — nach dem Merge von #1 kann die Basis aufmainwechseln.Zehn Commits, einer je Befundgruppe, jeder mit Tests, die ohne den Fix rot waren (jeweils gegen den alten Stand geprüft).
pnpm checkgrün: 237 / 77 / 471.Sofort (liefen in Produktion falsch)
sweepFileskannte nurstorage_keyund löschte täglich jede Bildvariante älter als eine Stunde. Jetzt zählt jeder Schlüssel einer Zeile;readFileOffällt bei fehlender Variante aufs Original zurück./kalender/:token.icsstand hinter dem statischen Rückfall — Kalenderabos haben nie funktioniert. Block vor den Rückfall, HTTP-Test.push.send— Push für Zuweisungen und Kommentare kam nie an. Handler inpush.ts; Migration 0039 verwirft den Rückstau, damit nach dem Deploy keine Flut alter Meldungen kommt.[object Object]. EinsessionCookie(token, days)für alle fünf Stellen;Securebeihttps://-Basisadresse (F12).Rechte
effectiveListLevel()(Maximum über Rolle und Gruppen, Eigentümer = admin) wird einmal nachmemberWorkspace()berechnet;listAccessNeeded(path, method)entscheidet fail-closed: persönliche und verwaltende Wege laufen vorbei, Lesen brauchtviewer, Schreibeneditor. Gast mit Konto → 403no_list_level, viewer beim Schreiben → 403read_only./api/meliefertlistLevelje Arbeitsbereich.GET /api/sharesgibt Tokens nur noch an Schreibende;mayManagein der Antwort, der Bildschirm versteckt Anlegen/Widerrufen für Mitleser.knownnur noch Schlagwörter des freigegebenen Projekts.deliver()prüft Mitgliedschaft;removePersonnimmt Zuweisungen und Gruppenmitgliedschaften im Arbeitsbereich mit.Gastpfade
readPatch,as neverweg.createFromLinebekommtmay: { assign: false, pinProject: true }und die Browser-Zone;@namekommt alsunknownAssigneeszurück,#projektwird nicht mehr nachträglich korrigiert. (Das Zuweisungszeichen ist@, nicht+wie im Audit —+ist das Schlagwort.)PUT …/files/:id/webmit derselben Grenze wie der Anhang, 413.SSO und Anmeldung
readWhoamiverlangtemail_verified === true.sote_sso-Keks bindet den Vorgang an den Browser (Hash insso_flows.browser_hash, Migration 0040);safeNextPathlehnt//…ab.Throttle: 10 Fehlversuche je Konto, 100 je Herkunft, 15 Minuten, 429 mitRetry-After, vor scrypt.SOTE_TRUST_PROXY=1fürX-Forwarded-For(compose + .env.example).Betrieb und Wächter
DELETE /api/pushnur eigenes Gerät; Endpunkt musshttps:sein und darf nicht nach innen zeigen (keine Dienst-Allowlist, UnifiedPush bleibt möglich); max. 20 Geräte; 10 s Timeout.check-routes-reachablekennt jetzt!path.startsWith()-Zweige und Regex-Wege — gegen den alten Stand fällt er mit/kalender/x … verschluckt.fileURLToPathin zwei Scripts.Nicht umgesetzt (bewusst)
/api/menennt die Stufe, aber die Bildschirme verstecken Bedienelemente noch nicht (nur Freigaben tut es). Ein Gast mit Konto sieht jetzt Fehler statt fremder Daten — richtig, aber noch nicht schön.Beim Deploy
viewer.email_verified: trueliefern (Authelia/Keycloak/Authentik tun das für bestätigte Adressen).SOTE_TRUST_PROXY=1setzen.🤖 Generated with Claude Code
https://claude.ai/code/session_01Kdn7zzrYhhwUwH8PzMteCA
Audit 12.09.2026, F08. `deliver()` legt seit dem ersten Tag Auftraege der Art `push.send`; kein Modul hat `handle('push.send', …)` gerufen. Fuenfmal „kein Bearbeiter", dann liegen gelassen. Von aussen unsichtbar, weil die Aufgabenerinnerungen `pushTo` direkt rufen und darum ankamen -- und in der Notiz zur Zuweisung stand bereits: „ob Push wirklich rausgeht, ist ungetestet. Der Job liegt." Jetzt: Bearbeiter in `push.ts`, Nutzlast geprueft statt geglaubt, ein Konto ohne Geraete ist erledigt und kein Fehler. Migration 0039 markiert den Rueckstau als verworfen, damit nach dem Deploy keine Flut alter Meldungen auf die Geraete geht. Zwei Tests. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Kdn7zzrYhhwUwH8PzMteCAAudit 12.09.2026, F09 und F12. Fuenfmal dieselbe Zeile in routes.ts, und die SSO-Fassung interpolierte `${session}` statt `${session.token}`: der Keks hiess `[object Object]`, die Anmeldung beim Anbieter gelang, und in SOTE war man trotzdem niemand. Der Typpruefer sieht das nicht -- in einem Template-Literal ist jedes Objekt ein String. `sessionCookie(token, days)` nimmt einen String und kann den Fehler nicht mehr machen. Dazu `Secure`, wenn `SOTE_BASE_URL` mit https:// beginnt -- dieselbe Angabe, aus der die Mail-Links gebaut werden. Das Abmelden loescht mit denselben Attributen, sonst loescht es nichts. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Kdn7zzrYhhwUwH8PzMteCAAudit 12.09.2026, F05, F17, F04. F05: der Gast-PATCH reichte `planned`/`due` roh an `patch()` weiter, mit `as never` am Typpruefer vorbei -- und `patch` kennt `plannedAt`/ `dueAt`. Ein Termin allein hiess „nichts zu aendern", mit Titel ging die Anfrage durch und der Termin blieb. Jetzt liest `readPatch` aus routes.ts beide Pfade, und der Cast ist weg. F17: die Schnellerfassung loeste `@name` auch fuer Gaeste auf, trug zu und meldete der Person -- die direkte Bearbeitung verbot genau das. `#projekt` wurde erst NACH dem Anlegen mit einem zweiten UPDATE zurueckgesetzt. Und die Zone des Browsers fehlte: „morgen 9 Uhr" eines Gasts in Berlin war 9 Uhr UTC. `createFromLine` bekommt jetzt Faehigkeiten (`may: { assign, pinProject }`) und die Zone; der Name kommt als `unknownAssignees` zurueck statt still zu verschwinden. F04: `PUT …/files/:id/web` sammelte den ganzen Koerper, bevor es irgendetwas pruefte. Jetzt dieselbe Grenze wie beim Anhang und bei der Mitgliederroute, 413 beim Ueberschreiten. Drei Tests ueber HTTP, alle ohne die Fixes rot. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Kdn7zzrYhhwUwH8PzMteCAAudit 12.09.2026, F14 und F16. F14: `DELETE /api/push` loeschte ueber den Endpunkt allein -- wer den eines anderen kannte, meldete dessen Geraet ab. Jetzt `(user_id, endpoint)`. Ein Endpunkt muss `https:` sein und darf nicht nach innen zeigen (localhost, private Bereiche, .local); KEINE Liste zugelassener Dienste, damit Firefox-Autopush und UnifiedPush weiter gehen. Hoechstens 20 Geraete je Konto; der Versand hat zehn Sekunden. F16: `check-routes-reachable` kannte nur `/^\/api…/`-Muster und `path === '…'`-Literale -- den Kalender hinter `!path.startsWith('/api/')` konnte er nicht sehen und meldete „alle erreichbar". Jetzt ist der startsWith-Zweig ein Muster, jeder Regex ein Weg (geprueft an seinem woertlichen Anfang), und gegen den alten Stand faellt der Waechter mit „/kalender/x … verschluckt von alles ausser /api/…". `check-env-passed` und `check-styles` nehmen `fileURLToPath` statt `.pathname`. `SOTE_TRUST_PROXY` steht in compose und .env.example -- der env-Waechter hat es verlangt, zu Recht. `pnpm check` gruen: 237 / 77 / 471. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Kdn7zzrYhhwUwH8PzMteCA