[SERVER-21659] bypassDocumentValidation authentication error Created: 24/Nov/15  Updated: 25/Jan/17  Resolved: 30/Nov/15

Status: Closed
Project: Core Server
Component/s: Security
Affects Version/s: 3.2.0-rc3
Fix Version/s: 3.2.0-rc5

Type: Bug Priority: Major - P3
Reporter: Hannes Magnusson Assignee: Spencer Brody (Inactive)
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Documented
is documented by DOCS-8944 bypassDocumentValidation authenticati... Closed
Related
is related to CDRIVER-1024 bypassDocumentValidation test fails o... Closed
is related to SERVER-21486 successful authentication does not gi... Closed
is related to SERVER-21561 Remove privilege redaction added for ... Closed
is related to SERVER-21673 Shell ignores "opQueryOnly", "opComma... Closed
Backwards Compatibility: Minor Change
Operating System: ALL
Steps To Reproduce:

On solaris-spawn evergreen spawnhost:

export LC_ALL=C
 
 
mkdir -p /data/mci/mongo-c-driver
cd /data/mci/mongo-c-driver
 
curl http://s3.amazonaws.com/mciuploads/mongo-c-driver/solaris-32-bit/8404048cf751df1c01e8f64867ebd4d86064f3e6/artifacts/mongo-mongo_c_driver_solaris_32_bit_8404048cf751df1c01e8f64867ebd4d86064f3e6_15_11_24_14_35_54.tar.gz -o mongo_c_driver_solaris_32_bit_8404048cf751df1c01e8f64867ebd4d86064f3e6_15_11_24_14_35_54.tar.gz --silent
 
tar -xzf mongo_c_driver_solaris_32_bit_8404048cf751df1c01e8f64867ebd4d86064f3e6_15_11_24_14_35_54.tar.gz
curl -s http://downloads.mongodb.org/sunos5/mongodb-sunos5-x86_64-latest.tgz --output mongo-archive.tgz
tar zxvf mongo-archive.tgz
mv mongodb* mongodb
 
export PATH=/data/mci/mongo-c-driver/mongodb/bin:$PATH:/opt/mongodbtoolchain/bin:

mkdir /data/db
mongod -vvvv --smallfiles --logpath=/data/db/mongod.log --auth --dbpath=/data/db --fork
mongo

> use admin
switched to db admin
> db.runCommand({createUser: "example", "pwd": "password", roles: [                    
... {'role': 'userAdminAnyDatabase', 'db': 'admin'},                                         
... {'role': 'clusterAdmin', 'db': 'admin'},                                                 
... {'role': 'dbAdminAnyDatabase', 'db': 'admin'},                                           
... {'role': 'readWriteAnyDatabase', 'db': 'admin'}                                          
... ]})
{ "ok" : 1 }
> 
bye

mongoc_run () {
	filename=$1 
	executable=`basename $filename .c` 
	gcc -o $executable $filename -Isrc/libbson/src/bson -Isrc/mongoc/ -L./.libs -lmongoc-1.0 -L./src/libbson/.libs -lbson-1.0
	LD_LIBRARY_PATH=.libs/:src/libbson/.libs ./$executable
}

mongoc_run bypass.c

Sprint: Sharding D (12/11/15)
Participants:

 Description   

I can consistently reproduce the following:

$ mongod --version
db version v3.2.0-rc3-89-g3a8aab6
git version: 3a8aab65a494f6e5b31ea0358a517b103e1cbcb6

