GHSA-q4vm-pq3q-8wgq

Suggest an improvement
Source
https://github.com/advisories/GHSA-q4vm-pq3q-8wgq
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/07/GHSA-q4vm-pq3q-8wgq/GHSA-q4vm-pq3q-8wgq.json
JSON Data
https://api.test.osv.dev/v1/vulns/GHSA-q4vm-pq3q-8wgq
Aliases
Published
2026-07-14T20:17:04Z
Modified
2026-08-24T00:37:04Z
Severity
  • 7.1 (High) CVSS_V4 - CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N CVSS Calculator
Summary
nebula-mesh: Operator session tokens stored in plaintext in the database
Details

Impact

Operator session tokens are stored in plaintext in the operator_sessions 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/sqlite_operators.go:590 — CreateOperatorSession inserts sess.Token verbatim.
  • internal/store/sqlite_operators.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 hash of the session token, mirroring API keys and enrollment tokens:

  1. Add a HashSessionToken helper (alongside the existing token-hash helpers).
  2. Migration to add a token_hash column.
  3. Update CreateOperatorSession, PromoteOperatorSession, and GetOperatorBySession to write/look up by hash.
  4. Drop the plaintext token column in a follow-up migration.

Sessions are ephemeral (24h TTL), so all active sessions can be invalidated on deployment — no backward compatibility needed.

Workarounds

Restrict and encrypt database backups; rotate the operator database. These mitigate exposure but do not fix the underlying storage of plaintext tokens.

Resources

  • internal/models/operator.go:58-66
  • internal/store/sqlite_operators.go:577-698
  • Migration 005_operators.up.sql:27
  • Prior related advisory: GHSA-ghmh-jhmj-wcmf
Database specific
{
    "cwe_ids":  [
        "CWE-312",
        "CWE-522"
    ],
    "github_reviewed":  true,
    "github_reviewed_at":  "2026-07-14T20:17:04Z",
    "nvd_published_at":  null,
    "severity":  "HIGH"
}
References

Affected packages

Go / github.com/forgekeep/nebula-mesh

Package

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

Affected ranges

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

Database specific

last_known_affected_version_range
"<= 0.3.7"
source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/07/GHSA-q4vm-pq3q-8wgq/GHSA-q4vm-pq3q-8wgq.json"