6

According to the documentation at http://docs.mongodb.org/meta-driver/latest/legacy/implement-authentication-in-driver/:

The driver then runs the authenticate command for the database on which to authenticate. The authenticate command has the following syntax:

db.runCommand( { authenticate : 1, user : <username>, nonce : <nonce>, key : <digest> }

<username> is a username in the database’s system.users collection.

<nonce> is the nonce returned from a previous getnonce step.

<digest> is the hex encoding of an MD5 message digest.

The MD5 message digest is the MD5 hash of the concatenation of <nonce>, <username>, <password_digest>.

The <password_digest> is the value in the pwd field associated with the <username> in the database's system.users collection. The pwd is the hex encoding of MD5( <username> + ":mongo:" + <password_text> ).

This means that the hashing is actually done client-side, as the driver is part of the client for the database connection. In order to authenticate, the client does not need to demonstrate knowledge of the password but of the stored hash. So, the real password is the stored hash, which just happens to have been generated through hashing something. That real password is stored in plaintext in the pwd field of system.users.

Am I reading that wrong? Is there a way to secure this authentication?

Svante
  • 161
  • 1
  • 3

2 Answers2

4

In a sense, that can be considered correct.

From what I understood from the MongoDB documentation, the db.addUser() expects one to pass in an already hashed password. This is clearly seen from the documentation of the function, where the expected data type of the pwd field is hash.

I read this as MongoDB expecting the system to perform the hashing prior to registration or authentication of users in the database. This makes sense when you consider that the MongoDB user most likely isn't going to be typing the password hash by hand. The use case for these user accounts are as authentication credentials for applications so the passwords are most certainly going to be stored in a configuration file somewhere.

The enterprise version of MongoDB supports the use of Kerberos for authentication. The steps to setup Kerberos can be found in the documentations as well. If you are really worried about this as a security factor, you should look into setting up Kerberos.

DrAwesome
  • 3
  • 2
1

MongoDB does not store passwords in plaintext. As of MongoDB 3.0, Salted Challenge Response Authentication Mechanism (SCRAM) is the default authentication mechanism for MongoDB. Scram supports both SCRAM-SHA-1 and SCRAM-SHA-256 hashing mechanisms.

Having said that, when interfacing with a database via driver, these often accept a hashed password so that it is not transmitted to and from the database in plaintext form. This imposes additional responsibility on the developer because he/she has to perform the hashing at their end using the same algorithm as is employed within the DB server. Luckily, these are readily available for just about any programming language.

Querying the system.users collection will return a document similar to this:

{
  "_id": "admin.123",
  "user": "123",
  "db": "admin",
  "credentials": {
    "SCRAM-SHA-1": {
      "iterationCount": 10000,
      "salt": "f9SdPCCcBOwk71/xDkj6Sw==",
      "storedKey": "83mNhTYctOdlYsL1sbnfpiA0uxw=",
      "serverKey": "09H9aEKKufaoCDxqUkHntx6EqrE="
    }
  },
  "roles": []
}

You can delve into the users and other collections with a good DB admin tool such as Navicat for MongoDB. It lets you view documents in three formats: Tree, JSON, and grid:

Navicat Views

Hope that answers your question.

rob

peterh
  • 2,938
  • 6
  • 25
  • 31
Rob Gravelle
  • 111
  • 2