From 7b9664ce3e25440e642e83b8c23fc86a5020a23e Mon Sep 17 00:00:00 2001 From: seanlongcc Date: Thu, 21 Mar 2024 14:25:30 -0400 Subject: [PATCH] able to check each db for roles - 252154, fixed spacing --- spec/ansible/roles/mongo-stig/tasks/cat1.yml | 20 -------------- spec/ansible/roles/mongo-stig/tasks/cat2.yml | 1 + .../controls/SV-252141.rb | 4 +-- .../controls/SV-252154.rb | 26 ++++++++++++++----- .../controls/SV-252159.rb | 16 ++++++++++-- .../controls/SV-252165.rb | 6 ++--- .../controls/SV-252168.rb | 6 ++--- .../controls/SV-252169.rb | 6 ++--- .../controls/SV-252171.rb | 10 +++---- .../controls/SV-252172.rb | 4 +-- .../controls/SV-252175.rb | 7 +++-- .../controls/SV-252180.rb | 2 +- spec/mongo-inspec-profile/inspec.yml | 16 ++++++++++++ 13 files changed, 73 insertions(+), 51 deletions(-) diff --git a/spec/ansible/roles/mongo-stig/tasks/cat1.yml b/spec/ansible/roles/mongo-stig/tasks/cat1.yml index 7043775..823520a 100644 --- a/spec/ansible/roles/mongo-stig/tasks/cat1.yml +++ b/spec/ansible/roles/mongo-stig/tasks/cat1.yml @@ -33,7 +33,6 @@ # - SV-252146 # - enterprise -##### DISABLED FOR EASIER TESTING - name: "HIGH | SV-252149 | MongoDB must integrate with an organization-level authentication/access mechanism providing account management and automation for all users, groups, roles, and any other principals." yedit: src: "{{ mongod_config_path }}" @@ -73,25 +72,6 @@ # - high # - SV-252158 - -##### PART TWO OF THIS DOESNT EXIST IN MONGO 4+ -# - name: "HIGH | SV-252159 | If passwords are used for authentication, MongoDB must store only hashed, salted representations of passwords." -# blockinfile: -# path: "{{ mongod_config_path }}" -# marker: "#Rule ID SV-252159" -# prepend_newline: true -# insertafter: "EOF" -# block: | -# setParameter: -# authenticationMechanisms: SCRAM-SHA-256 -# state: present -# ignore_errors: true -# tags: -# - cat1 -# - high -# - SV-252159 - -##### CHANGES TO ENTERPRISE WITH GSSAPI AND PLAIN, ASKS FOR ALL OF THEM - name: "HIGH | SV-252159 | If passwords are used for authentication, MongoDB must store only hashed, salted representations of passwords." yedit: src: "{{ mongod_config_path }}" diff --git a/spec/ansible/roles/mongo-stig/tasks/cat2.yml b/spec/ansible/roles/mongo-stig/tasks/cat2.yml index 173171b..589cdfd 100644 --- a/spec/ansible/roles/mongo-stig/tasks/cat2.yml +++ b/spec/ansible/roles/mongo-stig/tasks/cat2.yml @@ -202,6 +202,7 @@ # - medium # - SV-252153 +##### MANUAL ANSIBLE # - name: "MEDIUM | SV-252154 | Database objects (including but not limited to tables, indexes, storage, stored procedures, functions, triggers, links to software external to MongoDB, etc.) must be owned by database/DBMS principals authorized for ownership." # command: true # ignore_errors: true diff --git a/spec/mongo-inspec-profile/controls/SV-252141.rb b/spec/mongo-inspec-profile/controls/SV-252141.rb index 7dabaad..c61292f 100644 --- a/spec/mongo-inspec-profile/controls/SV-252141.rb +++ b/spec/mongo-inspec-profile/controls/SV-252141.rb @@ -48,7 +48,7 @@ tag nist: ['SC-24', 'SC-24'] describe mongodb_conf(input('mongod_config_path')) do - its(['storage','journal','enabled']){should eq true} - end + its(['storage','journal','enabled']){should eq true} + end end diff --git a/spec/mongo-inspec-profile/controls/SV-252154.rb b/spec/mongo-inspec-profile/controls/SV-252154.rb index 5c2e7cd..3b5363e 100644 --- a/spec/mongo-inspec-profile/controls/SV-252154.rb +++ b/spec/mongo-inspec-profile/controls/SV-252154.rb @@ -32,12 +32,26 @@ tag cci: ['CCI-001499'] tag nist: ['CM-5 (6)'] - #the beginning of something great - db_name = 'database' - command_string = "mongosh #{db_name} --quiet --eval 'db.getRoles()'" - - describe command(command_string) do - its('stdout') { should include 'dbOwner' } + check_command = "EJSON.stringify(db.getUsers())" + + input('mongo_dbs').each do |db_name| + run_check_command = "mongosh mongodb://#{input('mongo_dba')}:#{input('mongo_dba_password')}@#{input('mongo_host')}:#{input('mongo_port')}/#{db_name}?authSource=admin --quiet --eval \"#{check_command}\"" + + # run the command and parse the output as json + users_output = json({command: run_check_command}).params + + users_output['users'].each do |user| + # check if user is not a superuser + unless input('mongo_superusers').include?(user['user']) + # check each users role + describe "User #{user['_id']} in database #{db_name}" do + #collect all roles for user + subject { user['roles'].map { |role| role['role'] } } + it { should_not include 'dbOwner' } + end + end + end end + end \ No newline at end of file diff --git a/spec/mongo-inspec-profile/controls/SV-252159.rb b/spec/mongo-inspec-profile/controls/SV-252159.rb index bf12d2a..8363a7e 100644 --- a/spec/mongo-inspec-profile/controls/SV-252159.rb +++ b/spec/mongo-inspec-profile/controls/SV-252159.rb @@ -63,9 +63,21 @@ tag cci: ['CCI-000196'] tag nist: ['IA-5 (1) (c)'] - #authSchemaUpgrade command doesn't exist anymore since version 4, so part 2 is not doable describe mongodb_conf(input('mongod_config_path')) do - its(['setParameter','authenticationMechanisms']){should be_in ['SCRAM-SHA-1', 'SCRAM-SHA-256', 'MONGODB-X509', 'GSSAPI', 'PLAIN']} + its(['setParameter','authenticationMechanisms']){should be_in ['SCRAM-SHA-1', 'SCRAM-SHA-256', 'MONGODB-X509', 'GSSAPI', 'PLAIN','MONGODB-AWS',]} end + check_command = "db.getSiblingDB('admin').system.version.find({ '_id' : 'authSchema'}, {_id: 0})" + + run_check_command = "mongosh mongodb://#{input('mongo_dba')}:#{input('mongo_dba_password')}@#{input('mongo_host')}:#{input('mongo_port')} --quiet --eval \"#{check_command}\"" + + check_output = command(run_check_command) + + describe 'authSchemaVersion' do + it 'should be atleast version 5' do + expect(check_output.stdout).to match(/[ { currentVersion: 5 } ]/) + end + end + + end diff --git a/spec/mongo-inspec-profile/controls/SV-252165.rb b/spec/mongo-inspec-profile/controls/SV-252165.rb index e1ce887..8e5557f 100644 --- a/spec/mongo-inspec-profile/controls/SV-252165.rb +++ b/spec/mongo-inspec-profile/controls/SV-252165.rb @@ -51,9 +51,9 @@ check_output = command(run_check_command) describe 'Encrypted Storage Engine' do - it 'should be enabled' do - expect(check_output.stdout).to match(/false/) - end + it 'should be enabled' do + expect(check_output.stdout).to match(/false/) end + end end diff --git a/spec/mongo-inspec-profile/controls/SV-252168.rb b/spec/mongo-inspec-profile/controls/SV-252168.rb index 0110951..adcd8a0 100644 --- a/spec/mongo-inspec-profile/controls/SV-252168.rb +++ b/spec/mongo-inspec-profile/controls/SV-252168.rb @@ -54,10 +54,10 @@ check_output = command(run_check_command) describe 'Client log data' do - it 'should be redacted' do - expect(check_output.stdout).to match(/true/) - end + it 'should be redacted' do + expect(check_output.stdout).to match(/true/) end + end describe mongodb_conf(input('mongod_config_path')) do its(['security','redactClientLogData']){should eq true} diff --git a/spec/mongo-inspec-profile/controls/SV-252169.rb b/spec/mongo-inspec-profile/controls/SV-252169.rb index 4655039..a1a3e8c 100644 --- a/spec/mongo-inspec-profile/controls/SV-252169.rb +++ b/spec/mongo-inspec-profile/controls/SV-252169.rb @@ -55,10 +55,10 @@ check_output = command(run_check_command) describe 'Client log data' do - it 'should be redacted' do - expect(check_output.stdout).to match(/true/) - end + it 'should be redacted' do + expect(check_output.stdout).to match(/true/) end + end describe mongodb_conf(input('mongod_config_path')) do its(['security','redactClientLogData']){should eq true} diff --git a/spec/mongo-inspec-profile/controls/SV-252171.rb b/spec/mongo-inspec-profile/controls/SV-252171.rb index b1d5fcf..732fa08 100644 --- a/spec/mongo-inspec-profile/controls/SV-252171.rb +++ b/spec/mongo-inspec-profile/controls/SV-252171.rb @@ -65,10 +65,10 @@ tag nist: ['AU-3 (2)'] describe mongodb_conf(input('mongod_config_path')) do - its(['auditLog','destination']){should eq "file"} - its(['auditLog','format']){should eq "BSON"} - its(['auditLog','path']){should match input('mongo_audit_file_path')} - its(['auditLog','filter']){should match '{ atype: { $in: [ "createCollection", "dropCollection" ] } }'} - end + its(['auditLog','destination']){should eq "file"} + its(['auditLog','format']){should eq "BSON"} + its(['auditLog','path']){should match input('mongo_audit_file_path')} + its(['auditLog','filter']){should match '{ atype: { $in: [ "createCollection", "dropCollection" ] } }'} + end end diff --git a/spec/mongo-inspec-profile/controls/SV-252172.rb b/spec/mongo-inspec-profile/controls/SV-252172.rb index 253996a..9a4d9dc 100644 --- a/spec/mongo-inspec-profile/controls/SV-252172.rb +++ b/spec/mongo-inspec-profile/controls/SV-252172.rb @@ -41,7 +41,7 @@ tag nist: ['AU-4'] describe mongodb_conf(input('mongod_config_path')) do - its(['auditLog', 'destination']) { should eq "syslog"} - end + its(['auditLog', 'destination']) { should eq "syslog"} + end end diff --git a/spec/mongo-inspec-profile/controls/SV-252175.rb b/spec/mongo-inspec-profile/controls/SV-252175.rb index dc04e22..ed6ef72 100644 --- a/spec/mongo-inspec-profile/controls/SV-252175.rb +++ b/spec/mongo-inspec-profile/controls/SV-252175.rb @@ -101,13 +101,12 @@ expect(create_user_again.stderr).to match(/MongoServerError: User "myTester@test" already exists/) end end - end describe 'Test user' do - it 'should not be able to write to database' do - expect(run_user_output.stderr).to match(/MongoServerError: not authorized on test to execute command/) - end + it 'should not be able to write to database' do + expect(run_user_output.stderr).to match(/MongoServerError: not authorized on test to execute command/) end + end end diff --git a/spec/mongo-inspec-profile/controls/SV-252180.rb b/spec/mongo-inspec-profile/controls/SV-252180.rb index 543a7a3..7a6d650 100644 --- a/spec/mongo-inspec-profile/controls/SV-252180.rb +++ b/spec/mongo-inspec-profile/controls/SV-252180.rb @@ -55,6 +55,6 @@ its(['net','tls','allowInvalidCertificates']){should eq false} its(['net','tls','allowConnectionsWithoutCertificates']){should eq false} its(['net','tls','FIPSMode']){should eq true} - end + end diff --git a/spec/mongo-inspec-profile/inspec.yml b/spec/mongo-inspec-profile/inspec.yml index 5778832..6e60cf7 100644 --- a/spec/mongo-inspec-profile/inspec.yml +++ b/spec/mongo-inspec-profile/inspec.yml @@ -50,6 +50,22 @@ inputs: required: true sensitive: true + - name: mongo_superusers + description: "Authorized superuser accounts" + type: array + value: + - "" + required: true + sensitive: true + + - name: mongo_dbs + description: "Authorized mongo databases" + type: array + value: + - "" + required: true + sensitive: true + - name: mongod_config_path description: "The path to the mongod configuration file" type: string