Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-32640

killCursors auditing messages are duplicated or incomplete

    • Minor Change
    • ALL
    • Security 2021-02-22, Security 2021-03-08

      Run a mongod with auditing on:
      mongod --auditDestination console --setParameter auditAuthorizationSuccess=true

      Then start up a shell and insert some data:

          db.audit.drop()
          for (var i = 0; i < 100; i++) {
              assert.writeOK(db.audit.insert({_id: i}));
          }
      
          let query;
          let cursorId;
      

      Then, run a find() command and then kill the cursor associated with it:

          query = db.audit.find().batchSize(1);
          cursorId = query._cursor._cursorid;
          assert.neq(cursorId, NumberLong(0));
      
          cmdRes = db.runCommand({killCursors: db.audit.getName(), cursors: [cursorId]});
      

      You will see three audit messages:

      { "atype" : "authCheck", "ts" : { "$date" : "2018-01-10T12:23:53.675-0500" }, "local" : { "ip" : "127.0.0.1", "port" : 30000 }, "remote" : { "ip" : "127.0.0.1", "port" : 46976 }, "users" : [], "roles" : [], "param" : { "command" : "killCursors", "ns" : "test.audit", "args" : { "killCursors" : "audit", "cursors" : [ { "$numberLong" : "18214762657" } ], "$db" : "test" } }, "result" : 0 }
      { "atype" : "authCheck", "ts" : { "$date" : "2018-01-10T12:23:53.675-0500" }, "local" : { "ip" : "127.0.0.1", "port" : 30000 }, "remote" : { "ip" : "127.0.0.1", "port" : 46976 }, "users" : [], "roles" : [], "param" : { "command" : "killCursors", "ns" : "test.audit", "args" : { "killCursors" : "audit", "cursorId" : { "$numberLong" : "18214762657" } } }, "result" : 0 }
      { "atype" : "authCheck", "ts" : { "$date" : "2018-01-10T12:23:53.676-0500" }, "local" : { "ip" : "127.0.0.1", "port" : 30000 }, "remote" : { "ip" : "127.0.0.1", "port" : 46976 }, "users" : [], "roles" : [], "param" : { "command" : "killCursors", "ns" : "test.audit", "args" : { "killCursors" : "audit", "cursorId" : { "$numberLong" : "18214762657" } } }, "result" : 0 }
      

      Now try it with aggregate():

          query = db.audit.aggregate([{$limit: 500}], {cursor: {batchSize: 1}})
          cursorId = query._cursorid;
          assert.neq(cursorId, NumberLong(0));
      
          cmdRes = db.runCommand({killCursors: db.audit.getName(), cursors: [cursorId]});
      

      You will again see three messages. However, the ns field of the second message is empty!

      { "atype" : "authCheck", "ts" : { "$date" : "2018-01-10T12:22:08.695-0500" }, "local" : { "ip" : "127.0.0.1", "port" : 30000 }, "remote" : { "ip" : "127.0.0.1", "port" : 46976 }, "users" : [], "roles" : [], "param" : { "command" : "killCursors", "ns" : "test.audit", "args" : { "killCursors" : "audit", "cursors" : [ { "$numberLong" : "8130617323690985931" } ], "$db" : "test" } }, "result" : 0 }
      { "atype" : "authCheck", "ts" : { "$date" : "2018-01-10T12:22:08.695-0500" }, "local" : { "ip" : "127.0.0.1", "port" : 30000 }, "remote" : { "ip" : "127.0.0.1", "port" : 46976 }, "users" : [], "roles" : [], "param" : { "command" : "killCursors", "ns" : "", "args" : { "killCursors" : "", "cursorId" : { "$numberLong" : "8130617323690985931" } } }, "result" : 0 }
      { "atype" : "authCheck", "ts" : { "$date" : "2018-01-10T12:22:08.697-0500" }, "local" : { "ip" : "127.0.0.1", "port" : 30000 }, "remote" : { "ip" : "127.0.0.1", "port" : 46976 }, "users" : [], "roles" : [], "param" : { "command" : "killCursors", "ns" : "test.audit", "args" : { "killCursors" : "audit", "cursorId" : { "$numberLong" : "8130617323690985931" } } }, "result" : 0 }
      

      Now do the same for listCollections.

          // Create some temporary collections
          db.createCollection("tempColA");
          db.createCollection("tempColB");
          cmdRes = db.runCommand({listCollections: 1, cursor: {batchSize: 1}});
          cursorId = cmdRes.cursor.id
          cmdRes = db.runCommand({killCursors: db.audit.getName(), cursors: [cursorId]});
      

      Again you will see three audit messages, and the second has an empty ns field.

      { "atype" : "authCheck", "ts" : { "$date" : "2018-01-10T15:12:18.282-0500" }, "local" : { "ip" : "127.0.0.1", "port" : 30000 }, "remote" : { "ip" : "127.0.0.1", "port" : 47118 }, "users" : [], "roles" : [], "param" : { "command" : "killCursors", "ns" : "test.audit", "args" : { "killCursors" : "audit", "cursors" : [ { "$numberLong" : "8828860051368457912" } ], "$db" : "test" } }, "result" : 0 }
      { "atype" : "authCheck", "ts" : { "$date" : "2018-01-10T15:12:18.283-0500" }, "local" : { "ip" : "127.0.0.1", "port" : 30000 }, "remote" : { "ip" : "127.0.0.1", "port" : 47118 }, "users" : [], "roles" : [], "param" : { "command" : "killCursors", "ns" : "", "args" : { "killCursors" : "", "cursorId" : { "$numberLong" : "8828860051368457912" } } }, "result" : 43 }
      { "atype" : "authCheck", "ts" : { "$date" : "2018-01-10T15:12:18.283-0500" }, "local" : { "ip" : "127.0.0.1", "port" : 30000 }, "remote" : { "ip" : "127.0.0.1", "port" : 47118 }, "users" : [], "roles" : [], "param" : { "command" : "killCursors", "ns" : "test.audit", "args" : { "killCursors" : "audit", "cursorId" : { "$numberLong" : "8828860051368457912" } } }, "result" : 43 }
      

      Running killCursors on a find while using the shell with --readMode=legacy will produce only one audit message:
      ./mongo --readMode=legacy

      query = db.audit.find().batchSize(1);
      query.close();
      
      { "atype" : "authCheck", "ts" : { "$date" : "2018-01-11T13:42:41.397-0500" }, "local" : { "ip" : "127.0.0.1", "port" : 30000 }, "remote" : { "ip" : "127.0.0.1", "port" : 55612 }, "users" : [], "roles" : [], "param" : { "command" : "killCursors", "ns" : "test.audit", "args" : { "killCursors" : "audit", "cursorId" : { "$numberLong" : "13009096037" } } }, "result" : 0 }
      

      On an aggregate (with readMode legacy) it will produce one audit message, but with a missing namespace:

      query = db.audit.aggregate([{$limit: 500}], {cursor: {batchSize: 1}})
      query.close()
      
      { "atype" : "authCheck", "ts" : { "$date" : "2018-01-11T13:45:28.706-0500" }, "local" : { "ip" : "127.0.0.1", "port" : 30000 }, "remote" : { "ip" : "127.0.0.1", "port" : 55612 }, "users" : [], "roles" : [], "param" : { "command" : "killCursors", "ns" : "", "args" : { "killCursors" : "", "cursorId" : { "$numberLong" : "9177271237534965986" } } }, "result" : 0 }
      

            Assignee:
            sergey.galtsev@mongodb.com Sergey Galtsev (Inactive)
            Reporter:
            ian.boros@mongodb.com Ian Boros
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: