CVE-2026-61699

highpriority · track · 0EPSS 0.004 · 39 %ileUS
grimoire priorityP2 · Scheduled
Exploitable?
—
no known exploitation
Likely / severe?
0.45% (39th) EPSS
CVSS 8.1 · high
Is it mine?
1 products
Check your exposure
Who says so?
1 sources
osv

EPSS · scored 2026-10-27

nebula-mesh is a self-hosted control plane for Slack Nebula mesh VPN. Prior to version 0.7.1, revocation is the only in-band mechanism that isolates a compromised/offboarded host from a Nebula mesh. Because the blocklist never reaches any peer's config.yml, a Blocked host retains full overlay reachability to every peer under its CA (and internal services on the mesh) for up to 30d (agent) / 365d (mobile). An attacker who exfiltrates host.key+host.crt can run stock slackhq/nebula directly, ignore the agent's 403/410 poll responses, and stay connected after the operator revokes the host. Operator-visible state (UI shows blocked, audit log records it) is misleading. This issue has been patched in version 0.7.1.

01

cvss

Technical severity, 0–10. One row per scoring source.

8.1
010

base score 0–10 · higher = more severe · hover a vector to decode

v3.18.1highCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:Nsecondary · security-advisories@github.comexploitability 2.8 · impact 5.2
v3.18.1highCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:Nsecondary · OSV
v3.17.4highCVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N/E:Usecondary · CVSS-BT (t0sche)
02

ssvc

A stakeholder decision — act, attend, or track — from exploitation and impact.

Exploitation: poc · Automatable: no · Technical Impact: totalcoordinatorcisa_ssvcUS
03

weaknesses

The CWE weakness classes this flaw belongs to.

04

affected products (1)

Products and version ranges known to be affected.

05

advisories (2)

Vendor and ecosystem advisories describing this.

  • GHSA-cm26-5974-52h8nebula-mesh: Certificate revocation is never enforced at the mesh2026-07-14ghsa · osvUS

    ### Summary 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 `has_updates=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`) and `GeneratorInput` carries no blocklist (`internal/configgen/generator.go:23-52`). So even the server-rendered `config.yml` shipped via `ConfigYAML` cannot carry it. Result: a blocked/offboarded/compromised host's certificate is never rejected by its peers. Its handshakes keep succeeding for the full remaining cert lifetime — up to 30 days for agent hosts (`DefaultAgentCertDuration`) and 365 days for mobile hosts (`DefaultMobileCertDuration`). Blocking a host in the UI/API has no effect on the data plane. ### Affected components - Agent drops the blocklist: `internal/agent/poller.go:33` (decode target), `internal/agent/poller.go:300-339` (poll() applies cert/CA/config, never the blocklist). - Generator cannot emit it: `internal/configgen/marshal.go:42-46` (`pkiSection{CA,Cert,Key}`), `internal/configgen/generator.go:23-52` (`GeneratorInput` has no blocklist), `internal/api/enroll.go:255-330` (`renderHostConfig`, source of shipped ConfigYAML). - Server correctly produces/ships it (proves intent): `internal/store/sqlite.go:2034` (`GetBlocklistForCA`), `internal/api/updates.go:182-191` (`resp.Blocklist`), `internal/api/updates.go:277` (`has_updates` set on blocklist change). - Dead helper: `internal/pki/blocklist.go` (`Blocklist` type) is never used in non-test code — no server-side enforcement either. ### Reachability (hop by hop) 1. Operator clicks Block on host B (or B is compromised/offboarded). B's fingerprint enters the per-CA `blocklist` table. 2. Every other host A under the same CA polls `GET /api/v1/agent/updates`; server returns `blocklist: [<B-fp>, ...]` and `has_updates=true`. 3. A's agent decodes `Blocklist` then discards it; `poll()` has no blocklist branch. 4. Even on a config re-render, `configgen.Generate` emits `pki: {ca,cert,key}` with no `blocklist` key (proven by PoC). 5. A's Nebula daemon has an empty blocklist and accepts handshakes from B's still-valid cert. B keeps full mesh access. ### Impact Revocation is the only in-band mechanism that isolates a compromised/offboarded host from a Nebula mesh. Because the blocklist never reaches any peer's config.yml, a Blocked host retains full overlay reachability to every peer under its CA (and internal services on the mesh) for up to 30d (agent) / 365d (mobile). An attacker who exfiltrates `host.key`+`host.crt` can run stock slackhq/nebula directly, ignore the agent's 403/410 poll responses, and stay connected after the operator revokes the host. Operator-visible state (UI shows blocked, audit log records it) is misleading. ### Proof of Concept (benign) `internal/configgen/blocklist_poc_test.go` renders a fully-populated host config and asserts the output contains the `pki` section but NO `blocklist` key: ``` $ go test ./internal/configgen/ -run TestPoC_NMESH001 -v === RUN TestPoC_NMESH001_GeneratedConfigOmitsBlocklist CONFIRMED: generated config has a pki section but no blocklist key pki: ca: /etc/nebula/ca.crt cert: /etc/nebula/host.crt key: /etc/nebula/host.key ... --- PASS ``` The agent half is verifiable by inspection: `poll()` has branches for CertificatePEM/CACertPEM/ConfigYAML/RekeyRequired but none for Blocklist. ### Distinctness NOT a duplicate of GHSA-339v / CVE-2026-53602 (revocation durability = a blocked host getting a NEW cert re-issued; its fix `CheckIssuanceAllowed` is present and orthogonal). This bug is that the EXISTING cert is never rejected at peers — the distribution/enforcement layer. Checked against all 17 known advisories; none cover blocklist application in the agent or `pki.blocklist` generation. ### Remediation 1. Add `Blocklist []safeString` to `pkiSection` (yaml `blocklist,omitempty`) and `GeneratorInput`; consider also `pki.disconnect_invalid: true`. 2. Have the agent apply `updates.Blocklist` by re-rendering/rewriting `config.yml` + SIGHUP (same path as `ConfigYAML`). Simplest: fold the blocklist into the server-rendered `ConfigYAML` so it flows through the existing write path. 3. Add a regression test asserting a non-empty server blocklist yields a `pki.blocklist` entry in the agent's written config.yml.

  • GO-2026-5986nebula-mesh: Certificate revocation is never enforced at the mesh in github.com/forgekeep/nebula-mesh2026-07-17vendor · osvUS

    nebula-mesh: Certificate revocation is never enforced at the mesh in github.com/forgekeep/nebula-mesh

06

also known as (2)

Other names and identifiers for this entity.

07

sources

Which sources assert this record, and when.

published 2026-09-04modified 2026-09-08
08

references (3) nvd

External citations — patches, advisories, analysis.

scry

Attackers weaponise vulnerabilities like this against internet-exposed services. See what is exposed on your perimeter with a free passive scan.

Free scan