## 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
## 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
Update github.com/forgekeep/nebula-mesh to 0.3.8 if you use the affected versions. Test the change in a non-production environment first.
Local check
hol-guard supply-chain scannebula-mesh: Operator session tokens stored in plaintext in the database affects github.com/forgekeep/nebula-mesh (go). Severity is high. ## 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
AI coding agents often install or upgrade packages automatically in go. A high vulnerability in a dependency can be pulled into a project through a normal install or update without a human reviewing the change, expanding the blast radius from a single package to every agent workspace that depends on it.
| Package | Affected range | Fixed version |
|---|---|---|
| github.com/forgekeep/nebula-meshgo | <=0.3.7 | 0.3.8 |
Fixed versions are reported by the source feed; confirm compatibility before updating.
Reported by GitHub Security Advisories (ghsa).
HOL Guard can help your team review package activity against supported protection paths.
Explore HOL GuardUpdate github.com/forgekeep/nebula-mesh to 0.3.8 if you use the affected versions. Test the change in a non-production environment first.
Local check
hol-guard supply-chain scannebula-mesh: Operator session tokens stored in plaintext in the database affects github.com/forgekeep/nebula-mesh (go). Severity is high. ## 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
AI coding agents often install or upgrade packages automatically in go. A high vulnerability in a dependency can be pulled into a project through a normal install or update without a human reviewing the change, expanding the blast radius from a single package to every agent workspace that depends on it.
| Package | Affected range | Fixed version |
|---|---|---|
| github.com/forgekeep/nebula-meshgo | <=0.3.7 | 0.3.8 |
Fixed versions are reported by the source feed; confirm compatibility before updating.
Reported by GitHub Security Advisories (ghsa).
HOL Guard can help your team review package activity against supported protection paths.
Explore HOL Guard