Admin JWTs signed with a well-known secret when JWT_SECRET is unset #1

Closed
opened 2026-08-31 18:55:29 -05:00 by Ghost · 0 comments

Severity

High

What's going on

The admin API signs JWTs with JWT_SECRET when set. If it is unset, NewJWTManager used a fixed string compiled into the binary (dev-only-insecure-secret-change-in-prod). docker-compose.yml does not set JWT_SECRET, and the README docker path does not either.

Anyone who can reach the admin API can mint a valid admin Bearer token without knowing the login password. That is full control of proxy hosts, streams, certs, and access lists.

Practical impact

A default docker compose up (or a binary started with no JWT_SECRET) on a LAN/public bind has a publicly known signing key. Changing the admin password does not fix this.

Fix

  • Prefer JWT_SECRET from the environment.
  • Otherwise generate a random secret once and persist it under the data dir as data/.jwt_secret (mode 0600).
  • Do not fall back to a well-known constant.

A PR with this change is attached.

## Severity High ## What's going on The admin API signs JWTs with `JWT_SECRET` when set. If it is unset, `NewJWTManager` used a **fixed string compiled into the binary** (`dev-only-insecure-secret-change-in-prod`). `docker-compose.yml` does not set `JWT_SECRET`, and the README docker path does not either. Anyone who can reach the admin API can mint a valid admin Bearer token without knowing the login password. That is full control of proxy hosts, streams, certs, and access lists. ## Practical impact A default `docker compose up` (or a binary started with no `JWT_SECRET`) on a LAN/public bind has a publicly known signing key. Changing the admin password does **not** fix this. ## Fix - Prefer `JWT_SECRET` from the environment. - Otherwise generate a random secret once and persist it under the data dir as `data/.jwt_secret` (mode 0600). - Do not fall back to a well-known constant. A PR with this change is attached.
Ghost closed this issue 2026-08-31 18:57:55 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: s1d3sw1ped/helix-proxy#1