-bash-4.2$ rm -rf /data/db/*
-bash-4.2$ mongod -vvvv --smallfiles --logpath=/data/db/mongod.log --auth --dbpath=/data/db --fork
about to fork child process, waiting until server is ready for connections.
forked process: 20505
child process started successfully, parent exiting

-bash-4.2$ mongo
MongoDB shell version: 3.2.0-rc3-89-g3a8aab6
connecting to: test
> use admin
switched to db admin
> db.runCommand({createUser: "example", "pwd": "password", roles: [                    
... {'role': 'userAdminAnyDatabase', 'db': 'admin'},                                         
... {'role': 'clusterAdmin', 'db': 'admin'},                                                 
... {'role': 'dbAdminAnyDatabase', 'db': 'admin'},                                           
... {'role': 'readWriteAnyDatabase', 'db': 'admin'}                                          
... ]})
{ "ok" : 1 }
> 
bye

Then. Using the latest master of mongo-c-driver:

  • Create new client using "mongodb://example:password@localhost:27017/admin"
  • Create a schema validator: {"validator": {"number": {"$gte": 5, "validationAction": "error"}}}
  • Bulk insert 3 document that fail the validation, and get "Document failed validation" error back
  • Bulk insert 3 documents that fail the validation, passing bypassDocumentValidation: true

Now, what happens depends on the following:

  • If I have an active shell session logged in with the same username and password, the bypassDocumentValidation succeeds
  • If I have no active shell session the bypassDocumentValidation fails with authentication error.

"bypass.c"

#include <bcon.h>
#include <mongoc.h>
 
int main(void)
{
   mongoc_collection_t *collection;
   bson_t reply = BSON_INITIALIZER;
   mongoc_bulk_operation_t *bulk;
   mongoc_database_t *database;
   mongoc_write_concern_t *wr;
   mongoc_client_t *client;
   bson_error_t error;
   bson_t *options;
   int r;
   int i;
 
   client = mongoc_client_new ("mongodb://example:password@localhost:27017/admin");
 
   database = mongoc_client_get_database (client, "databaseName");
   collection = mongoc_database_get_collection (database, "collectionName");
   mongoc_collection_drop (collection, NULL);
 
   options = bson_new_from_json ("{\"validator\": {\"number\": {\"$gte\": 5}}, \"validationAction\": \"error\"}", -1, NULL);
   if (!mongoc_database_create_collection (database, "collectionName", options, &error)) {
      fprintf(stderr, "Got error %s on line %d\n", error.message, __LINE__);
      fprintf(stderr, "\nFAILED\n");
      return 1;
   }
 
   /* {{{ Default fails validation */
   bulk = mongoc_collection_create_bulk_operation (collection, true, NULL);
   for (i = 0; i < 3; i++) {
      bson_t *doc = bson_new_from_json ("{\"number\": 3 }", -1, NULL);
      mongoc_bulk_operation_insert (bulk, doc);
      bson_destroy (doc);
   }
   r = mongoc_bulk_operation_execute (bulk, &reply, &error);
   if (r) {
      fprintf(stderr, "Should have got error line %d\n", __LINE__);
      fprintf(stderr, "\nFAILED\n");
      return 1;
   } else {
      fprintf(stdout, "Correctly failed validation (%s) on line %d\n", error.message, __LINE__);
   }
   mongoc_bulk_operation_destroy (bulk);
   /* }}} */
 
   /* {{{ bypass_document_validation=true ignores validation */
   bulk = mongoc_collection_create_bulk_operation (collection, true, NULL);
   mongoc_bulk_operation_set_bypass_document_validation (bulk, true);
   for (i = 0; i < 3; i++) {
      bson_t *doc = bson_new_from_json ("{\"number\": 3 }", -1, NULL);
      mongoc_bulk_operation_insert (bulk, doc);
      bson_destroy (doc);
   }
   r = mongoc_bulk_operation_execute (bulk, &reply, &error);
   if (r) {
      fprintf(stdout, "Correctly bypassed document validation on line %d\n", __LINE__);
   } else {
      fprintf(stderr, "Got error %s on line %d\n", error.message, __LINE__);
      fprintf(stderr, "\nFAILED\n");
      return 1;
   }
   mongoc_bulk_operation_destroy (bulk);
   /* }}} */
 
   bson_destroy (options);
   mongoc_database_destroy (database);
   mongoc_collection_destroy (collection);
   mongoc_client_destroy (client);
}


EDIT: This was originally noticed on Solaris spawnhost that had nightly deployed on it. It was later confirmed on Linux too.



 Comments   
Comment by Githook User [ 30/Nov/15 ]

Author:

{u'username': u'stbrody', u'name': u'Spencer T Brody', u'email': u'spencer@mongodb.com'}

Message: SERVER-21659 Move logic for redacting 'bypassDocumentValidation' privilege for backwards compatibility up to the usersInfo command
Branch: master
https://github.com/mongodb/mongo/commit/16b5070833b20c73f87fc37df1f6a21afca825ba

