Skip to content

Commit

Permalink
174 is cleaner, 157 working, 135 broken
Browse files Browse the repository at this point in the history
  • Loading branch information
seanlongcc committed Apr 22, 2024
1 parent bd46558 commit 2ea27d6
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 66 deletions.
4 changes: 1 addition & 3 deletions spec/mongo-inspec-profile/controls/SV-252134.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,13 +77,11 @@
tag cci: ['CCI-000130', 'CCI-000131', 'CCI-000132', 'CCI-000133', 'CCI-000134', 'CCI-000135', 'CCI-000140', 'CCI-000166', 'CCI-000171', 'CCI-000172', 'CCI-001464', 'CCI-001487', 'CCI-001814', 'CCI-001844', 'CCI-001851', 'CCI-001858']
tag nist: ['AU-3 a', 'AU-3 b', 'AU-3 c', 'AU-3 d', 'AU-3 e', 'AU-3 (1)', 'AU-5 b', 'AU-10', 'AU-12 b', 'AU-12 c', 'AU-14 (1)', 'AU-3 f', 'CM-5 (1)', 'AU-3 (2)', 'AU-4 (1)', 'AU-5 (2)']

mongo_audit_file_path = input('mongo_audit_file_path')

describe.one do
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 mongo_audit_file_path}
its(['auditLog','path']){should match input('mongo_audit_file_path')}
end

describe mongodb_conf(input('mongod_config_path')) do
Expand Down
39 changes: 28 additions & 11 deletions spec/mongo-inspec-profile/controls/SV-252135.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,18 +100,35 @@
tag 'documentable'
tag cci: ['CCI-000162', 'CCI-000163', 'CCI-000164']
tag nist: ['AU-9 a', 'AU-9 a', 'AU-9 a']

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')}
end

describe.one do
describe directory(input('mongo_audit_directory_path')) do
it { should be_directory}
it { should be_owned_by input('mongo_owner') }
it { should be_grouped_into input('mongo_group') }
it { should_not be_more_permissive_than(input('mongo_permissions')) }
end

describe mongodb_conf(input('mongod_config_path')) do
its(['auditLog', 'destination']) { should eq "syslog"}
end
describe directory(input('mongo_audit_directory_path')) do
it { should be_directory }
it { should be_owned_by input('mongo_owner') }
it { should be_grouped_into input('mongo_group') }
it { should_not be_more_permissive_than(input('mongo_permissions')) }
end

describe yaml(input('mongod_config_path')) do
its(['auditLog', 'destination']) { should eq "syslog"}
end

# describe.one do
# describe directory(input('mongo_audit_directory_path')) do
# it { should be_directory }
# it { should be_owned_by input('mongo_owner') }
# it { should be_grouped_into input('mongo_group') }
# it { should_not be_more_permissive_than(input('mongo_permissions')) }
# end

# describe mongodb_conf(input('mongod_config_path')) do
# its(['auditLog', 'destination']) { should eq "syslog"}
# end
# end

end
33 changes: 23 additions & 10 deletions spec/mongo-inspec-profile/controls/SV-252157.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,19 +47,32 @@
tag cci: ['CCI-000764']
tag nist: ['IA-2']

get_dbs = "db.adminCommand({ listDatabases: 1 })"

run_get_dbs = "mongosh \"mongodb://#{input('mongo_dba')}:#{input('mongo_dba_password')}@#{input('mongo_host')}:#{input('mongo_port')}/?tls=true&tlsCAFile=#{input('ca_file')}&tlsCertificateKeyFile=#{input('certificate_key_file')}\" --quiet --eval \"#{get_dbs}\""
only_if 'This control applies only when LDAP is disabled' do
!input('ldap_enabled')
end

get_system_users = "EJSON.stringify(db.system.users.find().toArray())"

run_get_system_users = "mongosh \"mongodb://#{input('mongo_dba')}:#{input('mongo_dba_password')}@#{input('mongo_host')}:#{input('mongo_port')}/admin?authSource=#{input'auth_source'}&tls=true&tlsCAFile=#{input('ca_file')}&tlsCertificateKeyFile=#{input('certificate_key_file')}\" --quiet --eval \"#{get_system_users}\""

describe json({command: run_get_dbs}) do
its('ok') { should cmp 1 }
system_users = json({command: run_get_system_users}).params

describe mongodb_conf(input('mongod_config_path')) do
its(['security','authorization']){should eq "enabled"}
end

describe json({command: run_get_dbs}) do
only_if 'LDAP is being used for authenticaion/authorization' do
input('ldap_enabled') == true
system_users.each do |user|
user_id = user['_id']

describe "User #{user_id}" do
subject { user_id }
it 'should be in either mongo_superusers or mongo_users' do
list = [input('mongo_superusers'), input('mongo_users')].flatten
if !list.include?(subject)
fail "User #{subject} is not authorized as a superuser or regular user"
end
end
end
its('ok') { should cmp 1 }
end

end
1 change: 1 addition & 0 deletions spec/mongo-inspec-profile/controls/SV-252161.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,5 @@
skip 'If using LDAP for authentication, this is not applicable.'
skip 'If the authenticated MongoDB user displayed does not have a user value equal to the x.509 certs Subject Name, this is a finding.'
end

end
8 changes: 4 additions & 4 deletions spec/mongo-inspec-profile/controls/SV-252165.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
tag cci: ['CCI-001199']
tag nist: ['SC-28']

