harden(fediverse): SSRF guard, remote-URL XSS scheme-guard, scoped Delete, gate-by-default + queue fixes
From a 3-agent hardening review of this session's fediverse code:
- SSRF: all outbound fetches (deliver/fetchActor/webfingerResolve) now go through
safeFetch — http(s)-only, rejects hosts resolving to private/loopback/link-local
ranges on the initial host AND every redirect hop (redirect:manual), + actor-doc
size cap. Blocks inbox-driven SSRF to cloud-metadata/internal services.
- Stored XSS: remote actor url/icon, timeline media + author urls, and remote-note
images/object_uri are now run through an http(s) scheme-guard before storage, so a
malicious actor can't smuggle javascript:/data: into owner-only-rendered href/src.
- Cross-actor Delete: inbound Delete is now scoped to the signing actor (can't wipe
another actor's replies/timeline rows).
- Gate-by-default: Add/Remove/Update added to the signature-enforced activity list.
- Delivery queue: re-entrancy guard (30 rows x 8s can exceed the 60s tick -> no
double-delivery) + backoff off-by-one fix (1-min first retry no longer skipped).
- Scheduler: delete-before-insert on FTS so a re-flipped post has no duplicate row.
- /meldingen: don't mark-seen for a viewer (GET-side mutation the global guard misses).
- Activity ids get a random suffix to avoid same-millisecond collisions.
Co-Authored-By: Claude <noreply@…>