GHSA-7hp6-g3pq-3pc3

Suggest an improvement
Source
https://github.com/advisories/GHSA-7hp6-g3pq-3pc3
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/06/GHSA-7hp6-g3pq-3pc3/GHSA-7hp6-g3pq-3pc3.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-7hp6-g3pq-3pc3
Aliases
Published
2026-06-08T23:08:15Z
Modified
2026-06-25T19:56:05Z
Severity
  • 8.7 (High) CVSS_V4 - CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N CVSS Calculator
Summary
nebula-mesh: Host advanced overrides allow YAML injection into agent config.yml
Details

internal/configgen/generator.go:86,108,119 interpolates the operator-supplied ListenHost and TunDevice fields raw into a text/template that produces the agent's config.yml. internal/web/advanced.go:20-35 accepts both with only strings.TrimSpace — no character or shape validation.

Exploit

An operator (or attacker with any operator key, given the cross-tenant CRUD advisory) sets adv_tun_device to:

nebula0
lighthouse:
  am_lighthouse: true
  hosts: ["10.0.0.1"]
#

The agent fetches the rendered config on its next signed poll. On config reload, it loads the injected YAML keys: the host self-promotes to lighthouse, attracts mesh traffic, or sets am_relay: true to be selected as a relay. The ListenHost field has the same shape.

Affected

All released versions prior to v0.3.2.

Threat model

  • Today: operator can compromise their own host's config (trivially allowed if they own the host, but they can also set lighthouse/relay flags that the operator-create form does NOT expose — privilege uplift within their own tenant).
  • Combined with the critical /api/v1 authz advisory: any operator key can mutate ANOTHER tenant's host overrides and inject YAML there.
  • Post-fix of the authz advisory: still relevant — the agent unconditionally trusts whatever config the server hands it, so any future operator-impersonation bug re-amplifies this.

Suggested fix

Two options, either acceptable:

  1. Input validation in parseAdvancedFromForm (internal/web/advanced.go):

    • ListenHost: regex ^[A-Za-z0-9.:\[\]_-]+$ (IPv4/IPv6/hostname)
    • TunDevice: regex ^[A-Za-z0-9_-]{1,15}$ (Linux IFNAMSIZ caps at 15) Reject invalid input with a form-level error; do not write to the host row.
  2. Safer marshalling: switch configgen/generator.go to marshal a typed Go struct via gopkg.in/yaml.v3 (which escapes correctly) instead of text/template string-concat. Larger change, but eliminates this entire injection class.

Option 2 is preferable long-term. Option 1 is the quick fix.

The unsafe_routes advanced field is already netip.Parse{Prefix,Addr}-validated at enroll.go:226-233 — apply the same validation discipline to the other advanced fields.

Database specific
{
    "cwe_ids": [
        "CWE-94"
    ],
    "github_reviewed": true,
    "github_reviewed_at": "2026-06-08T23:08:15Z",
    "nvd_published_at": null,
    "severity": "HIGH"
}
References

Affected packages

Go / github.com/juev/nebula-mesh

Package

Name
github.com/juev/nebula-mesh
View open source insights on deps.dev
Purl
pkg:golang/github.com/juev/nebula-mesh

Affected ranges

Type
SEMVER
Events
Introduced
0 Unknown introduced version / All previous versions are affected
Fixed
0.3.2

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/06/GHSA-7hp6-g3pq-3pc3/GHSA-7hp6-g3pq-3pc3.json"