Move the hardcoded __session cookie signing secret into an environment variable
- Dominant language
- TypeScript
- Stars
- 2.3k
- Forks
- 348
- PR merge metrics
- No merged PRs in 30d
Description
### What I found
`app/session.ts` hardcodes a static cookie-signing secret:
```ts
cookie: {
name: '__session',
secrets: ['oooOOooOOoOOoOOOOoo'],
sameSite: true,
httpOnly: true,
}
```
This value signs the `__session` cookie via Remix `createCookieSessionStorage` (HMAC-SHA256). Because it is committed to the public repository and identical across deployments, anyone who knows the value can mint a valid `__session` cookie.
### Context on impact (not a security report)
I want to be clear this is a **hardening / code-hygiene** note, not a vulnerability disclosure:
- The signed cookie only carries a self-asserted `username` (a display name), read in `app/utils/getUsername.server.ts`.
- When a deployment is behind Cloudflare Access, `getUsername()` returns the `Cf-Access-Authenticated-User-Email` header first and the cookie is ignored, so there is no authentication bypass or privilege escalation.
- For the public demo (`demo.orange.cloudflare.dev`) the app is intentionally open and any visitor can already set a display name via `/set-username`.
So the fix below is about removing a hardcoded secret and making the signing material deployment-specific, not about patching an exploit.
### Suggestion
Move the secret out of source and into the app's environment/secrets, e.g. a `SESSION_SECRET`:
- dev: `.dev.vars`
- production: `wrangler secret put SESSION_SECRET`
One caveat: `app/session.ts` is a module-level singleton, so the storage is created without access to `context.env`. Reading the secret may require lazily constructing the session storage per-request (or otherwise threading the secret in) rather than a bare `process.env` read, since `process.env` is only available for `NODE_ENV` in the Workers runtime.
Happy to open a PR if that's useful.
Contributor guide
Research direction
Start with app/session.ts and inspect how createCookieSessionStorage is constructed, then follow app/utils/getUsername.server.ts and the request context to determine how the deployment secret can reach session creation. Review .dev.vars and the suggested Wrangler secret configuration; done means the signing secret is no longer committed and local and production deployments use their configured secret.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- authentication, backend, security
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100