Comment by Githook User [ 25/Nov/15 ]

Author:

{u'username': u'ajdavis', u'name': u'A. Jesse Jiryu Davis', u'email': u'jesse@mongodb.com'}

Message: skip bypassValidation test with auth

Until SERVER-21659 is fixed in MongoDB 3.2 GA.
Branch: master
https://github.com/mongodb/mongo-c-driver/commit/94915175b364418284880952cfe0926344997334

Comment by Andy Schwerin [ 25/Nov/15 ]

I'll bet it's this commit, which was intended to fix compatibility between 3.0 mongos and 3.2 mongod during upgrade. I believe the problem is that it conflates the use of AuthzManagerExternalStateLocal::getUserDescription for fetching a user description to transmit to mongos and the use of the same function to identify the privileges of a local connection.

The reason that having the shell open changes behavior is that the shell authenticates using OP_COMMAND commands, which is the signal mongod is using to detect a 3.2 mongos. The user document is then cached, and so can be used by other (OP_QUERY command) connections.

Anyhow, the problem is limited to document validation bypass, and only restricts privilege unnecessarily (does not escalate privileges in error). We can figure out a fix in time for 3.2.0.

Comment by Hannes Magnusson [ 24/Nov/15 ]

spencer

test.sh

RET=0
scons -j24 --disable-warnings-as-errors mongod mongo mongos
rm -rf /data/db/*
./mongod -vvvv --smallfiles --logpath=/data/db/mongod.log --auth --dbpath=/data/db --fork
./mongo --eval '
db.runCommand({createUser: "example", "pwd": "password", roles: [                    
    {"role": "userAdminAnyDatabase", "db": "admin"},                                         
    {"role": "clusterAdmin", "db": "admin"},                                                 
    {"role": "dbAdminAnyDatabase", "db": "admin"},                                           
    {"role": "readWriteAnyDatabase", "db": "admin"}                                          
 ]})' admin
LD_LIBRARY_PATH=$HOME/Sources/mongo-c-driver/.libs/:$HOME/Sources/mongo-c-driver/src/libbson/.libs ~/Sources/mongo-c-driver/bypass
RET=$?
killall mongod
rm -rf /data/db/*
exit $RET

874fc812768718f015e81d6ce7bd2dab9ce14128 is the first bad commit
commit 874fc812768718f015e81d6ce7bd2dab9ce14128
Author: Spencer T Brody <spencer@mongodb.com>
Date:   Wed Nov 18 17:07:50 2015 -0500
 
    SERVER-21486 Redact bypassDocumentValidation from user privilege set when being talked to by a 3.0 mongos
 
:040000 040000 3bf3951999deaf1bd54ccbfc7af6aba0deb8228a e60ef78d717e72067fa9076e1273be5176e4fc8c M	src
bisect run success
git bisect run ./test.sh  16091.44s user 1208.76s system 1713% cpu 16:49.71 total

https://github.com/mongodb/mongo/commit/874fc812768718f015e81d6ce7bd2dab9ce14128

Comment by Hannes Magnusson [ 24/Nov/15 ]

I have reproduced this locally now!

EDIT: I fail at reading the download page.

RC3 is NOT affected.

The current nightly available on https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1404-latest.tgz IS AFFECTED

Comment by A. Jesse Jiryu Davis [ 24/Nov/15 ]

Yes, I just now see it here too:

https://evergreen.mongodb.com/task/mongo_c_driver_ubuntu_1404_64_integration_test_latest_replica_set_e8ac5e3447e4737dfec249eb5b8b8540707386d4_15_11_24_20_56_36

Comment by Hannes Magnusson [ 24/Nov/15 ]

I cannot reproduce this locally, but double checking evergreen it does appear to be failing on Ubuntu 12 and Ubuntu 15 too.
So its very likely not Solaris only problem.

See: https://evergreen.mongodb.com/version/mongo_c_driver_e8ac5e3447e4737dfec249eb5b8b8540707386d4

Comment by Andy Schwerin [ 24/Nov/15 ]

Can you reproduce this on other OSes?

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