From 55706df28b1759f7f54dc0278feae9a99e86fc71 Mon Sep 17 00:00:00 2001 From: anshul23102 Date: Wed, 27 May 2026 21:07:31 +0530 Subject: [PATCH] fix(auth): exclude password hash from req.user in deserializeUser Fixes #555 deserializeUser called User.findById(id) with no projection, attaching the full Mongoose document including the bcrypt password hash to req.user on every authenticated request. Any route handler returning req.user would silently expose the hash to the client. Added .select('-password -__v') to exclude the hash and internal version key. Added .lean() to return a plain object rather than a full Mongoose document, so model methods are not accessible on req.user. --- backend/config/passportConfig.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backend/config/passportConfig.js b/backend/config/passportConfig.js index 842f50ca..642c472e 100644 --- a/backend/config/passportConfig.js +++ b/backend/config/passportConfig.js @@ -35,9 +35,13 @@ passport.serializeUser((user, done) => { }); // Deserialize user (retrieve user from session) +// .select('-password -__v') excludes the bcrypt hash from req.user so it +// cannot be accidentally serialized into an API response. +// .lean() returns a plain object instead of a Mongoose document, preventing +// model methods from being accessible on req.user. passport.deserializeUser(async (id, done) => { try { - const user = await User.findById(id); + const user = await User.findById(id).select('-password -__v').lean(); done(null, user); } catch (err) { done(err, null);