GHSA-v2jf-442r-6mjh: nebula-mesh Signed-poll Nonce LRU Is In-memory Vulnerability

LOW
CWE-294
Published
Advisory Summary

GHSA-v2jf-442r-6mjh is a LOW signed-poll nonce lru is in-memory vulnerability (CWE-294: Authentication Bypass by Capture-replay) affecting nebula-mesh libraries in the Go ecosystem. The issue involves signed-poll nonce lru is in-memory and bounded; replay survives restart + eviction. Remediation is available by upgrading affected packages to version 0.3.4.

GHSA-v2jf-442r-6mjh at a Glance

CVE Identifier N/A
GHSA Identifier GHSA-v2jf-442r-6mjh
Severity LOW
CVSS v3.1 Base Score N/A
CWE Classification CWE-294: Authentication Bypass by Capture-replay
Affected Product nebula-mesh
Package Ecosystem Go
Published Date
Last Updated

How to Fix GHSA-v2jf-442r-6mjh

To remediate this vulnerability, upgrade all affected nebula-mesh dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

github.com/juev/nebula-mesh fixed: 0.3.4
Upgrade github.com/juev/nebula-mesh to 0.3.4
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for github.com/juev/nebula-mesh

How to Check if You Are Affected

To determine whether your application is affected by GHSA-v2jf-442r-6mjh, inspect your project dependencies for nebula-mesh:

inspect dependencies for github.com/juev/nebula-mesh

Analyze the terminal output to locate any version of nebula-mesh in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 0.3.4), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-294: Authentication Bypass by Capture-replay, where a capture-replay flaw exists when the design of the product makes it possible for a malicious user to sniff network traffic and bypass authentication by replaying it to the server in question to the same effect as the original message (or with minor changes). In nebula-mesh, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

`internal/api/pop/nonce.go:25,40,86` + `internal/api/server.go:38` — the signed-poll nonce cache is an in-process LRU sized at 65,536 entries. `internal/api/updates.go:31` sets `pollClockSkew = 5 * time.Minute` as the replay window. ## Affected All released versions through v0.3.0 that have shipped the ADR 0004 signed-poll path. (If this is gated behind a feature flag, on a side branch, or not yet on a release tag, please flag — this advisory may not apply to the released artifact yet.) ## Threat model A captured signed-poll request can be replayed: 1. **After any process restart** — the in-memory LRU is wiped, so the original nonce becomes "unseen" again. Replay succeeds if the original timestamp is still within the 5-minute skew. 2. **After forced eviction** — an attacker with control of any single host can flood >65,536 nonces under their own host_id, driving the global LRU to evict the victim's recorded nonce. Replay then succeeds. Impact is bounded: a replayed poll fetches the `/api/v1/agent/updates` body. That body can include a freshly-minted enrollment token if a rekey is pending (`updates.go:249-260`) — at which point the attacker holds a single-use token they can redeem under their own keypair. ## Suggested fix Two options, either acceptable: 1. Persist nonces in SQLite keyed by `(host_id, nonce)` with `ON CONFLICT DO NOTHING`, retained for the timestamp-skew window. Adds one transactional INSERT per poll; bounded by the skew window (~5 min worth of rows server-wide). 2. Per-host cap on the LRU instead of a global 65k cap, so one host cannot evict another's records. Combined with shorter skew (≤30s) to bound the post-restart replay window. Option 1 is more robust; option 2 is lower-implementation-effort.

GHSA-v2jf-442r-6mjh Affected nebula-mesh Versions

1 component(s)
Fixed Versions:
0.3.4
Product / Package Ecosystem Affected Versions Fixed Version
github.com/juev/nebula-mesh
Go
< 0.3.4
0.3.4

References

Frequently Asked Questions

What is GHSA-v2jf-442r-6mjh?
GHSA-v2jf-442r-6mjh is a security vulnerability in nebula-mesh involving Signed-poll nonce LRU is in-memory and bounded; replay survives restart + eviction under CWE-294: Authentication Bypass by Capture-replay.
Which nebula-mesh versions are affected?
Affected versions include releases prior to 0.3.4 across affected packages: github.com/juev/nebula-mesh.
What version fixes GHSA-v2jf-442r-6mjh?
Upgrading to 0.3.4 (or the latest patched release for your respective branch) resolves the vulnerability.
Is github.com/juev/nebula-mesh affected?
Yes, github.com/juev/nebula-mesh is affected in releases prior to 0.3.4. Upgrade your dependency to 0.3.4 or later.
What CWE is associated with GHSA-v2jf-442r-6mjh?
GHSA-v2jf-442r-6mjh is classified under CWE-294: Authentication Bypass by Capture-replay (A capture-replay flaw exists when the design of the product makes it possible for a malicious user to sniff network traffic and bypass authentication by replaying it to the server in question to the same effect as the original message (or with minor changes).).
How can I check Go dependencies for GHSA-v2jf-442r-6mjh?
Run the dependency tree command: 'inspect dependencies for github.com/juev/nebula-mesh'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-v2jf-442r-6mjh",
  "modified" : "2026-06-26T21:01:09Z",
  "published" : "2026-06-26T21:01:09Z",
  "aliases" : [ ],
  "summary" : "nebula-mesh: Signed-poll nonce LRU is in-memory and bounded; replay survives restart + eviction",
  "details" : "`internal/api/pop/nonce.go:25,40,86` + `internal/api/server.go:38` — the signed-poll nonce cache is an in-process LRU sized at 65,536 entries. `internal/api/updates.go:31` sets `pollClockSkew = 5 * time.Minute` as the replay window.\n\n## Affected\nAll released versions through v0.3.0 that have shipped the ADR 0004 signed-poll path. (If this is gated behind a feature flag, on a side branch, or not yet on a release tag, please flag — this advisory may not apply to the released artifact yet.)\n\n## Threat model\nA captured signed-poll request can be replayed:\n\n1. **After any process restart** — the in-memory LRU is wiped, so the original nonce becomes \"unseen\" again. Replay succeeds if the original timestamp is still within the 5-minute skew.\n2. **After forced eviction** — an attacker with control of any single host can flood >65,536 nonces under their own host_id, driving the global LRU to evict the victim's recorded nonce. Replay then succeeds.\n\nImpact is bounded: a replayed poll fetches the `/api/v1/agent/updates` body. That body can include a freshly-minted enrollment token if a rekey is pending (`updates.go:249-260`) — at which point the attacker holds a single-use token they can redeem under their own keypair.\n\n## Suggested fix\nTwo options, either acceptable:\n\n1. Persist nonces in SQLite keyed by `(host_id, nonce)` with `ON CONFLICT DO NOTHING`, retained for the timestamp-skew window. Adds one transactional INSERT per poll; bounded by the skew window (~5 min worth of rows server-wide).\n2. Per-host cap on the LRU instead of a global 65k cap, so one host cannot evict another's records. Combined with shorter skew (≤30s) to bound the post-restart replay window.\n\nOption 1 is more robust; option 2 is lower-implementation-effort.",
  "severity" : [ {
    "type" : "CVSS_V4",
    "score" : "CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:U"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Go",
      "name" : "github.com/juev/nebula-mesh"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "0.3.4"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 0.3.3"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/juev/nebula-mesh/security/advisories/GHSA-v2jf-442r-6mjh"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/juev/nebula-mesh"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-294" ],
    "severity" : "LOW",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-06-26T21:01:09Z",
    "nvd_published_at" : null
  }
}