Policy statement search: don't stacktrace on missing field (#2962)

Signed-off-by: Clinton Wolfe <clintoncwolfe@gmail.com>
This commit is contained in:
Clinton Wolfe 2018-04-17 13:21:29 -04:00 committed by GitHub
parent 2e2346ff0c
commit 146b60556d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 1 deletions

View file

@ -189,7 +189,12 @@ class AwsIamPolicy < Inspec.resource(1)
def has_statement__array_criterion(crit_name, statement, criteria) def has_statement__array_criterion(crit_name, statement, criteria)
return true unless criteria.key?(crit_name) return true unless criteria.key?(crit_name)
check = criteria[crit_name] check = criteria[crit_name]
values = statement[crit_name] # This is an array due to normalize_statements # This is an array due to normalize_statements
# If it is nil, the statement does not have an entry for that dimension;
# but since we were asked to match on it (on nothing), we
# decide to never match
values = statement[crit_name]
return false if values.nil?
if check.is_a?(String) if check.is_a?(String)
# If check is a string, it only has to match one of the values # If check is a string, it only has to match one of the values

View file

@ -98,5 +98,13 @@ control "aws_iam_policy matchers" do
describe aws_iam_policy('AWSCertificateManagerReadOnly') do describe aws_iam_policy('AWSCertificateManagerReadOnly') do
its('statement_count') { should cmp 1 } its('statement_count') { should cmp 1 }
it { should have_statement 'Effect' => 'Allow', 'Action' => 'acm:GetCertificate' } it { should have_statement 'Effect' => 'Allow', 'Action' => 'acm:GetCertificate' }
end
# This policy has a statment with a NotAction, and no Action
# We don't yet support NotAction
# But if you ask for action, it should not match, and also not explode
# arn:aws:iam::aws:policy/PowerUserAccess
describe aws_iam_policy('PowerUserAccess') do
it { should_not have_statement 'Action' => 'iam:*' }
end end
end end

View file

@ -233,6 +233,8 @@ class AwsIamPolicyMatchersTest < Minitest::Test
assert(AwsIamPolicy.new('test-policy-1').has_statement?('Action' => [/^ec2\:Describe/])) assert(AwsIamPolicy.new('test-policy-1').has_statement?('Action' => [/^ec2\:Describe/]))
# Able to match a degenerate policy doc in which there is exactly one statement as a hash. # Able to match a degenerate policy doc in which there is exactly one statement as a hash.
assert(AwsIamPolicy.new('test-policy-3').has_statement?('Action' => 'acm:GetCertificate')) assert(AwsIamPolicy.new('test-policy-3').has_statement?('Action' => 'acm:GetCertificate'))
# Don't explode, and also don't match, if a policy has a statement without an Action
refute(AwsIamPolicy.new('test-policy-4').has_statement?('Action' => 'iam:*'))
end end
def test_have_statement_when_resource_is_provided def test_have_statement_when_resource_is_provided
@ -295,6 +297,13 @@ module MAIPSB
attachment_count: 0, attachment_count: 0,
is_attachable: true, is_attachable: true,
}), }),
OpenStruct.new({
policy_name: 'test-policy-4',
arn: 'arn:aws:iam::aws:policy/test-policy-4',
default_version_id: 'v1',
attachment_count: 0,
is_attachable: false,
}),
] ]
OpenStruct.new({ policies: fixtures }) OpenStruct.new({ policies: fixtures })
end end
@ -392,6 +401,35 @@ module MAIPSB
document: '%7B%0A%20%20%20%20%22Version%22%3A%20%222012-10-17%22%2C%0A%20%20%20%20%22Statement%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22Effect%22%3A%20%22Allow%22%2C%0A%20%20%20%20%20%20%20%20%22Action%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22acm%3ADescribeCertificate%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22acm%3AListCertificates%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22acm%3AGetCertificate%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22acm%3AListTagsForCertificate%22%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20%22Resource%22%3A%20%22%2A%22%0A%20%20%20%20%7D%0A%7D', document: '%7B%0A%20%20%20%20%22Version%22%3A%20%222012-10-17%22%2C%0A%20%20%20%20%22Statement%22%3A%20%7B%0A%20%20%20%20%20%20%20%20%22Effect%22%3A%20%22Allow%22%2C%0A%20%20%20%20%20%20%20%20%22Action%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22acm%3ADescribeCertificate%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22acm%3AListCertificates%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22acm%3AGetCertificate%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22acm%3AListTagsForCertificate%22%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20%22Resource%22%3A%20%22%2A%22%0A%20%20%20%20%7D%0A%7D',
) )
}, },
'arn:aws:iam::aws:policy/test-policy-4' => {
'v1' => OpenStruct.new(
# This is arn:aws:iam::aws:policy/PowerUserAccess
# {
# "Version": "2012-10-17",
# "Statement": [
# {
# "Effect": "Allow",
# "NotAction": [
# "iam:*",
# "organizations:*"
# ],
# "Resource": "*"
# },
# {
# "Effect": "Allow",
# "Action": [
# "iam:CreateServiceLinkedRole",
# "iam:DeleteServiceLinkedRole",
# "iam:ListRoles",
# "organizations:DescribeOrganization"
# ],
# "Resource": "*"
# }
# ]
# }
document: '%7B%0A%20%20%22Version%22%3A%20%222012-10-17%22%2C%0A%20%20%22Statement%22%3A%20%5B%0A%20%20%20%20%7B%0A%20%20%20%20%20%20%22Effect%22%3A%20%22Allow%22%2C%0A%20%20%20%20%20%20%22NotAction%22%3A%20%5B%22iam%3A%2A%22%2C%20%22organizations%3A%2A%22%5D%2C%0A%20%20%20%20%20%20%22Resource%22%3A%20%22%2A%22%0A%20%20%20%20%7D%2C%7B%0A%20%20%20%20%20%20%22Effect%22%3A%20%22Allow%22%2C%0A%20%20%20%20%20%20%22Action%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%22iam%3ACreateServiceLinkedRole%22%2C%0A%20%20%20%20%20%20%20%20%20%20%22iam%3ADeleteServiceLinkedRole%22%2C%0A%20%20%20%20%20%20%20%20%20%20%22iam%3AListRoles%22%2C%0A%20%20%20%20%20%20%20%20%20%20%22organizations%3ADescribeOrganization%22%0A%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%22Resource%22%3A%20%22%2A%22%0A%20%20%20%20%7D%0A%20%20%5D%0A%7D',
)
},
} }
pv = fixtures.dig(query[:policy_arn], query[:version_id]) pv = fixtures.dig(query[:policy_arn], query[:version_id])
return OpenStruct.new(policy_version: pv) if pv return OpenStruct.new(policy_version: pv) if pv