-
Type: Bug
-
Resolution: Fixed
-
Priority: Major - P3
-
Affects Version/s: None
-
Component/s: Querying
-
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 }
- split to
-
SERVER-55014 KillCursors operation is not audited in legacy mode console
- Closed