What changed
- CSRF protection for split-origin deployments — The CORS middleware now rejects POST/PUT/DELETE requests whose Origin header does not match the configured --frontend-url. Previously, when SameSite=None was in effect, a malicious page could trigger cross-origin form submissions that carried the session cookie, allowing unauthenticated secret creation on behalf of a logged-in user. (#3781)
- Secret-request fingerprint check no longer fails open — Links to /r/:key without a fingerprint segment now refuse to render the form instead of silently skipping the public-key integrity check. This prevents a downgrade where the responder encrypts to an unverified key. (#3779)
- Webhook expiry tracker bounded — The in-memory expiry map is now capped at 100k entries and uses a min-heap instead of a full map scan every 5 seconds, preventing unbounded memory growth and lock contention when webhooks are enabled. (#3780)