[SERVER-19284] Should not be able to create role with same name as builtin role Created: 06/Jul/15  Updated: 05/Feb/16  Resolved: 14/Aug/15

Status: Closed
Project: Core Server
Component/s: Security
Affects Version/s: None
Fix Version/s: 2.6.12, 3.0.7, 3.1.7

Type: Bug Priority: Major - P3
Reporter: Kevin Pulo Assignee: Merry Mou
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: File createBuiltinRole.js    
Backwards Compatibility: Fully Compatible
Operating System: ALL
Backport Completed:
Sprint: Security 6 07/17/15, Security 7 08/10/15, Security 8 08/28/15
Participants:

 Description   
  1. createRole does not reject user-defined roles that have the same name as a builtin role. An entry gets written into admin.system.roles, but doesn't show up in the output of "show roles".
  2. Similarly, the updateRole will update this entry.
  3. dropRole won't remove it.

The workaround is to manually remove the entry from admin.system.roles (which requires sufficient privs to be granted to do that).

> db
admin
> db.version()
3.1.5
> 
> 
> 
> db.system.roles.find()
> show roles
{
        "role" : "__system",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "backup",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "clusterAdmin",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "clusterManager",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "clusterMonitor",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "dbAdmin",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "dbAdminAnyDatabase",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "dbOwner",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "hostManager",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "read",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "readAnyDatabase",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "readWrite",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "readWriteAnyDatabase",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "restore",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "root",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "userAdmin",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "userAdminAnyDatabase",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
> db.createRole({role: "readWrite", roles: [], privileges: []})
{ "role" : "readWrite", "roles" : [ ], "privileges" : [ ] }
> 
> 
> 
> 
> db.system.roles.find()
{ "_id" : "admin.readWrite", "role" : "readWrite", "db" : "admin", "privileges" : [ ], "roles" : [ ] }
> show roles
{
        "role" : "__system",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "backup",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "clusterAdmin",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "clusterManager",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "clusterMonitor",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "dbAdmin",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "dbAdminAnyDatabase",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "dbOwner",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "hostManager",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "read",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "readAnyDatabase",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "readWrite",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "readWriteAnyDatabase",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "restore",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "root",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "userAdmin",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "userAdminAnyDatabase",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
> 
> 
> 
> 
> db.updateRole("readWrite", {roles: [{role:"root", db:"admin"}]})
> db.system.roles.find()
{ "_id" : "admin.readWrite", "role" : "readWrite", "db" : "admin", "privileges" : [ ], "roles" : [ { "role" : "root", "db" : "admin" } ] }
> show roles
{
        "role" : "__system",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "backup",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "clusterAdmin",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "clusterManager",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "clusterMonitor",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "dbAdmin",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "dbAdminAnyDatabase",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "dbOwner",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "hostManager",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "read",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "readAnyDatabase",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "readWrite",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "readWriteAnyDatabase",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "restore",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "root",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "userAdmin",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "userAdminAnyDatabase",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
> 
> 
> 
> 
> 
> db.dropRole("readWrite")
2015-07-06T13:28:13.292+1000 E QUERY    [main] Error: readWrite@admin is a built-in role and cannot be modified.
    at Error (<anonymous>)
    at DB.dropRole (src/mongo/shell/db.js:1498:11)
    at (shell):1:4 at src/mongo/shell/db.js:1498
> db.system.roles.find()
{ "_id" : "admin.readWrite", "role" : "readWrite", "db" : "admin", "privileges" : [ ], "roles" : [ { "role" : "root", "db" : "admin" } ] }
> db.system.roles.remove({_id:"admin.readWrite"})
WriteResult({
        "writeError" : {
                "code" : 13,
                "errmsg" : "not authorized on admin to execute command { delete: \"system.roles\", deletes: [ { q: {}, limit: 0.0 } ], ordered: true }"
        }
})
> 
> 
> 
> 
> 
> db.createRole({role:"foo",roles:[], privileges:[{resource:{db:"admin",collection:"system.roles"}, actions:["remove"]}]})
{
        "role" : "foo",
        "roles" : [ ],
        "privileges" : [
                {
                        "resource" : {
                                "db" : "admin",
                                "collection" : "system.roles"
                        },
                        "actions" : [
                                "remove"
                        ]
                }
        ]
}
> db.grantRolesToUser("user", ["foo"])
> db.system.roles.remove({_id:"admin.readWrite"})
WriteResult({ "nRemoved" : 1 })
> db.system.roles.find()
{ "_id" : "admin.foo", "role" : "foo", "db" : "admin", "privileges" : [ { "resource" : { "db" : "admin", "collection" : "system.roles" }, "actions" : [ "remove" ] } ], "roles" : [ ] }
> show roles
{
        "role" : "__system",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "backup",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "clusterAdmin",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "clusterManager",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "clusterMonitor",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "dbAdmin",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "dbAdminAnyDatabase",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "dbOwner",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "foo",
        "db" : "admin",
        "isBuiltin" : false,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "hostManager",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "read",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "readAnyDatabase",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "readWrite",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "readWriteAnyDatabase",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "restore",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "root",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "userAdmin",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}
{
        "role" : "userAdminAnyDatabase",
        "db" : "admin",
        "isBuiltin" : true,
        "roles" : [ ],
        "inheritedRoles" : [ ]
}



 Comments   
Comment by Githook User [ 31/Aug/15 ]

Author:

{u'name': u'Merry Mou', u'email': u'merry.mou@mongodb.com'}

Message: SERVER-19284 Do not allow creation of roles with same names as builtin roles.
Branch: v3.0
https://github.com/mongodb/mongo/commit/d73eca8899d4747ebe0ff843401970c8b3c8d14e

Comment by Githook User [ 13/Aug/15 ]

Author:

{u'name': u'Merry Mou', u'email': u'merry.mou@mongodb.com'}

Message: SERVER-19284 Do not allow creation of roles with same names as builtin roles.
Branch: v2.6
https://github.com/mongodb/mongo/commit/4781c5ab81d3da420ff6f5c77da1e18e46d8deaf

Comment by Githook User [ 12/Aug/15 ]

Author:

{u'name': u'Merry Mou', u'email': u'merry.mou@mongodb.com'}

Message: SERVER-19284 Do not allow creation of roles with same names as builtin roles.
Branch: master
https://github.com/mongodb/mongo/commit/427643ee859b739e39427ccf2b54536cb22b1182

Comment by Kevin Pulo [ 07/Jul/15 ]

Looks like it's never worked. A simple jstest is now attached — the fix should probably include adding it to the auth suite.

$ mongo --eval 'print(db.version())' createBuiltinRole.js
MongoDB shell version: 2.6.10
connecting to: test
2.6.10
assert: command worked when it should have failed: { "ok" : 1 } : { "createRole" : "readWrite", "roles" : [ ], "privileges" : [ ] }
Error: command worked when it should have failed: { "ok" : 1 } : { "createRole" : "readWrite", "roles" : [ ], "privileges" : [ ] }
    at Error (<anonymous>)
    at doassert (src/mongo/shell/assert.js:11:14)
    at Function.assert.commandFailed (src/mongo/shell/assert.js:252:5)
    at createBuiltinRole.js:16:8
    at createBuiltinRole.js:20:3
2015-07-07T14:25:09.238+1000 Error: command worked when it should have failed: { "ok" : 1 } : { "createRole" : "readWrite", "roles" : [ ], "privileges" : [ ] } at src/mongo/shell/assert.js:13
failed to load: createBuiltinRole.js

$ mlaunch init --single --port 19284 --binarypath /sw/mongodb/3.0.4/bin
launching: /sw/mongodb/3.0.4/bin/mongod on port 19284
$ mongo --port 19284 --eval 'print(db.version())' createBuiltinRole.js
MongoDB shell version: 2.6.10
connecting to: 127.0.0.1:19284/test
3.0.4
assert: command worked when it should have failed: { "ok" : 1 } : { "createRole" : "readWrite", "roles" : [ ], "privileges" : [ ] }
Error: command worked when it should have failed: { "ok" : 1 } : { "createRole" : "readWrite", "roles" : [ ], "privileges" : [ ] }
    at Error (<anonymous>)
    at doassert (src/mongo/shell/assert.js:11:14)
    at Function.assert.commandFailed (src/mongo/shell/assert.js:252:5)
    at createBuiltinRole.js:16:8
    at createBuiltinRole.js:20:3
2015-07-07T14:25:18.311+1000 Error: command worked when it should have failed: { "ok" : 1 } : { "createRole" : "readWrite", "roles" : [ ], "privileges" : [ ] } at src/mongo/shell/assert.js:13
failed to load: createBuiltinRole.js

Comment by Andy Schwerin [ 06/Jul/15 ]

kevin.pulo@10gen.com, is this a regression or do the 2.6 and 3.0 branches suffer the same behavior? The intention was always to prohibit creating roles that have the same name as other existing roles, either built-in or user-defined.

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