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;
Source: config.ts
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));
Source: api-app.ts
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);
});
});
Source: passport.ts
Protected routes rely on req.isAuthenticated():
if (req.isAuthenticated()) {
return next();
}
res.sendStatus(401);
Source: auth.ts
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.
HyperDX Uses a Public Default Express Session Secret
Summary
HyperDX uses the public value
hyperdx is cool 👋whenEXPRESS_SESSION_SECRETis not configured:Source:
config.tsThe value is used as the signing secret for the
express-sessioncookie:Source:
api-app.tsAnyone who knows the public source can generate valid signatures for arbitrary
connect.sidvalues. This weakens the integrity protection of the sessioncookie.
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:
Source:
passport.tsProtected routes rely on
req.isAuthenticated():Source:
auth.tsProof of concept
Run this only against a local HyperDX test instance. The following creates a
correctly signed cookie for an attacker-chosen session ID:
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 thechosen session ID has no corresponding authenticated session in MongoDB.
As a positive control, log in to the local test instance, retain the returned
connect.sidcookie, and request/me. The request succeeds because Passportcan recover the user from the server-side session.
Impact
The default
hyperdx is cool 👋secret allows an attacker to sign arbitrarysession-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_SECRETand also expose one of those session-stateconditions. Otherwise, the demonstrated impact is the use of a public default
for a production authentication secret.
Remediation
hyperdx is cool 👋as the fallback in authenticated deployments.EXPRESS_SESSION_SECRET.placeholder.