[SERVER-15181] Granting a user "insert", but not "createCollection" does not prevent them from creating collections Created: 09/Sep/14  Updated: 07/Apr/22  Resolved: 12/Sep/14

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

Type: Bug Priority: Major - P3
Reporter: Victor Hooi Assignee: Ramon Fernandez Marina
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

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

> use test
switched to db test
> db.createRole({ role: "insertonly", privileges: [ {resource: {db: "test", collection: ""}, actions: [ "insert"]}], roles: []})
{
        "role" : "insertonly",
        "privileges" : [
                {
                        "resource" : {
                                "db" : "test",
                                "collection" : ""
                        },
                        "actions" : [
                                "insert"
                        ]
                }
        ],
        "roles" : [ ]
}
> db.createUser({"user": "foo", "pwd": "password", "roles": [ {role: "insertonly", db: "test"}]})
Successfully added user: {
        "user" : "foo",
        "roles" : [
                {
                        "role" : "insertonly",
                        "db" : "test"
                }
        ]
}

victorhooi@oswin-rmbp ~> mongo -u foo -p password test
MongoDB shell version: 2.6.3
connecting to: test
> use test
switched to db test
> db.thisisanewcollection.insert({name: "ernie", type: "cat"})
WriteResult({ "nInserted" : 1 })
> db.createCollection("secondnewcollection")
{ "ok" : 1 }

> show collections
secondnewcollection
system.indexes
thisisanewcollection

Participants:
Case:

 Description   

I created a new user role that only had the "insert" privilege.

> use test
switched to db test
> db.createRole({ role: "insertonly", privileges: [ {resource: {db: "test", collection: ""}, actions: [ "insert"]}], roles: []})
{
        "role" : "insertonly",
        "privileges" : [
                {
                        "resource" : {
                                "db" : "test",
                                "collection" : ""
                        },
                        "actions" : [
                                "insert"
                        ]
                }
        ],
        "roles" : [ ]
}

I then added a new user that only had this role:

> db.createUser({"user": "foo", "pwd": "password", "roles": [ {role: "insertonly", db: "test"}]})
Successfully added user: {
        "user" : "foo",
        "roles" : [
                {
                        "role" : "insertonly",
                        "db" : "test"
                }
        ]
}

I then list the collections in test:

> show collections

I then authenticate as this user in a new mongo shell. I am able to create a new collection implicitly, by adding to an empty collection:

> use test
switched to db test
> db.thisisanewcollection.insert({name: "ernie", type: "cat"})
WriteResult({ "nInserted" : 1 })

I am also able to create a new collection explicitly, by calling db.createCollection():

> db.createCollection("secondnewcollection")
{ "ok" : 1 }

I can verify both of these collection are there by running show collections (as the admin user):

> show collections
secondnewcollection
system.indexes
thisisanewcollection

So there are two issues here - a user possessing only the "insert" privilege is able to:

  1. Create collections implicitly by adding to a non-existent collection
  2. Create collections explicitly by calling db.createCollection().

I believe 2. is a definite buggy behaviour.

For 1., this may or may not be against intentions (based on the comment at https://github.com/mongodb/mongo/blob/266b75ca868a95fd2a4e30e3cf4898de1e13698d/src/mongo/db/dbcommands.cpp#L525). However, if it is intended, it it not made clear in the documentation, and also, we should raise a new SERVER ticket to add this functionality in - that is, it is certainly desirable to be have a way of preventing users from creating new collections at will.



 Comments   
Comment by Spencer Brody (Inactive) [ 10/Sep/14 ]

From a security standpoint there's no difference between being able to create a collection with an insert command or a createCollection command, the result is the same, so I feel like if users with "insert" can create a collection implicitly they should be able to create it explicitly as well. There are additional privileges needed by the createCollection command to create a collection with non-default options. For example you need "convertToCapped" to create a capped collection with createCollection.

Comment by Ramon Fernandez Marina [ 09/Sep/14 ]

victor.hooi, implicit collection creation on insert() is the expected behavior. In order to prevent users create new collections one needs to remove insert privileges for the whole database (the insertonly role in your example) and then grant insert privileges in specific collections:

db.createRole({ role: "insert_col_1", privileges: [ {resource: {db: "test", collection: "col_1"}, actions: [ "insert"]}], roles: []})
db.createUser({"user": "alice", "pwd": "password", "roles": [ {role: "insert_col_1", db: "test"}]})

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