[Security] Hardcoded JWT fallback secret enables token forgery
Summary
The JWT utility uses the predictable default secret secret when JWT_SECRET is empty. An attacker who knows this value can generate valid HS256 signatures for tokens processed by affected authentication paths, subject to any additional authorization and database checks.
Affected Version
Affected version: commit c3413ac19b755107b2b962e5459aa77ce5ebd4b2 on branch main.
Technical Details and Root Cause
At api/common/utils/jwt/jwt.go:12, the signing key is configured as []byte(env.String("JWT_SECRET", "secret")) (source). The environment helper uses the configured default when the environment value is empty (env.go:44, env.go:49).
The key is used in the JWT signing and verification chain (jwt.go:21, jwt.go:31, jwt.go:36:
17: "eid": eid,
18: "exp": time.Now().Add(168 * time.Hour).Unix(),
19: }
20:
21: token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
22: return token.SignedString(secretKey)
23: }
Exact source
The same key is also referenced by delegated upload JWT handling and batch-upload authentication paths (upload_delegate.go:45, upload_delegate.go:61, batch_upload_auth.go:65, batch_upload_auth.go:99).
Impact
An attacker needs access to a deployment where JWT_SECRET is empty and knowledge of the default value secret; no credential is needed to calculate a valid signature. Forged tokens may be accepted by JWT-based authentication consumers, potentially enabling impersonation or unauthorized access to data available through those consumers.
The primary authentication path additionally checks users.access_token, user identity, account status, and database role (user.go:131, user.go:136, auth.go:149, auth.go:162); whether the default alone enables unauthorized access therefore depends on deployment configuration and the specific consuming path.
Reproduction Conditions
Configure a deployment with JWT_SECRET empty, confirm that the JWT key resolves to the default secret, and trace an existing JWT authentication or batch-upload path. Validate whether an HS256 token signed with secret passes that path’s signature and subsequent identity, status, role, or database-token checks.
Recommended Fix
- Remove the committed
"secret" fallback and fail closed when JWT_SECRET is missing or empty.
- Require a unique, high-entropy secret for every deployment and rotate the exposed value.
- Store signing keys in a server-side secret or key manager, not in source-controlled configuration.
- Use separate, scoped keys where delegated upload authentication has different trust requirements.
- Keep credential claims minimal and never derive signing keys from passwords or password hashes.
This observation was identified during our ongoing research on authentication token security. We would be happy to provide additional technical details or assistance with preparing a patch. Please feel free to contact us if any clarification is needed.
[Security] Hardcoded JWT fallback secret enables token forgery
Summary
The JWT utility uses the predictable default secret
secretwhenJWT_SECRETis empty. An attacker who knows this value can generate valid HS256 signatures for tokens processed by affected authentication paths, subject to any additional authorization and database checks.Affected Version
Affected version: commit
c3413ac19b755107b2b962e5459aa77ce5ebd4b2on branchmain.Technical Details and Root Cause
At
api/common/utils/jwt/jwt.go:12, the signing key is configured as[]byte(env.String("JWT_SECRET", "secret"))(source). The environment helper uses the configured default when the environment value is empty (env.go:44, env.go:49).The key is used in the JWT signing and verification chain (jwt.go:21, jwt.go:31, jwt.go:36:
Exact source
The same key is also referenced by delegated upload JWT handling and batch-upload authentication paths (upload_delegate.go:45, upload_delegate.go:61, batch_upload_auth.go:65, batch_upload_auth.go:99).
Impact
An attacker needs access to a deployment where
JWT_SECRETis empty and knowledge of the default valuesecret; no credential is needed to calculate a valid signature. Forged tokens may be accepted by JWT-based authentication consumers, potentially enabling impersonation or unauthorized access to data available through those consumers.The primary authentication path additionally checks
users.access_token, user identity, account status, and database role (user.go:131, user.go:136, auth.go:149, auth.go:162); whether the default alone enables unauthorized access therefore depends on deployment configuration and the specific consuming path.Reproduction Conditions
Configure a deployment with
JWT_SECRETempty, confirm that the JWT key resolves to the defaultsecret, and trace an existing JWT authentication or batch-upload path. Validate whether an HS256 token signed withsecretpasses that path’s signature and subsequent identity, status, role, or database-token checks.Recommended Fix
"secret"fallback and fail closed whenJWT_SECRETis missing or empty.This observation was identified during our ongoing research on authentication token security. We would be happy to provide additional technical details or assistance with preparing a patch. Please feel free to contact us if any clarification is needed.