🔏 fix: Remove Federated Tokens from OpenID Refresh Response (#12264)

* 🔒 fix: Remove OpenID federated tokens from refresh endpoint response

The refresh controller was attaching federatedTokens (including the
refresh_token) to the user object returned in the JSON response,
exposing HttpOnly-protected tokens to client-side JavaScript.
The tokens are already stored server-side by setOpenIDAuthTokens
and re-attached by the JWT strategy on authenticated requests.

* 🔒 fix: Strip sensitive fields from OpenID refresh response user object

The OpenID refresh path returned the raw findOpenIDUser result without
field projection, unlike the non-OpenID path which excludes password,
__v, totpSecret, and backupCodes via getUserById projection. Destructure
out sensitive fields before serializing.

Also strengthens the regression test: uses not.toHaveProperty for true
property-absence checks (expect.anything() misses null/undefined), adds
positive shape assertion, and DRYs up duplicated mock user setup.
This commit is contained in:
Danny Avila 2026-03-16 09:23:46 -04:00 committed by GitHub
parent 381ed8539b
commit d17ac8f06d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 32 additions and 22 deletions

View file

@ -119,14 +119,8 @@ const refreshController = async (req, res) => {
const token = setOpenIDAuthTokens(tokenset, req, res, user._id.toString(), refreshToken);
user.federatedTokens = {
access_token: tokenset.access_token,
id_token: tokenset.id_token,
refresh_token: refreshToken,
expires_at: claims.exp,
};
return res.status(200).send({ token, user });
const { password: _pw, __v: _v, totpSecret: _ts, backupCodes: _bc, ...safeUser } = user;
return res.status(200).send({ token, user: safeUser });
} catch (error) {
logger.error('[refreshController] OpenID token refresh error', error);
return res.status(403).send('Invalid OpenID refresh token');