mirror of https://github.com/mongodb/mongo
94 lines
3.3 KiB
JavaScript
94 lines
3.3 KiB
JavaScript
// Test that manually inserted impersonation can't escalate privileges.
|
|
// @tags: [requires_replication]
|
|
|
|
import {ReplSetTest} from "jstests/libs/replsettest.js";
|
|
import {ShardingTest} from "jstests/libs/shardingtest.js";
|
|
|
|
function runTest(conn, keyFile = undefined) {
|
|
const admin = conn.getDB("admin");
|
|
admin.createUser({user: "admin", pwd: "admin", roles: ["root"]});
|
|
|
|
function assertError(cmd, msg, code) {
|
|
const errmsg = assert.commandFailedWithCode(admin.runCommand(cmd), code).errmsg;
|
|
assert(errmsg.includes(msg), "Error message is missing '" + msg + "': " + errmsg);
|
|
}
|
|
|
|
jsTest.log("Start - Sanity check without impersonation metadata");
|
|
|
|
// Localhost authbypass is disabled, and we haven't logged in,
|
|
// so normal auth-required commands should fail.
|
|
assertError({usersInfo: 1}, "Command usersInfo requires authentication", ErrorCodes.Unauthorized);
|
|
|
|
// Hello command requires no auth, so it works fine.
|
|
assert.commandWorked(admin.runCommand({hello: 1}));
|
|
|
|
jsTest.log("Negative tests - Add impersonation metadata to hello command");
|
|
|
|
// Adding impersonation metadata is forbidden if we're not permitted to use it.
|
|
const kImpersonatedUserHello = {
|
|
hello: 1,
|
|
"$audit": {
|
|
"$impersonatedUser": {user: "admin", db: "admin"},
|
|
"$impersonatedRoles": [{role: "root", db: "admin"}],
|
|
},
|
|
};
|
|
const kImpersonatedClientHello = {
|
|
hello: 1,
|
|
"$audit": {
|
|
"$impersonatedClient": {hosts: ["172.23.55.11:23890", "192.43.22.3:14089"]},
|
|
"$impersonatedRoles": [],
|
|
},
|
|
};
|
|
assertError(kImpersonatedUserHello, "Unauthorized use of impersonation metadata", ErrorCodes.Unauthorized);
|
|
assertError(kImpersonatedClientHello, "Unauthorized use of impersonation metadata", ErrorCodes.Unauthorized);
|
|
|
|
// Try as admin (root role), should still fail.
|
|
admin.auth("admin", "admin");
|
|
assertError(kImpersonatedUserHello, "Unauthorized use of impersonation metadata", ErrorCodes.Unauthorized);
|
|
assertError(kImpersonatedClientHello, "Unauthorized use of impersonation metadata", ErrorCodes.Unauthorized);
|
|
admin.logout();
|
|
|
|
if (keyFile !== undefined) {
|
|
// On a ReplSet or mongos, our impersonation payload should be fine with cluster user.
|
|
jsTest.log("Positive test, impersonation is okay when we're local.__system");
|
|
|
|
authutil.asCluster(conn, keyFile, () => {
|
|
assert.commandWorked(admin.runCommand(kImpersonatedUserHello));
|
|
assert.commandWorked(admin.runCommand(kImpersonatedClientHello));
|
|
});
|
|
}
|
|
|
|
jsTest.log("End");
|
|
}
|
|
|
|
{
|
|
const standalone = MongoRunner.runMongod({auth: ""});
|
|
runTest(standalone);
|
|
MongoRunner.stopMongod(standalone);
|
|
}
|
|
|
|
{
|
|
const kKeyfile = "jstests/libs/key1";
|
|
|
|
const rst = new ReplSetTest({nodes: 2});
|
|
rst.startSet({keyFile: kKeyfile});
|
|
rst.initiate();
|
|
rst.awaitSecondaryNodes();
|
|
runTest(rst.getPrimary(), kKeyfile);
|
|
rst.stopSet();
|
|
}
|
|
|
|
{
|
|
const kKeyfile = "jstests/libs/key1";
|
|
|
|
const st = new ShardingTest({
|
|
mongos: 1,
|
|
config: 1,
|
|
shard: 2,
|
|
keyFile: kKeyfile,
|
|
other: {mongosOptions: {auth: null}, configOptions: {auth: null}, rsOptions: {auth: null}},
|
|
});
|
|
runTest(st.s0, kKeyfile);
|
|
st.stop();
|
|
}
|