feat(oidc): Profilbild vom Identitätsanbieter übernehmen
Schickt der Anbieter ein `picture`, wird es bei der Anmeldung geholt,
mittig auf 256x256 zugeschnitten und oben rechts angezeigt. Fehlt es
oder scheitert das Holen, bleibt es beim Buchstabenkreis - die
Anmeldung selbst hängt nicht davon ab.
Die Bildadresse kommt aus einem Token, also von außen. Erlaubt ist
deshalb ausschließlich der Ursprung aus OIDC_ISSUER, Weiterleitungen
eingeschlossen; dazu 4 MB und 5 Sekunden als Deckel. Ohne das wäre es
eine Aufforderung an den Server, für einen Fremden beliebige Adressen
im internen Netz anzufragen.
Neu: Migration 000019 (avatar_key/-source/-updated_at), Paket
internal/avatar, Route GET /api/v1/users/{id}/avatar. Der GC durchsucht
"avatars/" mit und kennt die Schlüssel - sonst räumte er die Bilder
nach einem Tag weg.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3019e84681
commit
9f44215698
18 files changed
+814
-26
No files matched your search
+35
@@ -1274,6 +1274,41 @@ anbieten. Anlass: Bei einem Bild stand nirgends, wie groß es in **Pixeln** ist.
|
||||
|
||||
---
|
||||
|
||||
## Profilbild vom Identitätsanbieter (24.08.2026)
|
||||
|
||||
Gemessen an der laufenden Instanz auf `127.0.0.1:8090`:
|
||||
|
||||
| Fall | Erwartet | Gemessen |
|
||||
|---|---|---|
|
||||
| Bild hinterlegt, `/me` | `avatar_ver` > 0 | 1787571663 |
|
||||
| `GET /users/<id>/avatar?v=…` | `200`, `image/png`, 256×256 | ✅, `private, max-age=604800, immutable` |
|
||||
| ohne Anmeldung | `401` | ✅ |
|
||||
| Konto ohne Bild | `404` | ✅ |
|
||||
| erfundene Konto-ID | `404`, nicht `403` | ✅ |
|
||||
| Blob fehlt, Zeile steht | Buchstabenkreis, kein Loch | ✅ (Screenshot) |
|
||||
| GC-Lauf | Bild bleibt, 0 Waisen | ✅ (122 gescannt) |
|
||||
| verwaiste Datei unter `avatars/` | wird gefunden, Schonfrist greift | ✅ (123 gescannt, 1 jung) |
|
||||
|
||||
Geprüft mit Go-Tests, nicht am laufenden Anbieter:
|
||||
|
||||
- Zuschnitt: 800×200, 200×800, 512×512 und 16×16 ergeben alle 256×256; bei
|
||||
einem breiten Bild bleibt die Mitte stehen (linke Kante rot, rechte blau).
|
||||
- JPEG wird angenommen, Unsinn (`""`, `<svg/>`, Text) abgelehnt.
|
||||
- **SSRF:** `169.254.169.254`, `localhost:8080`, `postgres:5432`,
|
||||
`id.example.com.angreifer.net`, `id.example.com:9200`, `file://`, `gopher://`
|
||||
werden alle abgewiesen; eine Weiterleitung auf einen fremden Rechner wird
|
||||
nicht befolgt.
|
||||
- Ein Anbieter, der erst `401` sagt, bekommt genau einen zweiten Versuch mit
|
||||
Token – nicht mehr.
|
||||
- Eine 8-MB-Antwort wird bei 4 MB abgeschnitten.
|
||||
|
||||
**Noch offen (braucht deinen echten PocketID):**
|
||||
- [ ] Meldet PocketID `picture` im ID-Token oder erst über UserInfo?
|
||||
- [ ] Kommt das Bild ohne Token heraus, oder greift der zweite Versuch?
|
||||
- [ ] Bild in PocketID austauschen → steht nach dem nächsten Anmelden hier
|
||||
- [ ] Bild in PocketID entfernen → das alte bleibt hier stehen (so gebaut:
|
||||
gelöscht wird nur beim Austausch, nicht auf Verdacht)
|
||||
|
||||
## Automatisiert geprüft (22.08.2026)
|
||||
|
||||
Diese Punkte hat Claude per API/`curl` gegen Wegwerf-Konten durchgespielt; sie
|
||||
|
||||
Reference in new issue
Block a user