[SERVER-26577] Permissions are different for listCollections and listCollections getmore Created: 11/Oct/16  Updated: 06/Dec/17  Resolved: 28/Apr/17

Status: Closed
Project: Core Server
Component/s: Querying
Affects Version/s: 3.0.12, 3.2.10, 3.4.0-rc0
Fix Version/s: 3.5.7

Type: Bug Priority: Major - P3
Reporter: Andrew Young Assignee: Justin Seyster
Resolution: Done Votes: 0
Labels: neweng
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Backwards Compatibility: Fully Compatible
Operating System: ALL
Steps To Reproduce:

1. Create a user who lacks the 'listCollections' permission but does have the read permission on the system.namespaces collection.
2. Call the listCollections command with a batchSize of 0 as this user.
3. Call getmore on the returned cursor as the same user.

Sprint: Query 2017-05-08
Participants:

 Description   

A call to listCollections that does not define a batchSize will generally return all collections in a single batch. This call requires either the listCollections permission or the read permission on the system.namespaces collection. However, if you call listCollections with a batchSize of 0 and then try to call getmore on the cursor that is returned, the getmore call does not take the system.namespaces permission into account. This results in cases where a user can call the listCollections action successfully but can not call getmore on the returned cursor. Some drivers, such as the Java driver, specifically send a batchSize of 0 when making this call, which can cause this problem to manifest itself.



 Comments   
Comment by Githook User [ 28/Apr/17 ]

Author:

{u'username': u'jseyster', u'name': u'Justin Seyster', u'email': u'justin.seyster@mongodb.com'}

Message: SERVER-26577 Fix permissions for listCollections getMore.

Squashed commit of the following:

commit 11c363b941e99fc288c4f9a19cb807442fb09d44
Author: Justin Seyster <justin.seyster@mongodb.com>
Date: Fri Apr 21 17:59:23 2017 -0400

SERVER-26577 JS test for listCollections_getMore authorization

commit fa3e01205995ad4fd139e3d4fe77c407c2409aa0
Author: Justin Seyster <justin.seyster@mongodb.com>
Date: Thu Apr 20 15:10:49 2017 -0400

SERVER-26577 Unit tests for isAuthorizedToListCollections

commit 53cea2802850f221b492e5469d8da659bd1f6694
Author: Justin Seyster <justin.seyster@mongodb.com>
Date: Wed Apr 19 17:16:51 2017 -0400

SERVER-26577 Permissions checks for listCollections go to one function
Branch: master
https://github.com/mongodb/mongo/commit/4f1db7deaacfe76a2916c2c6b259191c491df2d4

Comment by Andrew Young [ 11/Oct/16 ]

The same issue exists for killCursors.

From db/auth/authorization_session.cpp, line 405, AuthorizationSession::checkAuthForKillCursors():

    if (ns.isListCollectionsCursorNS()) {
        if (!(isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName(ns.db()),
                                               ActionType::killCursors) ||
              isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName(ns.db()),
                                               ActionType::listCollections))) {
            return Status(ErrorCodes::Unauthorized,
                          str::stream() << "not authorized to kill listCollections cursor on "
                                        << ns.ns());
        }

Comment by Andrew Young [ 11/Oct/16 ]

From db/commands/list_collections.cpp, line 197, CmdListCollections::checkAuthForCommand():

        // Check for the listCollections ActionType on the database
        // or find on system.namespaces for pre 3.0 systems.
        if (authzSession->isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName(dbname),
                                                           ActionType::listCollections) ||
            authzSession->isAuthorizedForActionsOnResource(
                ResourcePattern::forExactNamespace(NamespaceString(dbname, "system.namespaces")),
                ActionType::find)) {
            return Status::OK();
        }

From db/auth/authorization_session.cpp, line 296, AuthorizationSession::checkAuthForGetMore():

    if (ns.isListCollectionsCursorNS()) {
        // "ns" is of the form "<db>.$cmd.listCollections".  Check if we can perform the
        // listCollections action on the database resource for "<db>".
        if (!isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName(ns.db()),
                                              ActionType::listCollections)) {
            return Status(ErrorCodes::Unauthorized,
                          str::stream() << "not authorized for listCollections getMore on "
                                        << ns.ns());
        }

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