only_if 'Encryption at rest must be enabled' do
input('encryption_at_rest') == true
end

check_command="db.serverStatus().encryptionAtRest.encryptionEnabled"

encrypt_check = "db.serverStatus().encryptionAtRest.encryptionCipherMode"
Expand All @@ -62,10 +66,6 @@

kmip_output = command(run_kmip_check)

only_if 'Encryption at rest must be enabled' do
input('encryption_at_rest') == true
end

describe 'Encrypted Storage Engine' do
it 'should be enabled' do
expect(check_output.stdout).to match(/true/i)
Expand Down
55 changes: 18 additions & 37 deletions spec/mongo-inspec-profile/controls/SV-252174.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,51 +64,32 @@
tag cci: ['CCI-001812']
tag nist: ['CM-11 (2)']

get_users = "EJSON.stringify(db.getUsers())"
get_system_users = "EJSON.stringify(db.system.users.find().toArray())"

get_dbs = "EJSON.stringify(db.adminCommand('listDatabases'))"
run_get_system_users = "mongosh \"mongodb://#{input('mongo_dba')}:#{input('mongo_dba_password')}@#{input('mongo_host')}:#{input('mongo_port')}/admin?authSource=#{input'auth_source'}&tls=true&tlsCAFile=#{input('ca_file')}&tlsCertificateKeyFile=#{input('certificate_key_file')}\" --quiet --eval \"#{get_system_users}\""

run_get_dbs = "mongosh \"mongodb://#{input('mongo_dba')}:#{input('mongo_dba_password')}@#{input('mongo_host')}:#{input('mongo_port')}/?authSource=#{input'auth_source'}&tls=true&tlsCAFile=#{input('ca_file')}&tlsCertificateKeyFile=#{input('certificate_key_file')}\" --quiet --eval \"#{get_dbs}\""

dbs_output = json({command: run_get_dbs}).params
system_users = json({command: run_get_system_users}).params

# extract just the names of the databases
db_names = dbs_output["databases"].map { |db| db["name"] }
system_users.each do |user|
user_id = user['_id']
unless input('mongo_superusers').include?(user_id)

db_names.each do |db_name|
p "db_name", db_name
run_get_users = "mongosh \"mongodb://#{input('mongo_dba')}:#{input('mongo_dba_password')}@#{input('mongo_host')}:#{input('mongo_port')}/#{db_name}?authSource=#{input'auth_source'}&tls=true&tlsCAFile=#{input('ca_file')}&tlsCertificateKeyFile=#{input('certificate_key_file')}\" --quiet --eval \"#{get_users}\""
db_name = user['db']
user_roles = user['roles'].map { |role| "#{role['role']}" }
db_roles = user_roles.map { |role| "#{db_name}.#{role}" }

# run the command and parse the output as json
users_output = json({command: run_get_users}).params
user_roles.each do |role|
run_get_role = "mongosh \"mongodb://#{input('mongo_dba')}:#{input('mongo_dba_password')}@#{input('mongo_host')}:#{input('mongo_port')}/#{db_name}?authSource=#{input'auth_source'}&tls=true&tlsCAFile=#{input('ca_file')}&tlsCertificateKeyFile=#{input('certificate_key_file')}\" --quiet --eval \"EJSON.stringify(db.getRole('#{role}', {showPrivileges: true}))\""

users_output['users'].each do |user|
p "user", user
role_output = json({command: run_get_role}).params

# check if user is not a superuser
unless input('mongo_superusers').include?(user['_id'])
all_actions = role_output["privileges"].map { |privilege| privilege["actions"] } +
role_output["inheritedPrivileges"].map { |privilege| privilege["actions"] }
all_actions.flatten!

# collect all roles for user and wrap in single quotes
user_roles = user['roles'].map { |role| "#{role['role']}" }

user_roles.each do |role|
p "role", role

run_get_role = "mongosh \"mongodb://#{input('mongo_dba')}:#{input('mongo_dba_password')}@#{input('mongo_host')}:#{input('mongo_port')}/#{db_name}?authSource=#{input'auth_source'}&tls=true&tlsCAFile=#{input('ca_file')}&tlsCertificateKeyFile=#{input('certificate_key_file')}\" --quiet --eval \"EJSON.stringify(db.getRole('#{role}', {showPrivileges: true}))\""

role_output = json({command: run_get_role}).params

all_actions = role_output["privileges"].map { |privilege| privilege["actions"] } +
role_output["inheritedPrivileges"].map { |privilege| privilege["actions"] }
all_actions.flatten!

p all_actions
p '---------------------------------------------------------------------------------------------------'

describe "Role #{role} of user #{user['_id']} does not have privileges for 'createCollection' and 'changeStream', and" do
subject { all_actions }
it { should_not be_in ["createCollection", "changeStream"] }
end
describe "Role '#{role}' of user #{user['_id']} does not have privileges for 'createCollection' and 'changeStream', and" do
subject { all_actions }
it { should_not be_in ["createCollection", "changeStream"] }
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/mongo-inspec-profile/inspec.yml
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ inputs:
value: "/var/log/mongodb/audit/"
required: true

# SV-252134, SV-252171
# SV-252134, SV-252135, SV-252171
- name: mongo_audit_file_path
description: "The path to the mongo audit file"
type: string
Expand Down

0 comments on commit 2ea27d6

Please sign in to comment.