[SERVER-26052] calculation of salted password where normalization is done wrong Created: 09/Sep/16  Updated: 28/Jan/20  Resolved: 28/Jan/20

Status: Closed
Project: Core Server
Component/s: Security
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor - P4
Reporter: Marcel Timmerman Assignee: Spencer Jackson
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Operating System: ALL
Sprint: Security 2020-02-10
Participants:

 Description   

The following example shown at page has in my opinion a bug

computeClientKey

function computeClientKey(username, plain_text_password) {
        mongo_hashed_password = HEX( MD5( UTF8( username + ':mongo:' + plain_text_password )));
        saltedPassword  = Hi(Normalize(mongo_hashed_password), salt, i);
        clientKey = HMAC(saltedPassword, "Client Key");
}

Normalize() is used on the place where it is used in the rfc5802 but should be used on username, password and authzid individually. Besides, in the above example, Normalize is used on a hexadecimal string which will change nothing and only eats cpu time.

In discussions with David Golden the example is not just an example but is the way how the server does things and I understood that changing that would break code.There has been some answers returned before such as
"we don't expect anyone to use non-ASCII usernames and passwords" or "we didn't do that before for usernames/passwords so we don't want to change and break compatibility". These two answers contradict each other because if only ASCII names are used, then changing it wouldn't do any harm because the normalization wouldn't change the strings.

Furthermore I can't imagine that there wouldn't be any use outside the 'West' (Europe and US), so a Japanese name like 黒澤 明 (Akira Kurosawa) for example should be possible to use. This would still work without normalisation, but imagine a type setting system using this name with some other kind of spacing between the characters, it would not be mapped to an ASCII space and there will be problems while it is not visible for the reader. There are also characters which should fail normally. So this normalization proces takes care of mapping, unicode normalization, fail on wrong characters and bidirectional use which is not taken care of this way.

To prevent any breaking of code, the server could add a boolean to the account info which says if it is using normalized names or not. New added names will be converted(bool set to true) and the old ones stay the same(bool set to false). Old servers cannot change drivers can use the old method and drivers should try login twice after some newer server version where the change is incorporated.

That said, if you think that mostly ASCII characters are used then there should only be an occasional breakage.



 Comments   
Comment by Spencer Jackson [ 28/Jan/20 ]

While SCRAM-SHA-1 credentials continue to be unnormalized, MongoDB's implementation of SCRAM-SHA-256 performs SASLPrep on passwords. In order to normalize passwords, create users with or update them to have credentials supporting the new mechanism.

Comment by David Golden [ 15/Sep/16 ]

Also relevant:

Comment by David Golden [ 09/Sep/16 ]

Example failure (MongoDB 3.2.9):

Shell:

MongoDB Enterprise > db.createUser({user:"me", pwd:"é",roles: [ {role:"readWrite", db: "test" } ]})
Successfully added user: {
        "user" : "me",
        "roles" : [
                {
                        "role" : "readWrite",
                        "db" : "test"
                }
        ]
}

Perl client code:

#!/usr/bin/env perl
use v5.10;
use strict;
use warnings;
use utf8;
use open qw/:std :utf8/;
use MongoDB;
 
my $uri1 = "mongodb://me:\N{U+00E9}\@localhost:27017/test";  # é
my $uri2 = "mongodb://me:e\N{U+0301}\@localhost:27017/test"; # e + combining accent
 
for my $u ( $uri1, $uri2 ) {
    say "\nConnecting to $u";
    my $mc = MongoDB->connect($u);
    my $coll = $mc->ns("test.foo");
    eval { $coll->insert_one({x => 1}) };
    say $@ ? $@ : "Inserted OK";
}

Error when running:

$ perl test.pl
 
Connecting to mongodb://me:é@localhost:27017/test
Inserted OK
 
Connecting to mongodb://me:é@localhost:27017/test
MongoDB::AuthError: Authentication to localhost:27017 failed: MongoDB::AuthError: SCRAM-SHA-1 error: MongoDB::DatabaseError: Authentication failed.

Server log messages:

2016-09-09T15:57:07.878-0400 I ACCESS   [conn29] Successfully authenticated as principal me on test
...
2016-09-09T15:57:07.960-0400 I ACCESS   [conn30] SCRAM-SHA-1 authentication failed for me on test from client ::1 ; AuthenticationFailed: SCRAM-SHA-1 authentication failed, storedKey mismatch

Comment by Bernie Hackett [ 09/Sep/16 ]

Hi,

Can you provide an example where you have not been able to authenticate a user due to the drivers and server not using SASLprep?

Generated at Thu Feb 08 04:11:00 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.