[SERVER-12223] cleanupOrphaned command grants authentication of internal __system user to current connection Created: 31/Dec/13  Updated: 11/Jul/16  Resolved: 09/Jan/14

Status: Closed
Project: Core Server
Component/s: Security, Sharding
Affects Version/s: 2.5.4
Fix Version/s: 2.5.5

Type: Bug Priority: Critical - P2
Reporter: Kamran K. Assignee: Randolph Tan
Resolution: Done Votes: 0
Labels: 26qa
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
Operating System: ALL
Steps To Reproduce:

function assertUnauthorized(res){
    if (res.ok == 0 && res.errmsg.startsWith('not authorized'))
        return;
 
    var finalMsg = "command worked when it should have been unauthorized: " + tojson(res);
    doassert(finalMsg);
}
 
var st = new ShardingTest({
    auth: true,
    keyFile: 'jstests/libs/key1'
});
 
st.stopBalancer();
 
var mongos = st.s0;
var mongosAdmin = mongos.getDB('admin');
var coll = mongos.getCollection('foo.bar');
 
assert.commandWorked(mongosAdmin.runCommand({
    enableSharding: coll.getDB().getName()
}));
 
assert.commandWorked(mongosAdmin.runCommand({
    shardCollection: coll.getFullName(),
    key: {_id: 'hashed'}
}));
 
 
var shardAdmin = st.shard0.getDB('admin');
shardAdmin.createUser({'user':'admin', 'pwd': 'x', 'roles': ['clusterAdmin']});
 
// the first attempt fails as expected
assertUnauthorized(shardAdmin.runCommand({cleanupOrphaned: 'foo.bar'}));
 
// authenticate
shardAdmin.auth('admin', 'x');
 
printjson(shardAdmin.runCommand('connectionStatus')); // Shows you are auth'd as admin@admin
 
// the second attempt succeeds after authenticating (as expected)
assert.commandWorked(shardAdmin.runCommand({cleanupOrphaned: 'foo.bar'}));
 
printjson(shardAdmin.runCommand('connectionStatus')); // Shows you are auth'd as admin@admin AND __system@local
 
// logging out seems to succeed
assert.commandWorked(shardAdmin.logout());
 
printjson(shardAdmin.runCommand('connectionStatus')); // Shows you are auth'd as __system@local
 
// the third attempt does not fail after logging out (hence the assertion failure)
assertUnauthorized(shardAdmin.runCommand({cleanupOrphaned: 'foo.bar'}));

Participants:

 Description   

The cleanupOrphaned command calls into RangeDeleterDBEnv::deleteRange, which calls cc().getAuthorizationSession()->grantInternalAuthorization().

This means that anyone with permission to run cleanupOrphaned can get privilege escalation because all they need to do is run cleanupOrphaned and now they are authenticated as the internal user, with full access to the system.



 Comments   
Comment by Githook User [ 09/Jan/14 ]

Author:

{u'username': u'renctan', u'name': u'Randolph Tan', u'email': u'randolph@10gen.com'}

Message: SERVER-12223 cleanupOrphaned command grants authentication of internal __system user to current conn
Branch: master
https://github.com/mongodb/mongo/commit/c8faa8a1bcb4f9eb9ad7d320b9fa720264fed115

Comment by Spencer Brody (Inactive) [ 02/Jan/14 ]

I believe you should be able to just remove the call to grantInternalAuthorization() from RangeDeleterDBEnv::deleteRange. Since it looks like that code just uses "Helpers" methods to access the data files, and those bypass the auth system entirely, the cleanupOrphaned command should continue to work even without the internal authorization.

Comment by Kamran K. [ 02/Jan/14 ]

Here's the output of shardAdmin.runCommand({connectionStatus: 1}) after shardAdmin.logout() is called:

{
	"authInfo" : {
		"authenticatedUsers" : [
			{
				"user" : "__system",
				"db" : "local"
			}
		]
	},
	"ok" : 1
}

Comment by Spencer Brody (Inactive) [ 02/Jan/14 ]

Hmm... Can you try printing the output of the connectionStatus command after you log out to make sure you're not still authenticated as any users?

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