-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Migrate KMS Microsoft_AD WAF CloudFront CloudWatch resources to cfn-g…
…uard ruleset
- Loading branch information
Showing
16 changed files
with
1,295 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# | ||
##################################### | ||
## AWS Solutions ## | ||
##################################### | ||
# | ||
# Rule Identifier: | ||
# KMS_NO_WILDCARD_PRINCIPAL | ||
# | ||
# Description: | ||
# KMS key should not allow * principal | ||
# | ||
# Reports on: | ||
# AWS::KMS::Key | ||
# | ||
# Evaluates: | ||
# AWS CloudFormation | ||
# | ||
# Rule Parameters: | ||
# NA | ||
# | ||
# CFN-NAG Rule | ||
# F76 | ||
# | ||
# Documentation: | ||
# https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html | ||
# | ||
# Scenarios: | ||
# a) SKIP: when there are no KMS CMKs | ||
# b) SKIP: when metada has rule suppression for KMS_NO_WILDCARD_PRINCIPAL | ||
# c) FAIL: when Principal: '*' appears in any KeyPolicy | ||
# d) PASS: when no keypolicy has Principle: '*' | ||
|
||
let kms_no_wildcard_principal = Resources.*[ Type == "AWS::KMS::Key" | ||
Metadata.cfn_nag.rules_to_suppress not exists or | ||
Metadata.cfn_nag.rules_to_suppress.*.id != "F76" | ||
Metadata.guard.SuppressedRules not exists or | ||
Metadata.guard.SuppressedRules.* != "KMS_NO_WILDCARD_PRINCIPAL" | ||
] | ||
|
||
rule KMS_NO_WILDCARD_PRINCIPAL when %kms_no_wildcard_principal !empty { | ||
let violations = %kms_no_wildcard_principal[ | ||
some Properties.KeyPolicy.Statement[*] { | ||
Principal == '*' | ||
} | ||
] | ||
%violations empty | ||
<< | ||
Violation: KMS key should not allow * principal. | ||
Fix: Set the EnableKeyRotation property to true. | ||
>> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
197 changes: 197 additions & 0 deletions
197
rules/aws/aws_kms/tests/kms_no_wildcard_principal_tests.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
### | ||
# KMS_NO_WILDCARD_PRINCIPAL tests | ||
### | ||
--- | ||
- name: Empty, SKIP | ||
input: {} | ||
expectations: | ||
rules: | ||
KMS_NO_WILDCARD_PRINCIPAL: SKIP | ||
|
||
- name: Scenario a) No resources, SKIP | ||
input: | ||
Resources: {} | ||
expectations: | ||
rules: | ||
KMS_NO_WILDCARD_PRINCIPAL: SKIP | ||
|
||
- name: KMS key with principal "*", FAIL | ||
input: | ||
Resources: | ||
KMS_NO_WILDCARD_PRINCIPAL: | ||
Type: AWS::KMS::Key | ||
Properties: | ||
KeyPolicy: | ||
Statement: | ||
- Action: kms:* | ||
Effect: Allow | ||
Principal: | ||
AWS: | ||
Fn::Join: | ||
- "" | ||
- - 'arn:' | ||
- Ref: AWS::Partition | ||
- :iam::123456789012:root | ||
Resource: 'arn:aws:iam::111122223333:foobar' | ||
- Action: | ||
- kms:Decrypt | ||
- kms:DescribeKey | ||
- kms:Encrypt | ||
- kms:ReEncrypt* | ||
- kms:GenerateDataKey* | ||
Effect: Allow | ||
Principal: '*' | ||
Resource: 'arn:aws:ec2:us-east-1:111122223333:foobar' | ||
expectations: | ||
rules: | ||
KMS_NO_WILDCARD_PRINCIPAL: FAIL | ||
|
||
- name: KMS key with principal NOT "*", PASS | ||
input: | ||
Resources: | ||
KMS_NO_WILDCARD_PRINCIPAL: | ||
Type: AWS::KMS::Key | ||
Properties: | ||
KeyPolicy: | ||
Statement: | ||
- Action: kms:* | ||
Effect: Allow | ||
Principal: | ||
AWS: | ||
Fn::Join: | ||
- "" | ||
- - 'arn:' | ||
- Ref: AWS::Partition | ||
- :iam::123456789012:root | ||
Resource: 'arn:aws:iam::111122223333:foobar' | ||
- Action: | ||
- kms:Decrypt | ||
- kms:DescribeKey | ||
- kms:Encrypt | ||
- kms:ReEncrypt* | ||
- kms:GenerateDataKey* | ||
Effect: Allow | ||
Principal: | ||
AWS: | ||
Fn::Join: | ||
- "" | ||
- - 'arn:' | ||
- Ref: AWS::Partition | ||
- :iam::123456789012:root | ||
Resource: 'arn:aws:ec2:us-east-1:111122223333:foobar' | ||
expectations: | ||
rules: | ||
KMS_NO_WILDCARD_PRINCIPAL: PASS | ||
|
||
## | ||
## Suppressions | ||
## | ||
- name: F76 CFN-NAG suppression, SKIP | ||
input: | ||
Resources: | ||
KMS_NO_WILDCARD_PRINCIPAL: | ||
Type: AWS::KMS::Key | ||
Properties: | ||
KeyPolicy: | ||
Statement: | ||
- Action: kms:* | ||
Effect: Allow | ||
Principal: | ||
AWS: | ||
Fn::Join: | ||
- "" | ||
- - 'arn:' | ||
- Ref: AWS::Partition | ||
- :iam::123456789012:root | ||
Resource: 'arn:aws:iam::111122223333:foobar' | ||
- Action: | ||
- kms:Decrypt | ||
- kms:DescribeKey | ||
- kms:Encrypt | ||
- kms:ReEncrypt* | ||
- kms:GenerateDataKey* | ||
Effect: Allow | ||
Principal: '*' | ||
Resource: 'arn:aws:ec2:us-east-1:111122223333:foobar' | ||
Metadata: | ||
cfn_nag: | ||
rules_to_suppress: | ||
- id: F76 | ||
reason: Suppressed for a very good reason | ||
expectations: | ||
rules: | ||
KMS_NO_WILDCARD_PRINCIPAL: SKIP | ||
|
||
- name: cfn-guard suppression, SKIP | ||
input: | ||
Resources: | ||
KMS_NO_WILDCARD_PRINCIPAL: | ||
Type: AWS::KMS::Key | ||
Properties: | ||
KeyPolicy: | ||
Statement: | ||
- Action: kms:* | ||
Effect: Allow | ||
Principal: | ||
AWS: | ||
Fn::Join: | ||
- "" | ||
- - 'arn:' | ||
- Ref: AWS::Partition | ||
- :iam::123456789012:root | ||
Resource: 'arn:aws:iam::111122223333:foobar' | ||
- Action: | ||
- kms:Decrypt | ||
- kms:DescribeKey | ||
- kms:Encrypt | ||
- kms:ReEncrypt* | ||
- kms:GenerateDataKey* | ||
Effect: Allow | ||
Principal: '*' | ||
Resource: 'arn:aws:ec2:us-east-1:111122223333:foobar' | ||
Metadata: | ||
guard: | ||
SuppressedRules: | ||
- KMS_NO_WILDCARD_PRINCIPAL: Suppressed for a very good reason | ||
expectations: | ||
rules: | ||
KMS_NO_WILDCARD_PRINCIPAL: SKIP | ||
|
||
- name: cfn-guard and cfn-nag suppression, SKIP | ||
input: | ||
Resources: | ||
KMS_NO_WILDCARD_PRINCIPAL: | ||
Type: AWS::KMS::Key | ||
Properties: | ||
KeyPolicy: | ||
Statement: | ||
- Action: kms:* | ||
Effect: Allow | ||
Principal: | ||
AWS: | ||
Fn::Join: | ||
- "" | ||
- - 'arn:' | ||
- Ref: AWS::Partition | ||
- :iam::123456789012:root | ||
Resource: 'arn:aws:iam::111122223333:foobar' | ||
- Action: | ||
- kms:Decrypt | ||
- kms:DescribeKey | ||
- kms:Encrypt | ||
- kms:ReEncrypt* | ||
- kms:GenerateDataKey* | ||
Effect: Allow | ||
Principal: '*' | ||
Resource: 'arn:aws:ec2:us-east-1:111122223333:foobar' | ||
Metadata: | ||
cfn_nag: | ||
rules_to_suppress: | ||
- id: F76 | ||
reason: Suppressed for a very good reason | ||
guard: | ||
SuppressedRules: | ||
- KMS_NO_WILDCARD_PRINCIPAL: Suppressed for a very good reason | ||
expectations: | ||
rules: | ||
KMS_NO_WILDCARD_PRINCIPAL: SKIP |
79 changes: 79 additions & 0 deletions
79
rules/aws/aws_microsoft_ad/microsoft_ad_no_plaintext_password.guard
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# | ||
##################################### | ||
## AWS Solutions ## | ||
##################################### | ||
# Rule Identifier: | ||
# MICROSOFT_AD_NO_PLAINTEXT_PASSWORD | ||
# | ||
# Description: | ||
# Directory Service Microsoft AD password must not be a plaintext string or a Ref to a Parameter with a Default value. | ||
# Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager/ssm-secure value. | ||
# with a Default value. Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager value. | ||
# | ||
# Reports on: | ||
# AWS::DirectoryService::MicrosoftAD | ||
# | ||
# Evaluates: | ||
# AWS CloudFormation | ||
# | ||
# Rule Parameters: | ||
# NA | ||
# | ||
# CFN_NAG Rule Id: | ||
# F36 | ||
# | ||
# Note: this rule works, however it sends the custom message twice for each resource | ||
# | ||
# Scenarios: | ||
# a) SKIP: when there are no AWS::DirectoryService::MicrosoftAD present | ||
# b) PASS: when all AWS::DirectoryService::MicrosoftAD use passwords from secure sources | ||
# c) FAIL: when any AWS::DirectoryService::MicrosoftAD has a Password property not using a secure source | ||
# d) SKIP: when metadata has rule suppression for MICROSOFT_AD_NO_PLAINTEXT_PASSWORD or CFN_NAG F36 | ||
|
||
let microsoft_ad_no_plaintext_password = Resources.*[ Type == 'AWS::DirectoryService::MicrosoftAD' | ||
Metadata.cfn_nag.rules_to_suppress not exists or | ||
Metadata.cfn_nag.rules_to_suppress.*.id != "F36" | ||
Metadata.guard.SuppressedRules not exists or | ||
Metadata.guard.SuppressedRules.* != "MICROSOFT_AD_NO_PLAINTEXT_PASSWORD" | ||
] | ||
|
||
# Get any AWS::DirectoryService::MicrosoftAD Refs for Password? | ||
let microsoft_ad_password_refs = %microsoft_ad_no_plaintext_password.Properties.Password.'!Ref' | ||
|
||
# Rule 1: when Microsoft AD password no plaintext password have Ref to Parameter for Password | ||
rule MICROSOFT_AD_PASSWORD_USES_SECURE_PARAMETER when | ||
%microsoft_ad_no_plaintext_password not empty | ||
{ | ||
Parameters exists | ||
Parameters not empty | ||
%microsoft_ad_password_refs not empty | ||
let parameter_refs = Parameters.%microsoft_ad_password_refs | ||
when %parameter_refs !empty { | ||
%parameter_refs.Type == 'String' | ||
%parameter_refs.NoEcho exists | ||
%parameter_refs.NoEcho == true | ||
%parameter_refs.Default !exists | ||
} | ||
} | ||
|
||
# Rule 2: when Microsoft AD password no plaintext password and above rule did not pass | ||
rule MICROSOFT_AD_PASSWORD_USES_SECURE_SERVICE when | ||
%microsoft_ad_no_plaintext_password not empty | ||
!MICROSOFT_AD_PASSWORD_USES_SECURE_PARAMETER | ||
{ | ||
%microsoft_ad_no_plaintext_password.Properties.Password exists | ||
%microsoft_ad_no_plaintext_password.Properties.Password in [ /{{resolve\:secretsmanager\:.*}}/, /{{resolve\:ssm-secure\:.*}}/ ] | ||
<< | ||
Violation: Microsoft AD Password Endpoint password must not be a plaintext string or a Ref to a Parameter with a Default value. Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager value. | ||
Fix: Replace plaintext value with a secure one. | ||
>> | ||
} | ||
|
||
# One rule to rule them all... | ||
rule MICROSOFT_AD_NO_PLAINTEXT_PASSWORD when | ||
%microsoft_ad_no_plaintext_password not empty | ||
{ | ||
MICROSOFT_AD_PASSWORD_USES_SECURE_PARAMETER | ||
OR | ||
MICROSOFT_AD_PASSWORD_USES_SECURE_SERVICE | ||
} |
Oops, something went wrong.