Skip to content

security: Remove hardcoded fallback JWT secrets (api/src/auth/auth.module.ts)Β #137

@Xhristin3

Description

@Xhristin3

πŸ”΄ Where to work

Primary file: api/src/auth/auth.module.ts β€” line 12, replace "dev-secret-change-me" fallback with fatal error
Secondary file: api/src/gateways/gateways.module.ts β€” line 15-17, replace "dev-insecure-secret-change-me" fallback
New file: api/src/config/jwt.config.ts β€” create shared JWT config factory
Reference: api/src/config/env.ts β€” already validates JWT_SECRET, use this pattern

Problem Statement

Two JwtModule registrations use hardcoded fallback secrets. In api/src/auth/auth.module.ts:12: secret: process.env.JWT_SECRET ?? "dev-secret-change-me". In api/src/gateways/gateways.module.ts:15-17: secret: secret ?? "dev-insecure-secret-change-me". If deployed without JWT_SECRET set, anyone can forge JWTs using these known strings.

Evidence

// api/src/auth/auth.module.ts:12 β€” silently falls back to hardcoded secret
secret: process.env.JWT_SECRET ?? "dev-secret-change-me",

// api/src/gateways/gateways.module.ts:15-17 β€” warns but still falls back in non-prod
const secret = process.env.JWT_SECRET
if (!secret && process.env.NODE_ENV === "production") {
  throw new Error("JWT_SECRET must be set in production for WebSocket auth")
}
return { secret: secret ?? "dev-insecure-secret-change-me", ... }

Impact

If JWT_SECRET is unset in production, attackers can forge JWTs using "dev-secret-change-me" and authenticate as any user. Critical credential disclosure.

Proposed Solution

Remove all fallback secrets. Create shared JWT config factory that throws on missing secret in all environments. Generate random secret in dev only (with clear warning).

Acceptance Criteria

  • Application refuses to start when JWT_SECRET is unset (fatal error at bootstrap)
  • No hardcoded string appears as a fallback JWT secret anywhere
  • Both AuthModule and GatewaysModule use same shared config source
  • Dev mode generates and logs a random secret with a clear warning
  • All existing tests pass with JWT_SECRET set in test env

File Map

  • api/src/config/jwt.config.ts [NEW] β€” shared JWT config factory, reads from validated Env, throws on missing secret
  • api/src/auth/auth.module.ts [EDIT] β€” use shared config, remove ?? "dev-secret-change-me"
  • api/src/gateways/gateways.module.ts [EDIT] β€” use shared config, remove ?? "dev-insecure-secret-change-me"
  • api/src/config/env.ts [VERIFY] β€” JWT_SECRET already required via z.string().min(1), ensure strict

Testing Strategy

  • Unit: Test that factory throws when JWT_SECRET is empty
  • Unit: Test that factory returns correct config when JWT_SECRET is set
  • Integration: Verify app starts with JWT_SECRET set, crashes without it

Security Considerations

This eliminates a hardcoded credential. Random dev secret must be clearly marked as unsafe for production. No fallback in any environment.

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions