← All CVEs NewScan detects
critical

CVE-2026-97055

SigNoz ships an EMPTY default JWT signing secret, so anyone can forge an admin session (CVSS 9.2)

Severity
critical
Affected product
SigNoz
Affected versions
SigNoz ≥ 0.8.0, < 0.143.0
Fixed in
SigNoz 0.143.0
Added to NewScan
2026-09-24
Detected by
NewScan — free, self-hosted

How NewScan reports it

COMPONENT VERSION RANGE

NewScan fingerprints SigNoz from its response and reports this CVE when the detected version falls inside the affected range below.

Added 2026-09-24 (/daily-cve). Version-gated on the tech_signatures "SigNoz" row added the same day and its /api/v1/version version_from - before that row SigNoz was bucket [D] in cve_coverage_audit.py, fingerprinted not at all, and this CVE was unwritable. The bug: `tokenizer::jwt::secret` (SIGNOZ_TOKENIZER_JWT_SECRET, or the deprecated SIGNOZ_JWT_SECRET) DEFAULTS TO THE EMPTY STRING and the server starts anyway without validating it, so every install that never set one is signing sessions with a key the attacker already has. GHSA-c26w-g4j8-39m2 gives the whole chain anonymously: GET /api/v2/sessions/context?email=<target> discloses the org id and confirms the address is registered, the empty HMAC key then signs a token for that org and a known user id, and /api/v2/users/me accepts it - and the JWT tokenizer cannot revoke anything, DeleteToken being a no-op, so the forged admin token lives until the version changes. THE BOUNDS ARE THE ADVISORY'S, both ends: `ge 0.8.0` because the tokenizer was introduced there and an older install is not in the affected train, `lt 0.143.0` because that release both requires a secret and rejects the empty one. MEASURED on loopback 2026-09-24, both containers and volumes removed after: v0.142.1 answers /api/v1/version with {"version":"v0.142.1"...} and falls inside the range, v0.143.0 answers 0.143.0 and falls outside it - the negative case, which is the claim that matters on a version gate. THIS IS A CONFIGURATION-CONDITIONAL ADVISORY and the detail should be read that way: an operator who set a real secret on an affected build is not exploitable, but the default is the vulnerable state and the scanner cannot see the secret, so the row tells the operator to patch or to check their own configuration. That is the same call every version-match row here makes. The sibling CVE-2026-97056 is deliberately NOT a row: it needs the OPAQUE session tokenizer, which was not the default on any version in its own affected range, so a version gate would call the large majority of in-range installs vulnerable - a false positive by construction. It is in docs/backlog.md instead.

References

Scan for this yourself — local, in-band scanning is free.

Get NewScan (FREE) →