nebula-mesh's web UI lacks CSRF tokens on /ui/* mutating endpoints
Date: 2026-06
Affected: go/github.com/juev/nebula-mesh
Attack vector: xss
Category: vulnerability-disclosure
Severity: High
CVE: CVE-2026-47725
CWE: CWE-269
CWE-352

Every `/ui/*` POST / PUT / PATCH / DELETE route processes the request as soon as the session cookie validates. `SameSite=Lax` on the session cookie prevents most cross-site form submits but does not protect: - top-level form-submit navigations from third-party pages (some browsers still send Lax cookies on top-level POSTs) - same-registrable-domain attackers (sibling-subdomain XSS, subdomain takeover) - the `GET /ui/logout` route, which a third-party `<img src=".../ui/logout">` can force-trigger The admin UI signs CA certificates, mints API keys, rotates / retires / deletes CAs, disables operators, and changes server settings. CSRF here is a real privilege escalation, not just annoyance. ## Affected All released versions up to v0.3.2. ## Suggested fix Double-submit cookie: a 32-byte `crypto/rand` token in a non-HttpOnly `_csrf` cookie, echoed in either `X-CSRF-Token` (htmx) or a `_csrf` form field (HTML forms). Compared in constant time. Rotated on every privilege transition (`Login`, OIDC `StartAuthenticatedSession`, `CompleteTwoFactor`, `Logout`) so pre-auth fixation cannot survive promotion. Rejections audit-logged as `ui.csrf.rejected` with reason; response body stays opaque. `/ui/logout` becomes POST so it is no longer reachable via `<img>` tags. Fix coordinates with the Secure-cookie advisory disclosed concurrently — the `_csrf` cookie inherits the same `Secure`-attribute derivation. ## Reproducer With an authenticated operator session in browser tab A, open the


Mitigations:

Architectural layers (MAESTRO):