GHSA-273Q-QGH5-WRJ6

Vulnerability from github – Published: 2026-06-08 23:09 – Updated: 2026-06-08 23:09
VLAI
Summary
nebula-mesh's web UI lacks CSRF tokens on /ui/* mutating endpoints
Details

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 following minimal HTML in any other tab:

<form action="https://nebula.example.com/ui/cas/{ca-id}/delete" method="POST">
  <button>Click for free puppy</button>
</form>

Click. The CA is deleted — the server processes the POST because the session cookie is automatically attached and there is no other check. The same trick works for force-rotate, retire, mint API keys, disable operators, etc.

Alternative force-logout: <img src="https://nebula.example.com/ui/logout"> placed on an attacker's page logs out any visiting authenticated operator. No interaction required.

Notes

  • Multipart and JSON endpoints don't exist in the current UI surface. Future additions must rely on the header path because r.PostFormValue only reads application/x-www-form-urlencoded bodies. The middleware's package comment documents this.
  • The patch assumes nebula-mgmt is the sole authority on its registrable domain. A compromised sibling subdomain can still set parent-domain cookies and forge matches; SameSite=Lax does not prevent that. Documented in the patch.
Show details on source website

{
  "affected": [
    {
      "database_specific": {
        "last_known_affected_version_range": "\u003c= 0.3.2"
      },
      "package": {
        "ecosystem": "Go",
        "name": "github.com/juev/nebula-mesh"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            },
            {
              "fixed": "0.3.3"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "aliases": [
    "CVE-2026-47725"
  ],
  "database_specific": {
    "cwe_ids": [
      "CWE-269",
      "CWE-352"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-08T23:09:21Z",
    "nvd_published_at": null,
    "severity": "HIGH"
  },
  "details": "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:\n\n- top-level form-submit navigations from third-party pages (some browsers still send Lax cookies on top-level POSTs)\n- same-registrable-domain attackers (sibling-subdomain XSS, subdomain takeover)\n- the `GET /ui/logout` route, which a third-party `\u003cimg src=\".../ui/logout\"\u003e` can force-trigger\n\nThe 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.\n\n## Affected\nAll released versions up to v0.3.2.\n\n## Suggested fix\nDouble-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.\n\n`/ui/logout` becomes POST so it is no longer reachable via `\u003cimg\u003e` tags.\n\nFix coordinates with the Secure-cookie advisory disclosed concurrently \u2014 the `_csrf` cookie inherits the same `Secure`-attribute derivation.\n\n## Reproducer\nWith an authenticated operator session in browser tab A, open the following minimal HTML in any other tab:\n\n```html\n\u003cform action=\"https://nebula.example.com/ui/cas/{ca-id}/delete\" method=\"POST\"\u003e\n  \u003cbutton\u003eClick for free puppy\u003c/button\u003e\n\u003c/form\u003e\n```\n\nClick. The CA is deleted \u2014 the server processes the POST because the session cookie is automatically attached and there is no other check. The same trick works for force-rotate, retire, mint API keys, disable operators, etc.\n\nAlternative force-logout: `\u003cimg src=\"https://nebula.example.com/ui/logout\"\u003e` placed on an attacker\u0027s page logs out any visiting authenticated operator. No interaction required.\n\n## Notes\n- Multipart and JSON endpoints don\u0027t exist in the current UI surface. Future additions must rely on the header path because `r.PostFormValue` only reads `application/x-www-form-urlencoded` bodies. The middleware\u0027s package comment documents this.\n- The patch assumes nebula-mgmt is the sole authority on its registrable domain. A compromised sibling subdomain can still set parent-domain cookies and forge matches; SameSite=Lax does not prevent that. Documented in the patch.",
  "id": "GHSA-273q-qgh5-wrj6",
  "modified": "2026-06-08T23:09:21Z",
  "published": "2026-06-08T23:09:21Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/juev/nebula-mesh/security/advisories/GHSA-273q-qgh5-wrj6"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/juev/nebula-mesh"
    }
  ],
  "schema_version": "1.4.0",
  "severity": [
    {
      "score": "CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:L/VI:H/VA:N/SC:N/SI:N/SA:N",
      "type": "CVSS_V4"
    }
  ],
  "summary": "nebula-mesh\u0027s web UI lacks CSRF tokens on /ui/* mutating endpoints"
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…