Rocket.chat: Crowd Login - password always stored in plaintext in mongo and logged

Created on 7 Aug 2017  路  15Comments  路  Source: RocketChat/Rocket.Chat

Description:

When using Atlassian Crowd to let users login to Rocket.Chat, the password of the user is always stored in plaintext in the mongo database. This does not happen when using LDAP.

Server Setup Information:

  • Version of Rocket.Chat Server: 0.57.2
  • Operating System: Ubuntu 16.04.3 LTS
  • Deployment Method(snap/docker/tar/etc): snap
  • Number of Running Instances: 1
  • DB Replicaset Oplog: activated
  • Node Version: v4.2.6

Steps to Reproduce:

  1. Activate crowd login. It does not matter if deny unauthorized or sync users is set.
  2. Let user login. It does not matter if the user already exists or is newly created.
  3. Check the mongodb users collection, see that the password is stored in plaintext.
  4. Check the logs and see the password there in plaintext.

Expected behavior:

Password is not stored at all or hashed.

Actual behavior

Password is stored in plaintext.

oauth / sso security

Most helpful comment

Agreed this should be released as soon as possible. In the meantime, is there are recommended method of patching a docker install?

All 15 comments

I guess the syncing happens because of https://github.com/RocketChat/Rocket.Chat/blob/develop/packages/rocketchat-crowd/server/crowd.js#L128 and https://github.com/RocketChat/Rocket.Chat/blob/develop/packages/rocketchat-crowd/server/crowd.js#L152.
The sync seems to happen no matter if CROWD_Sync_User_Data is set or not.

However I could be totally wrong here.

ping @rufushonour, hope you're still working with rocket.chat! :)

I have patched this on my local instance running 0.65.2. I was not unable to reproduce #4 on your list. Even with all log levels enabled I never saw the plain text password.

I added several other features with my changes:

  • Call Accounts.setPassword whenever a Crowd user authenticates. This will allow Rocket.Chat authentication in the event Crowd is offline.
  • Added a Sync Interval setting to customize how often the Crowd user data sync happens
  • Added a Clean Usernames setting. Because Crowd will allow email as username I implemented a simple method to fix this. Basically split on the '@' and use the first section as the rocket chat username. Could use some guidance on how to make this better.
  • Added a crowd_username property which stores the actual crowd username and is now used for all syncing purposes. This will allow users to change their RC username and still be synced with Crowd.
  • Added a secondary sync method for attempting to find user by email. This was mainly to repair my own users that had changed their usernames. If more than one email is found it bails out but for the most part worked really well.
  • Added a Sync User Data button to the Atlassian Crowd admin ui. This is async and is used to run a Crowd data sync on demand.

The only thing that is a problem with what i have built is the way im saving the crowd password in conjunction with the Allow Password Change setting. This setting effectively has no effect. A user could change their password in RC but as soon as they logged in with their Crowd credentials the password is overwritten with the crowd password.

If anyone else is interested in these improvements I can submit a pull request

@jsternadel Would be great to see these changes in upstream!
I'm hoping this will carry over removed and disabled users from crowd. Right now, it doesn't look like you can disable Rocket.Chat users through crowd.

I can't confirm/reproduce that passwords stored in plaintext, only bcrypt from login, but our crowd is connected to a active directory.

@jsternadel Maybe you want apply your additional changes to my fork #11483.

This should be released as fast as possible.

Agreed this should be released as soon as possible. In the meantime, is there are recommended method of patching a docker install?

Can confirm this is an issue and can see plaintext passwords stored in the MongoDB users collection. Using Crowd 3.2.2 with Crowd Internal Directory.

Here is a Gist with my current working changes:
https://gist.github.com/jsternadel/ffaadff287de75404032677a4595f629

The cleanUserName() method still needs some work. It should be trying to create a match from the global setting UTF8_Names_Validation. Unfortunately I haven't had time to try this out yet. Our Crowd instance allows emails to be used as usernames which doesn't work so well in RC.

The biggest change is using Accounts.setPassword which is the default way of saving user passwords that includes bcrypt encryption. This also allows RC to still be used if Crowd goes down since the fallback authentication mechanism actually works now.

There are also some new settings for invoking the cleanUserName() method as well as initiating a user sync from the "Atlassian Crowd" settings page.

Unfortunately my normal job is taking up all my dev time right now. Hopefully someone can use this to implement a permanent fix.

Here is a second Gist for anyone using Rocket Chat in a docker and want to know how to patch it with my latest code.
https://gist.github.com/jsternadel/09d2a068343f64146e98f675b20666e7

This will have to be done every time you update your container. I am currently on version 0.68.3 and this works for my environment.

@RocketChat any update?

Why do we need to patch it manually for so long, that's a SHAME

same issue here

@jsternadel Your patch works perfect, I only changed sync part - when user is not found in crowd I do not throw an error - instead just skip this person.

@jsternadel Your patch works perfect, I only changed sync part - when user is not found in crowd I do not throw an error - instead just skip this person.

Why not create a PR then?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tanc picture tanc  路  3Comments

sta-szek picture sta-szek  路  3Comments

Buzzele picture Buzzele  路  3Comments

brendanheywood picture brendanheywood  路  3Comments

karlprieb picture karlprieb  路  3Comments