Default rules
Rules are the heart of CFRipper. When running CFRipper the CloudFormation stack will be checked against each rule and the results combined.
Available Rules¶
BaseDangerousPolicyActions¶
Base class for dangerous actions. Admits a DANGEROUS_ACTIONS class variable with a list of dangerous actions
Severity: High
CloudFormationAuthenticationRule¶
Checks that any AWS::CloudFormation::Authentication
resource does not contain plain text credentials.
Severity: Medium
Risk¶
Secrets are stored in clear text and printed in clear text in the AWS console.
Fix¶
Do not store credentials in CloudFormation files, use parameters.
Code for fix¶
Parameters:
PasswordAuth:
NoEcho: true
Description: Some cool password
MinLength: 8
Type: String
...
Resources:
AWS::CloudFormation::Authentication:
...
password:
Ref: "PasswordAuth"
...
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
Resource |
Resource that is being addressed |
CrossAccountCheckingRule¶
Base class not intended to be instantiated, but inherited from. This class provides common methods used to detect access permissions from other accounts.
Severity: Medium
CrossAccountTrustRule¶
To be replaced by GenericCrossAccountTrustRule.
Checks if the trust policy of a role grants permissions to principals from other accounts. Do not use whole accounts as principals.
Severity: Medium
Risk¶
It might allow other AWS identities to escalate privileges.
Fix¶
If cross account permissions are required, the stack should be added to the allowlist for this rule. Otherwise, the access should be removed from the CloudFormation definition.
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str |
config variable available inside the rule |
extras |
str |
extras variable available inside the rule |
logical_id |
str |
ID used in CloudFormation to refer the resource being analysed |
resource |
IAMRole |
Resource that is being addressed |
statement |
Statement |
Statement being checked found in the Resource |
principal |
str |
AWS Principal being checked found in the statement |
account_id |
str |
Account ID found in the principal |
EBSVolumeHasSSERule¶
Checks that server side encryption is enabled for all EBS volumes.
Severity: Medium
Risk¶
Data that is not encrypted at rest could breach regulatory compliance and allow easier access for an attacker to view any instace storage data of your EC2 instance.
Fix¶
Enable server-side encryption on EBS volumes.
Code for fix¶
{
"Type" : "AWS::EC2::Volume",
"Properties" : {
...
"Encrypted" : true,
...
}
}
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
Resource |
EC2 Volume that is being addressed |
EC2SecurityGroupIngressOpenToWorldRule¶
Checks if security groups have an ingress IP that is open to the world for ports other than 80 and 443. All other ports should be closed off from public access to prevent a serious security misconfiguration.
Severity: Medium
Fix¶
Most security groups only need to be accessed privately, and
this can typically be done by specifying the CIDR of a Security Group's ingress to 10.0.0.0/8
or similar.
Unless required, do not use the following IP ranges in your Security Group Ingress:
-
0.0.0.0/0
. -
Any
/8
that does not start with 10. -
172/8
or192/8
(use172.16/12
and192.168/16
ranges, per RFC1918 specification).
As per RFC4193, fd00::/8
IPv6 addresses should be used to define a private network.
Code for fix¶
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
// this is compliant. Port 22 (typically SSH) is accessible from the private network only.
"InboundRule1": {
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties": {
"GroupId": {
"Fn::GetAtt": [
"TargetSG",
"GroupId"
]
},
"CidrIp": "10.0.0.0/8",
"IpProtocol": "tcp",
"FromPort": "22",
"ToPort": "22",
"SourceSecurityGroupId": "sg-12345678",
"SourceSecurityGroupOwnerId": "123456789012"
}
},
// this is not compliant. Anyone with the IP for this EC2 instance can connect on port 9090.
"InboundRule2": {
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties": {
"GroupId": {
"Fn::GetAtt": [
"TargetSG",
"GroupId"
]
},
"CidrIp": "0.0.0.0/0",
"IpProtocol": "tcp",
"FromPort": "9090",
"ToPort": "9090",
"SourceSecurityGroupId": "sg-12345678",
"SourceSecurityGroupOwnerId": "123456789012"
}
}
}
}
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
SecurityGroupIngress |
Resource that is being addressed |
ingress_ip |
str | IP Address range (IpV4 or IpV6) of the ingress object |
ingress_obj |
SecurityGroupIngressProperties |
SecurityGroupIngress being checked found in the Resource |
open_ports |
List[int] |
List of all open ports defined |
non_allowed_open_ports |
List[int] |
List of all non allowed open ports defined |
EC2SecurityGroupMissingEgressRule¶
Checks that Security Groups are defined with an egress policy, even if this is still allowing all outbound traffic.
Severity: Medium
Risk¶
If no egress rule is specified, the default is to open all outbound traffic to the world. Whilst some services may need this, it is usually the case that the security group can be locked down more. A NAT instance for example may require a completely open egress policy.
Allowing unrestricted (0.0.0.0/0
or ::/0
) outbound/egress access can increase opportunities for
malicious activity such as such as Denial of Service (DoS) attacks or Distributed Denial of Service (DDoS)
attacks.
Fix¶
Explicitly defining the egress policy for the security group.
Code for fix¶
Even in the example below, the egress rule added will allow HTTP traffic out to the world. However, this will pass the rule.
// example from https://stelligent.com/2016/04/07/finding-security-problems-early-in-the-development-process-of-a-cloudformation-template-with-cfn-nag/
{
"Resources": {
"sg": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "some_group_desc",
"SecurityGroupIngress": {
"CidrIp": "10.1.2.3/32",
"FromPort": 34,
"ToPort": 34,
"IpProtocol": "tcp"
},
// addition of egress to the `sg` resource
"SecurityGroupEgress": {
"CidrIp": "0.0.0.0/0",
"FromPort": 80,
"ToPort": 80,
"IpProtocol": "tcp"
},
"VpcId": "vpc-12345678"
}
}
}
}
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
SecurityGroup |
Resource that is being addressed |
EC2SecurityGroupOpenToWorldRule¶
Checks if security groups have an ingress IP that is open to the world for ports other than 80 and 443. All other ports should be closed off from public access to prevent a serious security misconfiguration.
Severity: Medium
Fix¶
Most security groups only need to be accessed privately, and
this can typically be done by specifying the CIDR of a Security Group's ingress to 10.0.0.0/8
or similar.
Unless required, do not use the following IP ranges in your Security Group Ingress:
-
0.0.0.0/0
. -
Any
/8
that does not start with 10. -
172/8
or192/8
(use172.16/12
and192.168/16
ranges, per RFC1918 specification).
As per RFC4193, fd00::/8
IPv6 addresses should be used to define a private network.
Code for fix¶
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"SecurityGroup": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {
"GroupDescription": "description",
"SecurityGroupIngress": [
// this is compliant. Port 22 (typically SSH) is accessible from the private network only.
{
"IpProtocol": "tcp",
"CidrIp": "10.0.0.0/8",
"FromPort": 22,
"ToPort": 22
},
// this is not compliant. Anyone with the IP for this EC2 instance can connect on port 9090.
{
"IpProtocol": "tcp",
"CidrIp": "0.0.0.0/0",
"FromPort": 9090,
"ToPort": 9090
}
]
}
}
}
}
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
SecurityGroup |
Resource that is being addressed |
ingress_ip |
str | IP Address range (IpV4 or IpV6) of the ingress object |
ingress_obj |
SecurityGroupIngressProp |
SecurityGroupIngressProp being checked found in the Resource |
open_ports |
List[int] |
List of all open ports defined |
non_allowed_open_ports |
List[int] |
List of all non allowed open ports defined |
ElasticsearchDomainCrossAccountTrustRule¶
To be replaced by GenericCrossAccountTrustRule.
Checks for Elasticsearch domains that allow cross-account principals to get access.
Severity: Medium
Risk¶
It might allow other AWS identities to read/modify data.
Fix¶
If cross account permissions are required for ES domains, the stack should be added to the allowlist for this rule. Otherwise, the access should be removed from the CloudFormation definition.
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str |
config variable available inside the rule |
extras |
str |
extras variable available inside the rule |
logical_id |
str |
ID used in CloudFormation to refer the resource being analysed |
resource |
ESDomain |
Resource that is being addressed |
statement |
Statement |
Statement being checked found in the Resource |
principal |
str |
AWS Principal being checked found in the statement |
account_id |
str |
Account ID found in the principal |
FullWildcardPrincipalRule¶
Checks for any wildcard principal defined in any statement.
Severity: High
Risk¶
It might allow other AWS identities to escalate privileges.
Fix¶
Where possible, restrict the access to only the required resources.
For example, instead of Principal: "*"
, include a list of the roles that need access.
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str |
config variable available inside the rule |
extras |
str |
extras variable available inside the rule |
logical_id |
str |
ID used in CloudFormation to refer the resource being analysed |
resource |
S3BucketPolicy |
Resource that is being addressed |
statement |
Statement |
Statement being checked found in the Resource |
principal |
str |
AWS Principal being checked found in the statement |
account_id |
str |
Account ID found in the principal |
GenericCrossAccountTrustRule¶
Checks if the trust policy of every resource grants permissions to principals from other accounts. Do not use whole accounts as principals. It doesn't check if policies allow permissions to assume roles in other accounts.
Severity: Medium
Risk¶
It might allow other AWS identities to escalate privileges.
Fix¶
If cross account permissions are required, the stack should be added to the allowlist for this rule. Otherwise, the access should be removed from the CloudFormation definition.
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str |
config variable available inside the rule |
extras |
str |
extras variable available inside the rule |
logical_id |
str |
ID used in CloudFormation to refer the resource being analysed |
resource |
Generic |
Resource that is being addressed |
statement |
Statement |
Statement being checked found in the Resource |
principal |
str |
AWS Principal being checked found in the statement |
account_id |
str |
Account ID found in the principal |
GenericResourceFullWildcardPrincipalRule¶
Checks for any wildcard principal defined in any statement.
Severity: High
Risk¶
It might allow other AWS identities to escalate privileges.
Fix¶
Where possible, restrict the access to only the required resources.
For example, instead of Principal: "*"
, include a list of the roles that need access.
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str |
config variable available inside the rule |
extras |
str |
extras variable available inside the rule |
logical_id |
str |
ID used in CloudFormation to refer the resource being analysed |
resource |
S3BucketPolicy |
Resource that is being addressed |
statement |
Statement |
Statement being checked found in the Resource |
principal |
str |
AWS Principal being checked found in the statement |
account_id |
str |
Account ID found in the principal |
GenericResourcePartialWildcardPrincipalRule¶
Checks for any wildcard or account-wide principals defined in any statements. This rule will flag
as non-compliant any principals where root
or *
are included at the end of the value, for
example, arn:aws:iam:12345:12345*
.
Severity: Medium
Risk¶
It might allow other AWS identities or the root access of the account to escalate privileges.
Fix¶
Where possible, restrict the access to only the required resources.
For example, instead of Principal: "*"
, include a list of the roles that need access.
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str |
config variable available inside the rule |
extras |
str |
extras variable available inside the rule |
logical_id |
str |
ID used in CloudFormation to refer the resource being analysed |
resource |
S3BucketPolicy |
Resource that is being addressed |
statement |
Statement |
Statement being checked found in the Resource |
principal |
str |
AWS Principal being checked found in the statement |
account_id |
str |
Account ID found in the principal |
GenericResourceWildcardPolicyRule¶
Rule that checks for use of a wildcard *
or ?
character in Actions of Policy Documents of Generic AWS Resources.
Severity: Medium
HardcodedRDSPasswordRule¶
Checks that any RDS clusters or instances aren't exposing their passwords.
The rule forbids default password parameters and any missing NoEcho
for RDS passwords.
Severity: Medium
Risk¶
Not setting this correctly can lead to malicious agents attempting to gain access to your
RDS instaces with a default password, or by reading the value that will be printed in plain
text in the AWS console and logs if NoEcho
is not set.
Fix¶
When defining a password do not use the default value. If you specify a default password and you don’t provide a parameter, it will use the default which can be found clear text in the CloudFormation file.
Code for fix¶
Parameters:
MasterUserPassword:
NoEcho: true
Description: The database admin account password
MinLength: 8
Type: String
...
Resources:
RDSCluster:
Type: AWS::RDS::DBCluster
DeletionPolicy: "Snapshot"
Properties:
...
MasterUserPassword: !Ref 'MasterUserPassword'
...
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
Resource |
Resource that is being addressed |
IAMRoleWildcardActionOnPolicyRule¶
Checks for use of wildcard characters in all IAM Role policies (including AssumeRolePolicyDocument
)
and AWS Managed Policies.
Severity: Medium
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
Union[IAMRole, IAMManagedPolicy] |
Resource that is being addressed |
IAMRolesOverprivilegedRule¶
Rule that checks for wildcards in resources for a set of actions and restricts managed policies.
Severity: Medium
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
IAMRole |
Resource that is being addressed |
statement |
Optional[Statement] |
Statement being checked found in the Resource |
action |
Optional[str] |
Action containing insecure permission with forbidden prefix |
KMSKeyCrossAccountTrustRule¶
To be replaced by GenericCrossAccountTrustRule.
Checks for KMS keys that allow cross-account principals to get access to the key.
Severity: Medium
Risk¶
It might allow other AWS identities to read/modify the secrets.
Fix¶
If cross account permissions are required for KMS access, the stack should be added to the allowlist for this rule. Otherwise, the access should be removed from the CloudFormation definition.
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str |
config variable available inside the rule |
extras |
str |
extras variable available inside the rule |
logical_id |
str |
ID used in CloudFormation to refer the resource being analysed |
resource |
KMSKey |
Resource that is being addressed |
statement |
Statement |
Statement being checked found in the Resource |
principal |
str |
AWS Principal being checked found in the statement |
account_id |
str |
Account ID found in the principal |
KMSKeyEnabledKeyRotation¶
Check if EnableKeyRotation is true for symmetric KMS keys in principals in KMS Policies.
Severity: High
Fix¶
Set EnableKeyRotation to true for any symmetric KMS key.
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
KMSKey |
Resource that is being addressed |
KMSKeyWildcardPrincipalRule¶
Check for wildcards in principals in KMS Policies.
Severity: Medium
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
KMSKey |
Resource that is being addressed |
statement |
Statement |
Statement being checked found in the Resource |
principal |
str | AWS Principal being checked found in the statement |
ManagedPolicyOnUserRule¶
Checks if any IAM managed policy is applied to a group and not a user.
Severity: Medium
Risk¶
Instead of defining permissions for individual IAM users, it's usually more convenient and secure to create IAM groups that relate to different functions. IAM users can be assigned to these groups. All the users in an IAM group inherit the permissions assigned to the group. That way, you can make changes for everyone in a group in just one place. As people move around in your company, you can simply change what IAM group their IAM user belongs to, without risking a user having too much privilege.
Fix¶
Use IAM Groups as opposed to users in IAM Managed Policies.
Code for fix¶
This is an example which will be flagged by CFRipper:
"BadPolicy": {
"Type": "AWS::IAM::ManagedPolicy",
"Properties": {
"Description": "Policy for something.",
"Path": "/",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [...]
},
"Users": [{"Ref": "TestUser"}]
}
}
This is an example of a more acceptable CloudFormation policy:
"GoodPolicy": {
"Type": "AWS::IAM::ManagedPolicy",
"Properties": {
"Description": "Policy for something.",
"Path": "/",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [...]
},
"Groups": ["user_group"]
}
}
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
IAMManagedPolicy |
Resource that is being addressed |
OpenSearchDomainCrossAccountTrustRule¶
To be replaced by GenericCrossAccountTrustRule.
Checks for OpenSearch domains that allow cross-account principals to get access.
Severity: Medium
Risk¶
It might allow other AWS identities to read/modify data.
Fix¶
If cross account permissions are required for OpenSearch domains, the stack should be added to the allowlist for this rule. Otherwise, the access should be removed from the CloudFormation definition.
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str |
config variable available inside the rule |
extras |
str |
extras variable available inside the rule |
logical_id |
str |
ID used in CloudFormation to refer the resource being analysed |
resource |
OpenSearchDomain |
Resource that is being addressed |
statement |
Statement |
Statement being checked found in the Resource |
principal |
str |
AWS Principal being checked found in the statement |
account_id |
str |
Account ID found in the principal |
PartialWildcardPrincipalRule¶
Checks for any wildcard or account-wide principals defined in any statements. This rule will flag
as non-compliant any principals where root
or *
are included at the end of the value, for
example, arn:aws:iam:12345:12345*
.
Severity: Medium
Risk¶
It might allow other AWS identities or the root access of the account to escalate privileges.
Fix¶
Where possible, restrict the access to only the required resources.
For example, instead of Principal: "*"
, include a list of the roles that need access.
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str |
config variable available inside the rule |
extras |
str |
extras variable available inside the rule |
logical_id |
str |
ID used in CloudFormation to refer the resource being analysed |
resource |
S3BucketPolicy |
Resource that is being addressed |
statement |
Statement |
Statement being checked found in the Resource |
principal |
str |
AWS Principal being checked found in the statement |
account_id |
str |
Account ID found in the principal |
PolicyOnUserRule¶
Checks if any IAM policy is applied to a group and not a user.
Severity: Medium
Risk¶
Instead of defining permissions for individual IAM users, it's usually more convenient and secure to create IAM groups that relate to different functions. IAM users can be assigned to these groups. All the users in an IAM group inherit the permissions assigned to the group. That way, you can make changes for everyone in a group in just one place. As people move around in your company, you can simply change what IAM group their IAM user belongs to, without risking a user having too much privilege.
Fix¶
Use IAM Groups as opposed to users in IAM Policies.
Code for fix¶
This is an example which will be flagged by CFRipper:
"BadPolicy": {
"Type": "AWS::IAM::Policy",
"Properties": {
"Description": "Policy for something.",
"Path": "/",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [...]
},
"Users": [{"Ref": "TestUser"}]
}
}
This is an example of a more acceptable CloudFormation policy:
"GoodPolicy": {
"Type": "AWS::IAM::Policy",
"Properties": {
"Description": "Policy for something.",
"Path": "/",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [...]
},
"Groups": ["user_group"]
}
}
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
IAMPolicy |
Resource that is being addressed |
PrincipalCheckingRule¶
Abstract class for rules that check principals.
valid_principals
is a set of the following Account IDs and Canonical IDs:
- aws_principals
set in the user defined config (default = None)
- ELB Log Account IDs from AWS
- ElastiCache Backup Canonical IDs
- (if defined) The AWS Account in the config which CFRipper is executing with
When using valid_principals
, make sure the scope of accounts allowed is not too large.
It might be the case that the account the stack is being deployed in is in this set.
This could raise false negatives in rules. If a rule should only be exempt for AWS Service
IDs, such as ELB and ElastiCache, consider using _get_allowed_from_config()
directly.
Severity: Medium
PrivilegeEscalationRule¶
Base class for dangerous actions. Admits a DANGEROUS_ACTIONS class variable with a list of dangerous actions
Severity: High
PublicELBCheckerRule¶
Rule to check if a public facing ELB is being created.
Severity: Low
RDSSecurityGroupIngressOpenToWorldRule¶
Checks if RDS native security groups have an ingress IP that is open to the world.
Severity: High
Fix¶
Most security groups only need to be [accessed privately](https://en.wikipedia.org/wiki/Private_network), and
this can typically be done by specifying the CIDR of a Security Group's ingress to `10.0.0.0/8` or similar.
Unless required, do not use the following IP ranges in your Security Group Ingress:
- `0.0.0.0/0`.
- Any `/8` that does not start with 10.
- `172/8` or `192/8` (use `172.16/12` and `192.168/16` ranges, per RFC1918 specification).
As per RFC4193, `fd00::/8` IPv6 addresses should be used to define a private network.
Code example:
```yaml
Resources:
CompliantRDSSecurityGroup:
Type: AWS::RDS::DBSecurityGroup
Properties:
EC2VpcId: "vpc-id"
DBSecurityGroupIngress:
- CIDRIP: 10.0.0.0/8
GroupDescription: Compliant RDS security group
NonCompliantRDSSecurityGroup:
Type: AWS::RDS::DBSecurityGroup
Properties:
EC2VpcId: "vpc-id"
DBSecurityGroupIngress:
- CIDRIP: 0.0.0.0/0
GroupDescription: Risky RDS security group
```
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
RDSDBSecurityGroup/RDSDBSecurityGroupIngress |
Resource that is being addressed |
ingress_obj |
DBSecurityGroupIngressProp |
DBSecurityGroupIngress being checked found in the Resource |
ResourceSpecificRule¶
Base class for rules that only apply to a subset of resource types.
RESOURCE_TYPES: Resources to invoke the rule for. EXCLUDED_RESOURCE_TYPES: Resources to explicitly not run the rule for.
Both fields are included to allow for more granular rule definitions. For example, you may want to allow all resources except S3BucketPolicies, in which case you would define these variables as:
EXCLUDED_RESOURCE_TYPES = (S3BucketPolicy,) RESOURCE_TYPES = (Resource,)
Where the S3BucketPolicy
Resource inherits from the base Resource
class.
Severity: Medium
S3BucketPolicyPrincipalRule¶
Checks for non-allowed principals in S3 bucket policies.
Severity: High
Risk¶
This is designed to block unintended access from third party accounts to your buckets.
Fix¶
All principals connected to S3 Bucket Policies should be known. CFRipper checks that all principals meet
the requirements expected. The list of valid accounts is defined in valid_principals
, which is set in the config.
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
S3BucketPolicy |
Resource that is being addressed |
statement |
Statement |
Statement being checked found in the Resource |
principal |
str | AWS Principal being checked found in the statement |
account_id |
str | Account ID found in the principal |
S3BucketPolicyWildcardActionRule¶
Soon to be replaced by GenericResourceWildcardPolicyRule
.
Checks for use of the wildcard *
character in the Actions of Policy Documents of S3 Bucket Policies.
This rule is a subclass of GenericWildcardPolicyRule
.
Severity: Medium
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
S3BucketPolicy |
Resource that is being addressed |
S3BucketPublicReadAclAndListStatementRule¶
Checks if any S3 bucket policy has a public read ACL and List
permission in the bucket policy.
Severity: Medium
Fix¶
Unless the bucket is hosting static content and needs to be accessed publicly, these bucket policies should be locked down.
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
S3BucketPolicy |
Resource that is being addressed |
bucket_name |
str | Name of the S3 bucket being analysed |
S3BucketPublicReadAclRule¶
Checks if any S3 bucket policy has access control set to PublicRead
.
Severity: High
Risk¶
Unless the bucket is hosting static content, S3 buckets should not have Public Read available on a bucket. This allows anyone to read any objects to your S3 bucket.
Fix¶
Remove any configuration that looks like "AccessControl": "PublicRead"
from your S3 bucket policy.
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
S3Bucket |
S3 Bucket that is being addressed |
S3BucketPublicReadWriteAclRule¶
Checks if any S3 bucket policy has access control set to PublicReadWrite
.
Severity: High
Risk¶
Unless required, S3 buckets should not have Public Write available on a bucket. This allows anyone to write any objects to your S3 bucket.
Fix¶
Remove any configuration that looks like "AccessControl": "PublicReadWrite"
from your S3 bucket policy.
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
S3Bucket |
S3 Bucket that is being addressed |
S3CrossAccountTrustRule¶
To be replaced by GenericCrossAccountTrustRule.
Check for cross account access in S3 bucket policies. Cross account access by default should not be allowed.
Severity: Medium
Risk¶
It might allow other AWS identities to access/modify content of the bucket.
Fix¶
If cross account permissions are required for S3 access, the stack should be added to the allowlist for this rule. Otherwise, the access should be removed from the CloudFormation definition.
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str |
config variable available inside the rule |
extras |
str |
extras variable available inside the rule |
logical_id |
str |
ID used in CloudFormation to refer the resource being analysed |
resource |
S3BucketPolicy |
Resource that is being addressed |
statement |
Statement |
Statement being checked found in the Resource |
principal |
str |
AWS Principal being checked found in the statement |
account_id |
str |
Account ID found in the principal |
S3LifecycleConfigurationRule¶
Checks for the presence of LifecycleConfiguration
on S3 buckets.
These rules can help with security, compliance, and reduce AWS Costs. The rule does not
check the specific rules contained with the LifecycleConfiguration
key.
Severity: Low
Fix¶
Add LifecycleConfiguration
property to the S3 Bucket as defined in
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-lifecycleconfig.html.
Code for fix¶
An example rule is included within the configuration.
Resources:
S3Bucket:
Type: AWS::S3::Bucket
Properties:
...
LifecycleConfiguration:
Rules:
- Status: Enabled
Prefix: logs/
ExpirationInDays: 7
...
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
S3Bucket |
Resource that is being addressed |
S3ObjectVersioningRule¶
Checks if the S3 bucket has object versioning enabled or not.
Severity: Low
Risk¶
Not having this property enabled could make the bucket more vulnerable to ransomware attacks. Bucket versioning allows the automatic creation of multiple versions of an object. When an object is deleted with versioning turned on, it is only marked as deleted but is still retrievable.
Fix¶
Add VersioningConfiguration
property with the value Enabled
to bucket as defined in the
AWS documentation.
Code for fix¶
Resources:
S3Bucket:
Type: AWS::S3::Bucket
Properties:
...
VersioningConfiguration:
Status: Enabled
...
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
S3Bucket |
Resource that is being addressed |
SNSTopicDangerousPolicyActionsRule¶
Base class for dangerous actions. Admits a DANGEROUS_ACTIONS class variable with a list of dangerous actions
Severity: Medium
SNSTopicPolicyNotPrincipalRule¶
Checks if an SNS topic policy has an Allow + a NotPrincipal.
Severity: Medium
Risk¶
AWS strongly recommends against using NotPrincipal
in the same policy statement as "Effect": "Allow"
.
Doing so grants the permissions specified in the policy statement to all principals except the one named
in the NotPrincipal
element. By doing this, you might grant access to anonymous (unauthenticated) users.
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
SNSTopicPolicy |
Resource that is being addressed |
statement |
Statement |
Statement being checked found in the Resource |
SNSTopicPolicyWildcardActionRule¶
Soon to be replaced by GenericResourceWildcardPolicyRule
.
Checks for use of the wildcard *
character in the Actions of Policy Documents of SQS Queue Policies.
This rule is a subclass of GenericWildcardPolicyRule
.
Severity: Medium
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
SNSTopicPolicy |
Resource that is being addressed |
SQSDangerousPolicyActionsRule¶
Base class for dangerous actions. Admits a DANGEROUS_ACTIONS class variable with a list of dangerous actions
Severity: Medium
SQSQueuePolicyNotPrincipalRule¶
Checks if an SQS Queue policy has an Allow + a NotPrincipal.
Severity: Medium
Risk¶
AWS strongly recommends against using NotPrincipal
in the same policy statement as "Effect": "Allow"
.
Doing so grants the permissions specified in the policy statement to all principals except the one named
in the NotPrincipal
element. By doing this, you might grant access to anonymous (unauthenticated) users.
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
SQSQueuePolicy |
Resource that is being addressed |
statement |
Statement |
Statement being checked found in the Resource |
SQSQueuePolicyPublicRule¶
Checks for wildcard principals in Allow statements in an SQS Queue Policy.
Severity: High
Risk¶
This is deemed a potential security risk as anyone would be able to interact with your queue.
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
SQSQueuePolicy |
Resource that is being addressed |
statement |
Statement |
Statement being checked found in the Resource |
SQSQueuePolicyWildcardActionRule¶
Soon to be replaced by GenericResourceWildcardPolicyRule
.
Checks for use of the wildcard *
character in the Actions of Policy Documents of SQS Queue Policies.
This rule is a subclass of GenericWildcardPolicyRule
.
Severity: Medium
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str | config variable available inside the rule |
extras |
str | extras variable available inside the rule |
logical_id |
str | ID used in Cloudformation to refer the resource being analysed |
resource |
SQSQueuePolicy |
Resource that is being addressed |
StackNameMatchesRegexRule¶
Checks that a given stack follows the naming convention given by a regex. For this to work, the stack name must be given either in the config or in the extras using the key "stack_name".
Severity: Low
Defaults to debug mode (rule not enforced)
StorageEncryptedRule¶
Severity: Low
Defaults to debug mode (rule not enforced)
WildcardResourceRule¶
Generic rule that detects actions that accept a resource and are using a wildcard.
Severity: Medium
Risk¶
Give roles access to undesired resources.
Fix¶
Check AWS docs to use the recommended resource value.
Filters context¶
Parameter | Type | Description |
---|---|---|
config |
str |
config variable available inside the rule |
extras |
str |
extras variable available inside the rule |
logical_id |
str |
ID used in CloudFormation to refer the resource being analysed |
policy_name |
Optional[str] |
If available, the policy name |
statement |
Statement |
Statement being checked found in the Resource |
action |
Optional[str] |
Action that has a wildcard resource. If None, means all actions |
Monitor Mode¶
By default, each rule has MONITOR_MODE
set to false. Monitor model will return the failed rules in another field in the
response, instead in the main "failed rules". This way new rules can be tested before they are removed from monitor
mode and start triggering alarms.