Skip to content

← Public intelligence

Go package

github.com/forgekeep/nebula-mesh

Open actionable advisories and recorded vendor fixes. This public package view has no inventory attached and cannot establish whether your deployment is affected. A vendor fix never resolves your finding; verify your installed version and the source guidance.

Open advisories

8 actionable advisories, newest first. Withdrawn advisories and news are excluded. Coverage is partial.

  1. High, CVSS 7.7GoPublished

    Nebula-mesh allows non-admin operators to disable webhook SSRF protection via allow_private

    GHSA-7rx3-5wx3-5v76

    Affected
    • Go github.com/forgekeep/nebula-mesh >= 0.6.0, <= 0.7.1
    Fixed in
    0.7.2· Vendor fix available
    Issue
    Non-admin operators (role user) can set allowprivate: true on their own managed webhook subscription (POST/PATCH /api/v1/webhook-subscriptions). No admin check exists on this field. At delivery time, allowprivate switches the dispatcher to an unguarded HTTP client, bypassing the private/loopback/link-local SSRF guard — letting a low-privilege operator make the server request internal addresses. Details internal/api/webhooks.go:67 (handleCreateWebhookSubscription) and :110 (handleUpdateWebhookSubscription) persist operator-supplied AllowPrivate with no role check — only ownership is enforced (canAccessWebhookSub), and that's not even called on create. internal/webhook/webhook.go:294-296: d.unguarded skips the loopback/private/link-local rejection config.ValidateWebhookURL otherwise enforces. Every other tenant-impacting toggle (network create internal/api/networks.go:21, settings PATCH internal/api/settings.go:36, CA management) gates on isActiveAdmin. allowprivate is the…

    Recommended action: Upgrade to 0.7.2 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  2. High, CVSS 8.1GoPublished

    nebula-mesh: Certificate revocation is never enforced at the mesh

    CVE-2026-61699 · GHSA-cm26-5974-52h8

    Affected
    • Go github.com/forgekeep/nebula-mesh < 0.7.1
    Fixed in
    0.7.1· Vendor fix available
    Issue
    nebula-mesh revokes a host by adding its certificate fingerprint to a per-CA blocklist and shipping that list to every other agent on each poll. Slack's Nebula enforces certificate revocation ONLY through the pki.blocklist list in config.yml (no CRL/OCSP). The project's own code states this: internal/pki/durations.go:15 — "Revocation via the blocklist remains the immediate security control." The server side is fully implemented (computes per-CA blocklist via GetBlocklistForCA, returns it in the agent-updates response, sets hasupdates=true when non-empty). The agent side was never implemented: 1. The agent decodes the blocklist JSON field into UpdatesResponse.Blocklist (internal/agent/poller.go:33) and then DISCARDS it — poll() applies CertificatePEM, CACertPEM, ConfigYAML, but never references updates.Blocklist (internal/agent/poller.go:300-339). 2. The config generator has NO field to emit pki.blocklist — pkiSection is only ca/cert/key (internal/configgen/marshal.go:42-46)…

    Recommended action: Upgrade to 0.7.1 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  3. Medium, CVSS 5.4GoPublished

    nebula-mesh: Web UI host creation ignores configured enrollment token TTL and mints 24-hour bearer enrollment tokens

    CVE-2026-55513 · GHSA-g4x6-jcvr-9m3g

    Affected
    • Go github.com/forgekeep/nebula-mesh >= 0.3.0, < 0.5.0
    Fixed in
    0.5.0· Vendor fix available
    Issue
    The nebula-mgmt Web UI host-creation path ignores both the server-wide enrollmenttokenttl security setting and per-network networkconfig.enrollmenttokenttl overrides. API host creation and token-regeneration paths use the configured TTL resolver, but POST /ui/hosts hardcodes now.Add(24 time.Hour) for newly minted agent enrollment tokens. In deployments that intentionally reduce enrollment-token lifetime, any authenticated operator who can create a host through the Web UI can still mint a bearer enrollment token valid for about 24 hours. Details Enrollment tokens are bearer credentials for the public POST /api/v1/enroll endpoint: possession of a valid token allows enrolling the pending host and receiving a signed Nebula certificate/config for that host. The server configuration documents a security knob for their default lifetime and per-network overrides: - internal/config/server.go:82 defines EnrollmentTokenTTL as the default lifetime for freshly minted enrollment tokens. -…

    Recommended action: Upgrade to 0.5.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  4. Medium, CVSS 5.3GoPublished

    nebula-mesh: Unauthenticated OIDC login endpoint allocates unbounded in-memory state entries without rate limiting

    CVE-2026-55512 · GHSA-m3cx-mwpg-32jg

    Affected
    • Go github.com/forgekeep/nebula-mesh >= 0.2.0, < 0.5.0
    Fixed in
    0.5.0· Vendor fix available
    Issue
    When OIDC is enabled, GET /ui/oidc/login is reachable without authentication and is registered outside the Web UI rate-limited auth routes. Every request creates a fresh random OIDC state value and stores it in an in-memory map for 10m. Expired states are swept lazily, but there is no rate limit or maximum live-state cap on the allocation path. An unauthenticated remote client can therefore grow OIDC.states for the full state TTL, bounded by request throughput rather than by configured auth rate limits. Details The OIDC login route is registered directly by WithOIDC: - internal/web/web.go:153 registers w.router.Get("/ui/oidc/login", o.HandleLogin). - internal/web/web.go:154 rate-limits only GET /ui/oidc/callback with w.rateLimitMiddleware("auth"). The normal /ui/ route group applies rate limiting to login/register form submissions, but this direct registration happens outside that group: - internal/web/web.go:287 through internal/web/web.go:292 show the rate-limited local…

    Recommended action: Upgrade to 0.5.0 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  5. High, CVSS 7.1GoPublished

    nebula-mesh: Operator session tokens stored in plaintext in the database

    CVE-2026-53603 · GHSA-q4vm-pq3q-8wgq

    Affected
    • Go github.com/forgekeep/nebula-mesh <= 0.3.7
    Fixed in
    0.3.8· Vendor fix available
    Issue
    Impact Operator session tokens are stored in plaintext in the operatorsessions table (the token column is the PRIMARY KEY). The session token is a 32-byte random hex value sent directly in a cookie and valid for 24 hours. - internal/models/operator.go:61 — OperatorSession.Token holds the plaintext token. - internal/store/sqliteoperators.go:590 — CreateOperatorSession inserts sess.Token verbatim. - internal/store/sqliteoperators.go:603,642,681,698 — lookups/updates/deletes use WHERE token = ? against the plaintext value. Anyone who can read the database (backup, snapshot, file copy, or SQL-level disclosure) obtains every active session token and can hijack operator sessions directly, with no further authentication. This is functionally identical to the plaintext enrollment-token issue fixed in GHSA-ghmh-jhmj-wcmf. API keys (OperatorAPIKey.KeyHash) and enrollment tokens (EnrollmentToken.TokenHash) already store only a SHA256 hash; session tokens were missed. Patches Store only a SHA256…

    Recommended action: Upgrade to 0.3.8 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  6. High, CVSS 8.7GoPublished

    nebula-mesh: CA private key not zeroized on web mobile-bundle error paths

    CVE-2026-53604 · GHSA-2p2f-px33-4vv5

    Affected
    • Go github.com/forgekeep/nebula-mesh <= 0.3.7
    Fixed in
    0.3.8· Vendor fix available
    Issue
    Impact The web handler renderMobileBundle (internal/web/handlers.go:1325) passes the real pki.CAResolver directly into mobilebundle.Build. Inside Build (internal/mobilebundle/builder.go:54), resolver.LoadByID decrypts the CA's ed25519 private key into a pki.CAManager, but Build never calls CAManager.Wipe() on any return path (success or any of the error paths at lines 56, 62, 68, 80, 86, 92, 98, 102, 109, 118, 150). As a result, when a mobile-bundle request goes through the web UI and Build returns — especially on error (missing network, invalid prefix, DB error, signing failure) — the plaintext CA private key remains on the Go heap, unwiped, until garbage collection. An attacker able to read process memory (core dump, swap, memory-scraping) can recover the CA signing key, which would allow minting arbitrary host certificates for the mesh. The API handler (internal/api/mobilebundle.go:74) already does this correctly: it loads the CAManager, defer caMgr.Wipe(), and wraps it in…

    Recommended action: Upgrade to 0.3.8 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  7. Medium, CVSS 4.9GoPublished

    nebula-mesh: Host revocation is not durable - blocked/offboarded hosts can regain a valid certificate

    CVE-2026-53602 · GHSA-339v-266x-79xr

    Affected
    • Go github.com/forgekeep/nebula-mesh < 0.3.7
    Fixed in
    0.3.7· Vendor fix available
    Issue
    Two related authorization gaps let a host that should no longer be trusted obtain a fresh, valid Nebula certificate, because nebula-mgmt does not re-evaluate revocation/authorization state at certificate issuance time — only at poll time. 1. Blocklist not enforced at sign / re-enroll time internal/api/enroll.go:128 calls caMgr.Sign(...) without consulting the blocklist. The blocklist is only checked in the poll path (internal/api/updates.go:57, fingerprintInBlocklist). The blocklist is keyed by certificate fingerprint (internal/store/sqlite.go), so a re-enrollment produces a new fingerprint that is not in the blocklist. mintEnrollmentTokenForHost (internal/api/hosts.go:491) authorizes the caller via canAccessHost but does not check the host status. There is no guard preventing a blocked host from transitioning back to enrolled (internal/store/sqlite.go, enrollHostInTx updates status unconditionally). Impact: A host that an operator has blocked can be silently un-blocked by…

    Recommended action: Upgrade to 0.3.7 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →
  8. UnratedGoPublished

    nebula-mesh: Decrypted CA private key persists in heap after signing

    CVE-2026-48025 · GHSA-8h84-fhqq-q58v

    Affected
    • Go github.com/forgekeep/nebula-mesh < 0.3.7
    Fixed in
    0.3.7· Vendor fix available
    Issue
    internal/pki/resolver.go:36-64 constructs a CAManager with the plaintext ed25519.PrivateKey after unwrapping via the master key; internal/pki/ca.go:13-16 stores it. Callers at internal/api/enroll.go:116, internal/api/updates.go:297, and internal/api/mobilebundle.go:40 use the manager for one Sign() and drop the reference on function return — but the underlying slice contents are not wiped before release. The keystore package's contract (internal/keystore/keystore.go doc: "Callers MUST zeroise the returned plaintext DEK as soon as it is no longer needed") is not met by the CAManager consumer. Decrypted CA private keys persist in process heap until Go's GC scavenges the underlying slice — minutes to hours under load, indefinitely on idle servers. Affected All released versions up to v0.3.6. Threat model Memory-read access: core dump, ptrace, kernel swap to disk, container/VM snapshot, OOM-debug bundle, side-channel via shared cache lines. Not a remote-network vulnerability, but defeats…

    Recommended action: Upgrade to 0.3.7 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.

    Sources:github.comSource checked Evidence →