ExportXMLWordPrintableJSON

    • Type: Bug
    • Resolution: Fixed
    • Priority: Major - P3
    • 9.0.7
    • Affects Version/s: None
    • Component/s: None
    • None
    • DB Integration & Observability
    • Fully Compatible
    • ALL
    • v9.0
    • Hide
      const conn = MongoRunner.runMongod({auth: ""});
      const admin = conn.getDB("admin");
      admin.createUser({user: "root", pwd: "pwd", roles: ["root"]});
      assert(admin.auth("root", "pwd"));
      admin.createUser({user: "rw", pwd: "pwd", roles: ["readWriteAnyDatabase"]});
      admin.logout();
      
      assert(admin.auth("rw", "pwd"));
      assert.commandFailedWithCode(admin.runCommand({find: "system.users"}), ErrorCodes.Unauthorized);
      assert.commandWorked(admin.anchor.insert({_id: 1}));
      
      const res = admin.runCommand({
          create: "leak",
          viewOn: "anchor",
          pipeline: [
              {
                  $graphLookup: {
                      from: "anchor",
                      startWith: "$_id",
                      connectFromField: "_id",
                      connectToField: "_id",
                      as: "g",
                      $_internalFromPipeline: [{$lookup: {from: "system.users", pipeline: [], as: "users"}}],
                  },
              },
          ],
      });
      if (res.ok) {
          const leaked = admin.leak.findOne().g[0].users;
          assert.eq(leaked, [], "view leaked admin.system.users: " + tojson(leaked));
      }
      assert.commandFailedWithCode(res, [ErrorCodes.Unauthorized, 5491300]);
      
      MongoRunner.stopMongod(conn, null, {user: "root", pwd: "pwd"});
      

       

      Show
      const conn = MongoRunner.runMongod({auth: ""}); const admin = conn.getDB( "admin" ); admin.createUser({user: "root" , pwd: "pwd" , roles: [ "root" ]}); assert (admin.auth( "root" , "pwd" )); admin.createUser({user: "rw" , pwd: "pwd" , roles: [ "readWriteAnyDatabase" ]}); admin.logout(); assert (admin.auth( "rw" , "pwd" )); assert .commandFailedWithCode(admin.runCommand({find: "system.users" }), ErrorCodes.Unauthorized); assert .commandWorked(admin.anchor.insert({_id: 1})); const res = admin.runCommand({ create: "leak" , viewOn: "anchor" , pipeline: [ { $graphLookup: { from: "anchor" , startWith: "$_id" , connectFromField: "_id" , connectToField: "_id" , as: "g" , $_internalFromPipeline: [{$lookup: {from: "system.users" , pipeline: [], as: "users" }}], }, }, ], }); if (res.ok) { const leaked = admin.leak.findOne().g[0].users; assert .eq(leaked, [], "view leaked admin.system.users: " + tojson(leaked)); } assert .commandFailedWithCode(res, [ErrorCodes.Unauthorized, 5491300]); MongoRunner.stopMongod(conn, null , {user: "root" , pwd: "pwd" });  
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      That field is only allowed by internal clients, it should not be allowed in view definitions. The fact that it's allowed in view definitions can be abused to read collections that the user is not authorized to read. 

            Assignee:
            Finley Lau
            Reporter:
            Henri Nikku
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: