HyperDX Uses a Public Default Express Session Secret
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 9.9k
- Forks
- 471
- Avg merge
- 2d 4h
- Merged PRs (30d)
- 117
Description
HyperDX Uses a Public Default Express Session Secret
Summary
HyperDX uses the public value hyperdx is cool 👋 when
EXPRESS_SESSION_SECRET is not configured:
const DEFAULT_EXPRESS_SESSION = 'hyperdx is cool 👋';
export const EXPRESS_SESSION_SECRET = (env.EXPRESS_SESSION_SECRET ||
DEFAULT_EXPRESS_SESSION) as string;
The value is used as the signing secret for the express-session cookie:
const sess = {
// ...
secret: config.EXPRESS_SESSION_SECRET,
store: new MongoStore({ mongoUrl: config.MONGO_URI }),
};
app.use(session(sess));
Anyone who knows the public source can generate valid signatures for arbitrary
connect.sid values. This weakens the integrity protection of the session
cookie.
Authentication flow
The Session Cookie carries a Session ID. HyperDX stores the Passport user
identifier in the corresponding server-side session, and Passport later loads
the user from MongoDB:
passport.serializeUser(function (user, done) {
done(null, (user as any)._id);
});
passport.deserializeUser(function (id, done) {
findUserById(id).then(user => {
if (user == null) return done(null, false);
done(null, user);
});
});
Protected routes rely on req.isAuthenticated():
if (req.isAuthenticated()) {
return next();
}
res.sendStatus(401);
Proof of concept
Run this only against a local HyperDX test instance. The following creates a
correctly signed cookie for an attacker-chosen session ID:
const signature = require('cookie-signature');
const sessionId = 'attacker-chosen-session-id';
const signed = `s:${sessionId}.${signature.sign(
sessionId,
'hyperdx is cool 👋',
)}`;
console.log(encodeURIComponent(signed));
Send the result to a protected API route:
curl -i \
-H 'Cookie: connect.sid=<url-encoded-signed-cookie>' \
http://127.0.0.1:8000/me
Expected result: 401 Unauthorized. The cookie signature is valid, but the
chosen session ID has no corresponding authenticated session in MongoDB.
As a positive control, log in to the local test instance, retain the returned
connect.sid cookie, and request /me. The request succeeds because Passport
can recover the user from the server-side session.
Impact
The default hyperdx is cool 👋 secret allows an attacker to sign arbitrary
session-cookie values without knowing the deployment secret.
The secret alone does not prove arbitrary user impersonation in the current
flow. A successful impersonation would additionally require a session-state
weakness, such as disclosure or fixation of a valid session ID, or the ability
to create or modify the referenced MongoDB session.
The issue is directly exploitable in deployments that omit
EXPRESS_SESSION_SECRET and also expose one of those session-state
conditions. Otherwise, the demonstrated impact is the use of a public default
for a production authentication secret.
Remediation
- Remove
hyperdx is cool 👋as the fallback in authenticated deployments. - Require a deployment-specific high-entropy
EXPRESS_SESSION_SECRET. - Fail closed at startup when the secret is missing or equals the public
placeholder. - Rotate the secret and invalidate existing sessions after applying the fix.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with packages/api/src/config.ts and packages/api/src/api-app.ts to trace the session secret fallback and Express session setup, then review packages/api/src/utils/passport.ts and packages/api/src/middleware/auth.ts for authentication behavior. Done means authenticated deployments no longer use the public placeholder, missing or unsafe secrets fail closed, and existing sessions are rotated or invalidated as described.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- express, mongodb, typescript
- Domain
- authentication, backend, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100