Description
A HIGH severity security vulnerability exists in backend/routes/auth.js at line 34 and backend/config/passportConfig.js. Two issues compound: (1) the session ID is never regenerated after successful authentication, enabling session fixation attacks; (2) deserializeUser returns the full Mongoose document including the bcrypt-hashed password, which is then serialised into the login response JSON via req.user.
Impact
Session fixation: an attacker who can plant a known session ID into a victim's browser (via cookie injection from a related subdomain or briefly shared access) becomes fully authenticated as that victim after the victim logs in — no password required.
Password hash leak: the bcrypt hash present in the POST /api/auth/login response enables offline dictionary attacks. Anyone who can read network traffic, API logs, or browser DevTools obtains a crackable credential.
Steps to Reproduce
- Make any unauthenticated request to the server (e.g.,
GET /api/auth/logout) and record the connect.sid cookie value.
- Log in with valid credentials at
POST /api/auth/login.
- Inspect the JSON response body — it contains a
password field with the full bcrypt hash.
- After login, inspect
connect.sid — the value is unchanged from step 1, confirming no session regeneration occurred.
Expected Behaviour
On successful login the server must issue a brand-new session ID. The login response must contain only safe fields (id, username, email) — never a password hash or any credential material.
Proposed Fix
Refactor the login route to regenerate the session before establishing the authenticated context, and fix deserializeUser to never load the password hash.
// backend/routes/auth.js — replace login route
router.post("/login", validateRequest(loginSchema), (req, res, next) => {
passport.authenticate('local', (err, user, info) => {
if (err) return next(err);
if (!user) return res.status(401).json({ message: info?.message || 'Invalid credentials' });
req.session.regenerate((err) => {
if (err) return next(err);
req.logIn(user, (err) => {
if (err) return next(err);
res.status(200).json({
message: 'Login successful',
user: { id: user.id, username: user.username, email: user.email },
});
});
});
})(req, res, next);
});
// backend/config/passportConfig.js — fix deserializeUser
passport.deserializeUser(async (id, done) => {
try {
const user = await User.findById(id).select('-password');
done(null, user);
} catch (err) {
done(err, null);
}
});
Files affected: backend/routes/auth.js, backend/config/passportConfig.js
Labels
type:security level:advanced gssoc:approved
Please assign this issue to me under GSSoC 2026. I will open a PR with a complete fix covering all affected files, proper test coverage, and verification steps.
Description
A HIGH severity security vulnerability exists in
backend/routes/auth.jsat line 34 andbackend/config/passportConfig.js. Two issues compound: (1) the session ID is never regenerated after successful authentication, enabling session fixation attacks; (2)deserializeUserreturns the full Mongoose document including the bcrypt-hashed password, which is then serialised into the login response JSON viareq.user.Impact
Session fixation: an attacker who can plant a known session ID into a victim's browser (via cookie injection from a related subdomain or briefly shared access) becomes fully authenticated as that victim after the victim logs in — no password required.
Password hash leak: the bcrypt hash present in the
POST /api/auth/loginresponse enables offline dictionary attacks. Anyone who can read network traffic, API logs, or browser DevTools obtains a crackable credential.Steps to Reproduce
GET /api/auth/logout) and record theconnect.sidcookie value.POST /api/auth/login.passwordfield with the full bcrypt hash.connect.sid— the value is unchanged from step 1, confirming no session regeneration occurred.Expected Behaviour
On successful login the server must issue a brand-new session ID. The login response must contain only safe fields (
id,username,email) — never a password hash or any credential material.Proposed Fix
Refactor the login route to regenerate the session before establishing the authenticated context, and fix
deserializeUserto never load the password hash.Files affected:
backend/routes/auth.js,backend/config/passportConfig.jsLabels
type:securitylevel:advancedgssoc:approvedPlease assign this issue to me under GSSoC 2026. I will open a PR with a complete fix covering all affected files, proper test coverage, and verification steps.