SoftInstigate / restheart

Rapid API Development with MongoDB
https://restheart.org
GNU Affero General Public License v3.0
805 stars 171 forks source link

can't access any collection unless user has listDatabases permission #36

Closed O1O1O1O closed 9 years ago

O1O1O1O commented 9 years ago

I'm trying to use Restheart against a database for which my user does not have listDatabases permission (as a security precaution). Even if I access GET /dbname/collection Restheart still tries to get database properties which in turn asks if the database exists.

                   "com.mongodb.CommandFailureException: { \"serverUsed\" : \"xxxxxxxx\" , \"ok\" : 0.0 , \"errmsg\" : \"not authorized on admin to execute command { listDatabases: 1 }\" , \"code\" : 13}", 
                "  at com.mongodb.CommandResult.getException(CommandResult.java:76)", 
                "  at com.mongodb.CommandResult.throwOnError(CommandResult.java:140)", 
                "  at com.mongodb.Mongo.getDatabaseNames(Mongo.java:374)", 
                "  at org.restheart.db.DbsDAO.existsDatabaseWithName(DbsDAO.java:100)", 
                "  at org.restheart.db.DbsDAO.getDatabaseProperties(DbsDAO.java:149)", 

Maybe there could be an option to lock Restheart into a specific database and have it skip the existence check?

Then again looking at the code it looks like Restheart also needs write access to add a _properties collection to each database so perhaps this is a moot point if you also have read only access only such as a read only replica.

ujibang commented 9 years ago

I confirm you that RESTHeart requires listDatabases permission.

However a strong security isolation can be achieved via mongo-mounts configuration option.

For instance, the following configuration only exposes the two databases db1 and db2 and the collection db3.coll (note that you can also bind the resources to a custom URL, in this case under the /api prefix)

# Use mongo-mounts to bind URls to mongodb resources using the out-of-the-box URL rewrite feature.
mongo-mounts:
    - what: "/db1"
      where: /api/db1
    - what: "/db2"
      where: /api/db2
    - what: "/db3/coll"
      where: /api/db3/coll

The suggested mongodb user roles are readWrite and dbAdmin on the databases and bakcup on admin, as follows:

db.createUser({user: "mongousr",
               pwd: "secret",
               roles: [ {role: "readWrite", db: "db1"},
                           {role: "dbAdmin", db: "db1"},
                           {role: "readWrite", db: "db2"},
                           {role: "dbAdmin", db: "db2"},
                           {role: "readWrite", db: "db3"},
                           {role: "dbAdmin", db: "db3"},
                           {role: "backup", db: "admin"}]})

Note that the backup roles includes the listDatabases permission (that provides minimal privileges needed for backing up data; reference: http://docs.mongodb.org/manual/reference/built-in-roles/#backup-and-restoration-roles).

Regarding the write permission on the _properties collection: when RESTHeart accesses a dababase (that might not be created by it), it creates it eventually (this also occurs on server startup). If you isolate the exposes resources, there is no need to have write permission on other databases.

ujibang commented 8 years ago

@O1O1O1O for your information the latest release 1.1.0 allows to connect with mongodb using just read or readWrite roles.

the dbAdmin role and listDatabases permission are no longer needed!

more info at http://www.softinstigate.com/blog/2015/12/08/what-is-new-in-RESTHeart-1.1.0/