ec2

package
v1.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 17, 2023 License: MIT Imports: 10 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var CheckASEnableAtRestEncryption = rules.Register(
	scan.Rule{
		AVDID:       "AVD-AWS-0008",
		Aliases:     []string{"aws-autoscaling-enable-at-rest-encryption"},
		Provider:    providers.AWSProvider,
		Service:     "ec2",
		ShortCode:   "enable-launch-config-at-rest-encryption",
		Summary:     "Launch configuration with unencrypted block device.",
		Impact:      "The block device could be compromised and read from",
		Resolution:  "Turn on encryption for all block devices",
		Explanation: `Block devices should be encrypted to ensure sensitive data is held securely at rest.`,
		Links: []string{
			"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/RootDeviceStorage.html",
		},
		Terraform: &scan.EngineMetadata{
			GoodExamples:        terraformASEnableAtRestEncryptionGoodExamples,
			BadExamples:         terraformASEnableAtRestEncryptionBadExamples,
			Links:               terraformASEnableAtRestEncryptionLinks,
			RemediationMarkdown: terraformASEnableAtRestEncryptionRemediationMarkdown,
		},
		CloudFormation: &scan.EngineMetadata{
			GoodExamples:        cloudFormationASEnableAtRestEncryptionGoodExamples,
			BadExamples:         cloudFormationASEnableAtRestEncryptionBadExamples,
			Links:               cloudFormationASEnableAtRestEncryptionLinks,
			RemediationMarkdown: cloudFormationASEnableAtRestEncryptionRemediationMarkdown,
		},
		Severity: severity.High,
	},
	func(s *state.State) (results scan.Results) {
		for _, launchConfig := range s.AWS.EC2.LaunchConfigurations {
			if launchConfig.RootBlockDevice != nil && launchConfig.RootBlockDevice.Encrypted.IsFalse() {
				results.Add(
					"Root block device is not encrypted.",
					launchConfig.RootBlockDevice.Encrypted,
				)
			} else {
				results.AddPassed(&launchConfig)
			}
			for _, device := range launchConfig.EBSBlockDevices {
				if device.Encrypted.IsFalse() {
					results.Add(
						"EBS block device is not encrypted.",
						device.Encrypted,
					)
				} else {
					results.AddPassed(device)
				}
			}
		}
		return
	},
)
View Source
var CheckASIMDSAccessRequiresToken = rules.Register(
	scan.Rule{
		AVDID:      "AVD-AWS-0130",
		Aliases:    []string{"aws-autoscaling-enforce-http-token-imds"},
		Provider:   providers.AWSProvider,
		Service:    "ec2",
		ShortCode:  "enforce-launch-config-http-token-imds",
		Summary:    "aws_instance should activate session tokens for Instance Metadata Service.",
		Impact:     "Instance metadata service can be interacted with freely",
		Resolution: "Enable HTTP token requirement for IMDS",
		Explanation: `
IMDS v2 (Instance Metadata Service) introduced session authentication tokens which improve security when talking to IMDS.
By default <code>aws_instance</code> resource sets IMDS session auth tokens to be optional. 
To fully protect IMDS you need to enable session tokens by using <code>metadata_options</code> block and its <code>http_tokens</code> variable set to <code>required</code>.
`,

		Links: []string{
			"https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service",
		},

		Terraform: &scan.EngineMetadata{
			GoodExamples:        terraformASEnforceHttpTokenImdsGoodExamples,
			BadExamples:         terraformASEnforceHttpTokenImdsBadExamples,
			Links:               terraformASEnforceHttpTokenImdsLinks,
			RemediationMarkdown: terraformASEnforceHttpTokenImdsRemediationMarkdown,
		},
		CloudFormation: &scan.EngineMetadata{
			GoodExamples:        cloudformationASEnforceHttpTokenImdsGoodExamples,
			BadExamples:         cloudformationASEnforceHttpTokenImdsBadExamples,
			Links:               cloudformationASEnforceHttpTokenImdsLinks,
			RemediationMarkdown: cloudformationASEnforceHttpTokenImdsRemediationMarkdown,
		},
		Severity: severity.High,
	},
	func(s *state.State) (results scan.Results) {
		for _, configuration := range s.AWS.EC2.LaunchConfigurations {
			if !configuration.RequiresIMDSToken() && !configuration.HasHTTPEndpointDisabled() {
				results.Add(
					"Launch configuration does not require IMDS access to require a token",
					configuration.MetadataOptions.HttpTokens,
				)
			} else {
				results.AddPassed(&configuration)
			}
		}
		for _, instance := range s.AWS.EC2.LaunchTemplates {
			if !instance.RequiresIMDSToken() && !instance.HasHTTPEndpointDisabled() {
				results.Add(
					"Launch template does not require IMDS access to require a token",
					instance.MetadataOptions.HttpTokens,
				)
			} else {
				results.AddPassed(&instance)
			}
		}
		return results
	},
)
View Source
var CheckASNoSecretsInUserData = rules.Register(
	scan.Rule{
		AVDID:       "AVD-AWS-0129",
		Aliases:     []string{"aws-autoscaling-no-secrets-in-user-data"},
		Provider:    providers.AWSProvider,
		Service:     "ec2",
		ShortCode:   "no-secrets-in-launch-template-user-data",
		Summary:     "User data for EC2 instances must not contain sensitive AWS keys",
		Impact:      "User data is visible through the AWS Management console",
		Resolution:  "Remove sensitive data from the EC2 instance user-data generated by launch templates",
		Explanation: `EC2 instance data is used to pass start up information into the EC2 instance. This userdata must not contain access key credentials. Instead use an IAM Instance Profile assigned to the instance to grant access to other AWS Services.`,
		Links: []string{
			"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-add-user-data.html",
		},
		Terraform: &scan.EngineMetadata{
			GoodExamples:        terraformASNoSecretsInUserDataGoodExamples,
			BadExamples:         terraformASNoSecretsInUserDataBadExamples,
			Links:               terraformASNoSecretsInUserDataLinks,
			RemediationMarkdown: terraformASNoSecretsInUserDataRemediationMarkdown,
		},
		CloudFormation: &scan.EngineMetadata{
			GoodExamples:        cloudFormationASNoSecretsInUserDataGoodExamples,
			BadExamples:         cloudFormationASNoSecretsInUserDataBadExamples,
			Links:               cloudFormationASNoSecretsInUserDataLinks,
			RemediationMarkdown: cloudFormationASNoSecretsInUserDataRemediationMarkdown,
		},
		Severity: severity.Critical,
	},
	func(s *state.State) (results scan.Results) {
		for _, instance := range s.AWS.EC2.LaunchTemplates {
			if instance.Metadata.IsUnmanaged() {
				continue
			}
			if result := scanner.Scan(instance.UserData.Value()); result.TransgressionFound {
				results.Add(
					fmt.Sprintf("Sensitive data found in launch template user data: %s", result.Description),
					instance.UserData,
				)
			} else {
				results.AddPassed(&instance)
			}
		}
		return
	},
)
View Source
var CheckAddDescriptionToSecurityGroup = rules.Register(
	scan.Rule{
		AVDID:      "AVD-AWS-0099",
		Aliases:    []string{"aws-vpc-add-description-to-security-group"},
		Provider:   providers.AWSProvider,
		Service:    "ec2",
		ShortCode:  "add-description-to-security-group",
		Summary:    "Missing description for security group.",
		Impact:     "Descriptions provide context for the firewall rule reasons",
		Resolution: "Add descriptions for all security groups",
		Explanation: `Security groups should include a description for auditing purposes.

Simplifies auditing, debugging, and managing security groups.`,
		Links: []string{
			"https://www.cloudconformity.com/knowledge-base/aws/EC2/security-group-rules-description.html",
		},
		Terraform: &scan.EngineMetadata{
			GoodExamples:        terraformAddDescriptionToSecurityGroupGoodExamples,
			BadExamples:         terraformAddDescriptionToSecurityGroupBadExamples,
			Links:               terraformAddDescriptionToSecurityGroupLinks,
			RemediationMarkdown: terraformAddDescriptionToSecurityGroupRemediationMarkdown,
		},
		CloudFormation: &scan.EngineMetadata{
			GoodExamples:        cloudFormationAddDescriptionToSecurityGroupGoodExamples,
			BadExamples:         cloudFormationAddDescriptionToSecurityGroupBadExamples,
			Links:               cloudFormationAddDescriptionToSecurityGroupLinks,
			RemediationMarkdown: cloudFormationAddDescriptionToSecurityGroupRemediationMarkdown,
		},
		Severity: severity.Low,
	},
	func(s *state.State) (results scan.Results) {
		for _, group := range s.AWS.EC2.SecurityGroups {
			if group.Metadata.IsUnmanaged() {
				continue
			}
			if group.Description.IsEmpty() {
				results.Add(
					"Security group does not have a description.",
					group.Description,
				)
			} else if group.Description.EqualTo("Managed by Terraform") {
				results.Add(
					"Security group explicitly uses the default description.",
					group.Description,
				)
			} else {
				results.AddPassed(&group)
			}
		}
		return
	},
)
View Source
var CheckAddDescriptionToSecurityGroupRule = rules.Register(
	scan.Rule{
		AVDID:      "AVD-AWS-0124",
		Aliases:    []string{"aws-vpc-add-description-to-security-group-rule"},
		Provider:   providers.AWSProvider,
		Service:    "ec2",
		ShortCode:  "add-description-to-security-group-rule",
		Summary:    "Missing description for security group rule.",
		Impact:     "Descriptions provide context for the firewall rule reasons",
		Resolution: "Add descriptions for all security groups rules",
		Explanation: `Security group rules should include a description for auditing purposes.

Simplifies auditing, debugging, and managing security groups.`,
		Links: []string{
			"https://www.cloudconformity.com/knowledge-base/aws/EC2/security-group-rules-description.html",
		},
		Terraform: &scan.EngineMetadata{
			GoodExamples:        terraformAddDescriptionToSecurityGroupRuleGoodExamples,
			BadExamples:         terraformAddDescriptionToSecurityGroupRuleBadExamples,
			Links:               terraformAddDescriptionToSecurityGroupRuleLinks,
			RemediationMarkdown: terraformAddDescriptionToSecurityGroupRuleRemediationMarkdown,
		},
		CloudFormation: &scan.EngineMetadata{
			GoodExamples:        cloudFormationAddDescriptionToSecurityGroupRuleGoodExamples,
			BadExamples:         cloudFormationAddDescriptionToSecurityGroupRuleBadExamples,
			Links:               cloudFormationAddDescriptionToSecurityGroupRuleLinks,
			RemediationMarkdown: cloudFormationAddDescriptionToSecurityGroupRuleRemediationMarkdown,
		},
		Severity: severity.Low,
	},
	func(s *state.State) (results scan.Results) {
		for _, group := range s.AWS.EC2.SecurityGroups {
			for _, rule := range append(group.EgressRules, group.IngressRules...) {
				if rule.Description.IsEmpty() {
					results.Add(
						"Security group rule does not have a description.",
						rule.Description,
					)
				} else {
					results.AddPassed(&rule)
				}
			}

		}
		return
	},
)
View Source
var CheckEnableAtRestEncryption = rules.Register(
	scan.Rule{
		AVDID:       "AVD-AWS-0131",
		Provider:    providers.AWSProvider,
		Service:     "ec2",
		ShortCode:   "enable-at-rest-encryption",
		Summary:     "Instance with unencrypted block device.",
		Impact:      "The block device could be compromised and read from",
		Resolution:  "Turn on encryption for all block devices",
		Explanation: `Block devices should be encrypted to ensure sensitive data is held securely at rest.`,
		Links: []string{
			"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/RootDeviceStorage.html",
		},
		Terraform: &scan.EngineMetadata{
			GoodExamples:        terraformEnableAtRestEncryptionGoodExamples,
			BadExamples:         terraformEnableAtRestEncryptionBadExamples,
			Links:               terraformEnableAtRestEncryptionLinks,
			RemediationMarkdown: terraformEnableAtRestEncryptionRemediationMarkdown,
		},
		CloudFormation: &scan.EngineMetadata{
			GoodExamples:        cloudFormationEnableAtRestEncryptionGoodExamples,
			BadExamples:         cloudFormationEnableAtRestEncryptionBadExamples,
			Links:               cloudFormationEnableAtRestEncryptionLinks,
			RemediationMarkdown: cloudFormationEnableAtRestEncryptionRemediationMarkdown,
		},
		Severity: severity.High,
	},
	func(s *state.State) (results scan.Results) {
		for _, instance := range s.AWS.EC2.Instances {
			if instance.RootBlockDevice != nil && instance.RootBlockDevice.Encrypted.IsFalse() {
				results.Add(
					"Root block device is not encrypted.",
					instance.RootBlockDevice.Encrypted,
				)
			} else {
				results.AddPassed(&instance)
			}
			for _, device := range instance.EBSBlockDevices {
				if device.Encrypted.IsFalse() {
					results.Add(
						"EBS block device is not encrypted.",
						device.Encrypted,
					)
				} else {
					results.AddPassed(device)
				}
			}
		}
		return
	},
)
View Source
var CheckEnableVolumeEncryption = rules.Register(
	scan.Rule{
		AVDID:       "AVD-AWS-0026",
		Aliases:     []string{"aws-ebs-enable-volume-encryption"},
		Provider:    providers.AWSProvider,
		Service:     "ec2",
		ShortCode:   "enable-volume-encryption",
		Summary:     "EBS volumes must be encrypted",
		Impact:      "Unencrypted sensitive data is vulnerable to compromise.",
		Resolution:  "Enable encryption of EBS volumes",
		Explanation: `By enabling encryption on EBS volumes you protect the volume, the disk I/O and any derived snapshots from compromise if intercepted.`,
		Links:       []string{"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html"},
		Terraform: &scan.EngineMetadata{
			GoodExamples:        terraformEnableVolumeEncryptionGoodExamples,
			BadExamples:         terraformEnableVolumeEncryptionBadExamples,
			Links:               terraformEnableVolumeEncryptionLinks,
			RemediationMarkdown: terraformEnableVolumeEncryptionRemediationMarkdown,
		},
		CloudFormation: &scan.EngineMetadata{
			GoodExamples:        cloudFormationEnableVolumeEncryptionGoodExamples,
			BadExamples:         cloudFormationEnableVolumeEncryptionBadExamples,
			Links:               cloudFormationEnableVolumeEncryptionLinks,
			RemediationMarkdown: cloudFormationEnableVolumeEncryptionRemediationMarkdown,
		},
		Severity: severity.High,
	},
	func(s *state.State) (results scan.Results) {
		for _, volume := range s.AWS.EC2.Volumes {
			if volume.Metadata.IsUnmanaged() {
				continue
			}
			if volume.Encryption.Enabled.IsFalse() {
				results.Add(
					"EBS volume is not encrypted.",
					volume.Encryption.Enabled,
				)
			} else {
				results.AddPassed(&volume)
			}
		}
		return
	},
)
View Source
var CheckEncryptionCustomerKey = rules.Register(
	scan.Rule{
		AVDID:       "AVD-AWS-0027",
		Aliases:     []string{"aws-ebs-encryption-customer-key"},
		Provider:    providers.AWSProvider,
		Service:     "ec2",
		ShortCode:   "volume-encryption-customer-key",
		Summary:     "EBS volume encryption should use Customer Managed Keys",
		Impact:      "Using AWS managed keys does not allow for fine grained control",
		Resolution:  "Enable encryption using customer managed keys",
		Explanation: `Encryption using AWS keys provides protection for your EBS volume. To increase control of the encryption and manage factors like rotation use customer managed keys.`,
		Links:       []string{"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSEncryption.html"},
		Terraform: &scan.EngineMetadata{
			GoodExamples:        terraformEncryptionCustomerKeyGoodExamples,
			BadExamples:         terraformEncryptionCustomerKeyBadExamples,
			Links:               terraformEncryptionCustomerKeyLinks,
			RemediationMarkdown: terraformEncryptionCustomerKeyRemediationMarkdown,
		},
		CloudFormation: &scan.EngineMetadata{
			GoodExamples:        cloudFormationEncryptionCustomerKeyGoodExamples,
			BadExamples:         cloudFormationEncryptionCustomerKeyBadExamples,
			Links:               cloudFormationEncryptionCustomerKeyLinks,
			RemediationMarkdown: cloudFormationEncryptionCustomerKeyRemediationMarkdown,
		},
		Severity: severity.Low,
	},
	func(s *state.State) (results scan.Results) {
		for _, volume := range s.AWS.EC2.Volumes {
			if volume.Metadata.IsUnmanaged() {
				continue
			}
			if volume.Encryption.KMSKeyID.IsEmpty() {
				results.Add(
					"EBS volume does not use a customer-managed KMS key.",
					volume.Encryption.KMSKeyID,
				)
			} else {
				results.AddPassed(&volume)
			}
		}
		return
	},
)
View Source
var CheckIMDSAccessRequiresToken = rules.Register(
	scan.Rule{
		AVDID:      "AVD-AWS-0028",
		Provider:   providers.AWSProvider,
		Service:    "ec2",
		ShortCode:  "enforce-http-token-imds",
		Summary:    "aws_instance should activate session tokens for Instance Metadata Service.",
		Impact:     "Instance metadata service can be interacted with freely",
		Resolution: "Enable HTTP token requirement for IMDS",
		Explanation: `
IMDS v2 (Instance Metadata Service) introduced session authentication tokens which improve security when talking to IMDS.
By default <code>aws_instance</code> resource sets IMDS session auth tokens to be optional. 
To fully protect IMDS you need to enable session tokens by using <code>metadata_options</code> block and its <code>http_tokens</code> variable set to <code>required</code>.
`,

		Links: []string{
			"https://aws.amazon.com/blogs/security/defense-in-depth-open-firewalls-reverse-proxies-ssrf-vulnerabilities-ec2-instance-metadata-service",
		},

		Terraform: &scan.EngineMetadata{
			GoodExamples:        terraformEnforceHttpTokenImdsGoodExamples,
			BadExamples:         terraformEnforceHttpTokenImdsBadExamples,
			Links:               terraformEnforceHttpTokenImdsLinks,
			RemediationMarkdown: terraformEnforceHttpTokenImdsRemediationMarkdown,
		},
		Severity: severity.High,
	},
	func(s *state.State) (results scan.Results) {
		for _, instance := range s.AWS.EC2.Instances {
			if !instance.RequiresIMDSToken() && !instance.HasHTTPEndpointDisabled() {
				results.Add(
					"Instance does not require IMDS access to require a token",
					instance.MetadataOptions.HttpTokens,
				)
			} else {
				results.AddPassed(&instance)
			}
		}
		return results
	},
)
View Source
var CheckNoDefaultVpc = rules.Register(
	scan.Rule{
		AVDID:       "AVD-AWS-0101",
		Aliases:     []string{"aws-vpc-no-default-vpc"},
		Provider:    providers.AWSProvider,
		Service:     "ec2",
		ShortCode:   "no-default-vpc",
		Summary:     "AWS best practice to not use the default VPC for workflows",
		Impact:      "The default VPC does not have critical security features applied",
		Resolution:  "Create a non-default vpc for resources to be created in",
		Explanation: `Default VPC does not have a lot of the critical security features that standard VPC comes with, new resources should not be created in the default VPC and it should not be present in the Terraform.`,
		Links: []string{
			"https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html",
		},
		Terraform: &scan.EngineMetadata{
			GoodExamples:        terraformNoDefaultVpcGoodExamples,
			BadExamples:         terraformNoDefaultVpcBadExamples,
			Links:               terraformNoDefaultVpcLinks,
			RemediationMarkdown: terraformNoDefaultVpcRemediationMarkdown,
		},
		Severity: severity.High,
	},
	func(s *state.State) (results scan.Results) {
		for _, def := range s.AWS.EC2.VPCs {
			if def.IsDefault.IsTrue() {
				results.Add(
					"Default VPC is used.",
					&def,
				)
			}
		}
		return
	},
)
View Source
var CheckNoExcessivePortAccess = rules.Register(
	scan.Rule{
		AVDID:       "AVD-AWS-0102",
		Aliases:     []string{"aws-vpc-no-excessive-port-access"},
		Provider:    providers.AWSProvider,
		Service:     "ec2",
		ShortCode:   "no-excessive-port-access",
		Summary:     "An Network ACL rule allows ALL ports.",
		Impact:      "All ports exposed for ingressing/egressing data",
		Resolution:  "Set specific allowed ports",
		Explanation: `Ensure access to specific required ports is allowed, and nothing else.`,
		Links: []string{
			"https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html",
		},
		Terraform: &scan.EngineMetadata{
			GoodExamples:        terraformNoExcessivePortAccessGoodExamples,
			BadExamples:         terraformNoExcessivePortAccessBadExamples,
			Links:               terraformNoExcessivePortAccessLinks,
			RemediationMarkdown: terraformNoExcessivePortAccessRemediationMarkdown,
		},
		CloudFormation: &scan.EngineMetadata{
			GoodExamples:        cloudFormationNoExcessivePortAccessGoodExamples,
			BadExamples:         cloudFormationNoExcessivePortAccessBadExamples,
			Links:               cloudFormationNoExcessivePortAccessLinks,
			RemediationMarkdown: cloudFormationNoExcessivePortAccessRemediationMarkdown,
		},
		Severity: severity.Critical,
	},
	func(s *state.State) (results scan.Results) {
		for _, acl := range s.AWS.EC2.NetworkACLs {
			for _, rule := range acl.Rules {
				if rule.Action.EqualTo("allow") && rule.Protocol.EqualTo("-1") || rule.Protocol.EqualTo("all") {
					results.Add(
						"Network ACL rule allows access using ALL ports.",
						rule.Protocol,
					)
				} else {
					results.AddPassed(&rule)
				}
			}
		}
		return
	},
)
View Source
var CheckNoPublicEgressSgr = rules.Register(
	scan.Rule{
		AVDID:       "AVD-AWS-0104",
		Aliases:     []string{"aws-vpc-no-public-egress-sgr"},
		Provider:    providers.AWSProvider,
		Service:     "ec2",
		ShortCode:   "no-public-egress-sgr",
		Summary:     "An egress security group rule allows traffic to /0.",
		Impact:      "Your port is egressing data to the internet",
		Resolution:  "Set a more restrictive cidr range",
		Explanation: `Opening up ports to connect out to the public internet is generally to be avoided. You should restrict access to IP addresses or ranges that are explicitly required where possible.`,
		Links: []string{
			"https://docs.aws.amazon.com/whitepapers/latest/building-scalable-secure-multi-vpc-network-infrastructure/centralized-egress-to-internet.html",
		},
		Terraform: &scan.EngineMetadata{
			GoodExamples:        terraformNoPublicEgressSgrGoodExamples,
			BadExamples:         terraformNoPublicEgressSgrBadExamples,
			Links:               terraformNoPublicEgressSgrLinks,
			RemediationMarkdown: terraformNoPublicEgressSgrRemediationMarkdown,
		},
		CloudFormation: &scan.EngineMetadata{
			GoodExamples:        cloudFormationNoPublicEgressSgrGoodExamples,
			BadExamples:         cloudFormationNoPublicEgressSgrBadExamples,
			Links:               cloudFormationNoPublicEgressSgrLinks,
			RemediationMarkdown: cloudFormationNoPublicEgressSgrRemediationMarkdown,
		},
		Severity: severity.Critical,
	},
	func(s *state.State) (results scan.Results) {
		for _, group := range s.AWS.EC2.SecurityGroups {
			for _, rule := range group.EgressRules {
				var fail bool
				for _, block := range rule.CIDRs {
					if cidr.IsPublic(block.Value()) && cidr.CountAddresses(block.Value()) > 1 {
						fail = true
						results.Add(
							"Security group rule allows egress to multiple public internet addresses.",
							block,
						)
					}
				}
				if !fail {
					results.AddPassed(&rule)
				}
			}
		}
		return
	},
)
View Source
var CheckNoPublicIngress = rules.Register(
	scan.Rule{
		AVDID:       "AVD-AWS-0105",
		Aliases:     []string{"aws-vpc-no-public-ingress-acl"},
		Provider:    providers.AWSProvider,
		Service:     "ec2",
		ShortCode:   "no-public-ingress-acl",
		Summary:     "An ingress Network ACL rule allows specific ports from /0.",
		Impact:      "The ports are exposed for ingressing data to the internet",
		Resolution:  "Set a more restrictive cidr range",
		Explanation: `Opening up ACLs to the public internet is potentially dangerous. You should restrict access to IP addresses or ranges that explicitly require it where possible.`,
		Links: []string{
			"https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html",
		},
		Terraform: &scan.EngineMetadata{
			GoodExamples:        terraformNoPublicIngressAclGoodExamples,
			BadExamples:         terraformNoPublicIngressAclBadExamples,
			Links:               terraformNoPublicIngressAclLinks,
			RemediationMarkdown: terraformNoPublicIngressAclRemediationMarkdown,
		},
		CloudFormation: &scan.EngineMetadata{
			GoodExamples:        cloudFormationNoPublicIngressAclGoodExamples,
			BadExamples:         cloudFormationNoPublicIngressAclBadExamples,
			Links:               cloudFormationNoPublicIngressAclLinks,
			RemediationMarkdown: cloudFormationNoPublicIngressAclRemediationMarkdown,
		},
		Severity: severity.Critical,
	},
	func(s *state.State) (results scan.Results) {
		for _, acl := range s.AWS.EC2.NetworkACLs {
			for _, rule := range acl.Rules {
				if !rule.Type.EqualTo(ec2.TypeIngress) {
					continue
				}
				if !rule.Action.EqualTo(ec2.ActionAllow) {
					continue
				}
				var fail bool
				for _, block := range rule.CIDRs {
					if cidr.IsPublic(block.Value()) && cidr.CountAddresses(block.Value()) > 1 {
						fail = true
						results.Add(
							"Network ACL rule allows ingress from public internet.",
							block,
						)
					}
				}
				if !fail {
					results.AddPassed(&rule)
				}
			}
		}
		return
	},
)
View Source
var CheckNoPublicIngressSgr = rules.Register(
	scan.Rule{
		AVDID:     "AVD-AWS-0107",
		Aliases:   []string{"aws-vpc-no-public-ingress-sgr"},
		Provider:  providers.AWSProvider,
		Service:   "ec2",
		ShortCode: "no-public-ingress-sgr",
		Frameworks: map[framework.Framework][]string{
			framework.Default:     nil,
			framework.CIS_AWS_1_2: {"4.1", "4.2"},
		},
		Summary:     "An ingress security group rule allows traffic from /0.",
		Impact:      "Your port exposed to the internet",
		Resolution:  "Set a more restrictive cidr range",
		Explanation: `Opening up ports to the public internet is generally to be avoided. You should restrict access to IP addresses or ranges that explicitly require it where possible.`,
		Links: []string{
			"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-rules-reference.html",
		},
		Terraform: &scan.EngineMetadata{
			GoodExamples:        terraformNoPublicIngressSgrGoodExamples,
			BadExamples:         terraformNoPublicIngressSgrBadExamples,
			Links:               terraformNoPublicIngressSgrLinks,
			RemediationMarkdown: terraformNoPublicIngressSgrRemediationMarkdown,
		},
		CloudFormation: &scan.EngineMetadata{
			GoodExamples:        cloudFormationNoPublicIngressSgrGoodExamples,
			BadExamples:         cloudFormationNoPublicIngressSgrBadExamples,
			Links:               cloudFormationNoPublicIngressSgrLinks,
			RemediationMarkdown: cloudFormationNoPublicIngressSgrRemediationMarkdown,
		},
		Severity: severity.Critical,
	},
	func(s *state.State) (results scan.Results) {
		for _, group := range s.AWS.EC2.SecurityGroups {
			for _, rule := range group.IngressRules {
				var failed bool
				for _, block := range rule.CIDRs {
					if cidr.IsPublic(block.Value()) && cidr.CountAddresses(block.Value()) > 1 {
						failed = true
						results.Add(
							"Security group rule allows ingress from public internet.",
							block,
						)
					}
				}
				if !failed {
					results.AddPassed(&rule)
				}
			}
		}
		return
	},
)
View Source
var CheckNoPublicIp = rules.Register(
	scan.Rule{
		AVDID:       "AVD-AWS-0009",
		Aliases:     []string{"aws-autoscaling-no-public-ip"},
		Provider:    providers.AWSProvider,
		Service:     "ec2",
		ShortCode:   "no-public-ip",
		Summary:     "Launch configuration should not have a public IP address.",
		Impact:      "The instance or configuration is publicly accessible",
		Resolution:  "Set the instance to not be publicly accessible",
		Explanation: `You should limit the provision of public IP addresses for resources. Resources should not be exposed on the public internet, but should have access limited to consumers required for the function of your application.`,
		Links: []string{
			"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html",
		},
		Terraform: &scan.EngineMetadata{
			GoodExamples:        terraformNoPublicIpGoodExamples,
			BadExamples:         terraformNoPublicIpBadExamples,
			Links:               terraformNoPublicIpLinks,
			RemediationMarkdown: terraformNoPublicIpRemediationMarkdown,
		},
		CloudFormation: &scan.EngineMetadata{
			GoodExamples:        cloudFormationNoPublicIpGoodExamples,
			BadExamples:         cloudFormationNoPublicIpBadExamples,
			Links:               cloudFormationNoPublicIpLinks,
			RemediationMarkdown: cloudFormationNoPublicIpRemediationMarkdown,
		},
		Severity: severity.High,
	},
	func(s *state.State) (results scan.Results) {
		for _, launchConfig := range s.AWS.EC2.LaunchConfigurations {
			if launchConfig.AssociatePublicIP.IsTrue() {
				results.Add(
					"Launch configuration associates public IP address.",
					launchConfig.AssociatePublicIP,
				)
			} else {
				results.AddPassed(&launchConfig)
			}
		}
		return
	},
)
View Source
var CheckNoPublicIpSubnet = rules.Register(
	scan.Rule{
		AVDID:       "AVD-AWS-0164",
		Aliases:     []string{"aws-subnet-no-public-ip"},
		Provider:    providers.AWSProvider,
		Service:     "ec2",
		ShortCode:   "no-public-ip-subnet",
		Summary:     "Instances in a subnet should not receive a public IP address by default.",
		Impact:      "The instance is publicly accessible",
		Resolution:  "Set the instance to not be publicly accessible",
		Explanation: `You should limit the provision of public IP addresses for resources. Resources should not be exposed on the public internet, but should have access limited to consumers required for the function of your application.`,
		Links: []string{
			"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-instance-addressing.html#concepts-public-addresses",
		},
		Terraform: &scan.EngineMetadata{
			GoodExamples:        terraformNoPublicIpSubnetGoodExamples,
			BadExamples:         terraformNoPublicIpSubnetBadExamples,
			Links:               terraformNoPublicIpSubnetLinks,
			RemediationMarkdown: terraformNoPublicIpSubnetRemediationMarkdown,
		},
		CloudFormation: &scan.EngineMetadata{
			GoodExamples:        cloudFormationNoPublicIpSubnetGoodExamples,
			BadExamples:         cloudFormationNoPublicIpSubnetBadExamples,
			Links:               cloudFormationNoPublicIpSubnetLinks,
			RemediationMarkdown: cloudFormationNoPublicIpSubnetRemediationMarkdown,
		},
		Severity: severity.High,
	},
	func(s *state.State) (results scan.Results) {
		for _, subnet := range s.AWS.EC2.Subnets {
			if subnet.MapPublicIpOnLaunch.IsTrue() {
				results.Add(
					"Subnet associates public IP address.",
					subnet.MapPublicIpOnLaunch,
				)
			} else {
				results.AddPassed(&subnet)
			}
		}
		return
	},
)
View Source
var CheckNoSecretsInUserData = rules.Register(
	scan.Rule{
		AVDID:       "AVD-AWS-0029",
		Provider:    providers.AWSProvider,
		Service:     "ec2",
		ShortCode:   "no-secrets-in-user-data",
		Summary:     "User data for EC2 instances must not contain sensitive AWS keys",
		Impact:      "User data is visible through the AWS Management console",
		Resolution:  "Remove sensitive data from the EC2 instance user-data",
		Explanation: `EC2 instance data is used to pass start up information into the EC2 instance. This userdata must not contain access key credentials. Instead use an IAM Instance Profile assigned to the instance to grant access to other AWS Services.`,
		Links: []string{
			"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-add-user-data.html",
		},
		Terraform: &scan.EngineMetadata{
			GoodExamples:        terraformNoSecretsInUserDataGoodExamples,
			BadExamples:         terraformNoSecretsInUserDataBadExamples,
			Links:               terraformNoSecretsInUserDataLinks,
			RemediationMarkdown: terraformNoSecretsInUserDataRemediationMarkdown,
		},
		CloudFormation: &scan.EngineMetadata{
			GoodExamples:        cloudFormationNoSecretsInUserDataGoodExamples,
			BadExamples:         cloudFormationNoSecretsInUserDataBadExamples,
			Links:               cloudFormationNoSecretsInUserDataLinks,
			RemediationMarkdown: cloudFormationNoSecretsInUserDataRemediationMarkdown,
		},
		Severity: severity.Critical,
	},
	func(s *state.State) (results scan.Results) {
		for _, instance := range s.AWS.EC2.Instances {
			if instance.Metadata.IsUnmanaged() {
				continue
			}
			if result := scanner.Scan(instance.UserData.Value()); result.TransgressionFound {
				results.Add(
					fmt.Sprintf("Sensitive data found in instance user data: %s", result.Description),
					instance.UserData,
				)
			} else {
				results.AddPassed(&instance)
			}
		}
		return
	},
)
View Source
var CheckNoSensitiveInfo = rules.Register(
	scan.Rule{
		AVDID:       "AVD-AWS-0122",
		Aliases:     []string{"aws-autoscaling-no-sensitive-info"},
		Provider:    providers.AWSProvider,
		Service:     "ec2",
		ShortCode:   "no-sensitive-info",
		Summary:     "Ensure all data stored in the launch configuration EBS is securely encrypted",
		Impact:      "Sensitive credentials in user data can be leaked",
		Resolution:  "Don't use sensitive data in user data",
		Explanation: `When creating Launch Configurations, user data can be used for the initial configuration of the instance. User data must not contain any sensitive data.`,
		Links:       []string{},
		Terraform: &scan.EngineMetadata{
			GoodExamples:        terraformNoSensitiveInfoGoodExamples,
			BadExamples:         terraformNoSensitiveInfoBadExamples,
			Links:               terraformNoSensitiveInfoLinks,
			RemediationMarkdown: terraformNoSensitiveInfoRemediationMarkdown,
		},
		Severity: severity.High,
	},
	func(s *state.State) (results scan.Results) {
		scanner := squealer.NewStringScanner()
		for _, launchConfig := range s.AWS.EC2.LaunchConfigurations {
			if result := scanner.Scan(launchConfig.UserData.Value()); result.TransgressionFound {
				results.Add(
					fmt.Sprintf("Sensitive data found in user data: %s", result.Description),
					launchConfig.UserData,
				)
			} else {
				results.AddPassed(&launchConfig)
			}
		}
		return
	},
)
View Source
var CheckRequireVPCFlowLogs = rules.Register(
	scan.Rule{
		AVDID:       "AVD-AWS-0178",
		Aliases:     []string{"aws-autoscaling-enable-at-rest-encryption"},
		Provider:    providers.AWSProvider,
		Service:     "ec2",
		ShortCode:   "require-vpc-flow-logs-for-all-vpcs",
		Summary:     `VPC Flow Logs is a feature that enables you to capture information about the IP traffic going to and from network interfaces in your VPC. After you've created a flow log, you can view and retrieve its data in Amazon CloudWatch Logs. It is recommended that VPC Flow Logs be enabled for packet "Rejects" for VPCs.`,
		Impact:      "Without VPC flow logs, you risk not having enough information about network traffic flow to investigate incidents or identify security issues.",
		Resolution:  "Enable flow logs for VPC",
		Explanation: `VPC Flow Logs provide visibility into network traffic that traverses the VPC and can be used to detect anomalous traffic or insight during security workflows.`,
		Links: []string{
			"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/RootDeviceStorage.html",
		},
		Terraform:      &scan.EngineMetadata{},
		CloudFormation: &scan.EngineMetadata{},
		Severity:       severity.Medium,
	},
	func(s *state.State) (results scan.Results) {
		for _, vpc := range s.AWS.EC2.VPCs {
			if vpc.FlowLogsEnabled.IsFalse() {
				results.Add("VPC Flow Logs is not enabled for VPC "+vpc.ID.Value(), vpc)
			} else {
				results.AddPassed(vpc)
			}
		}
		return
	},
)
View Source
var CheckRestrictAllInDefaultSG = rules.Register(
	scan.Rule{
		AVDID:     "AVD-AWS-0173",
		Provider:  providers.AWSProvider,
		Service:   "ec2",
		ShortCode: "restrict-all-in-default-sg",
		Frameworks: map[framework.Framework][]string{
			framework.CIS_AWS_1_4: {"5.3"},
		},
		Summary:    "Default security group should restrict all traffic",
		Impact:     "Easier to accidentally expose resources - goes against principle of least privilege",
		Resolution: "Configure default security group to restrict all traffic",
		Explanation: `
Configuring all VPC default security groups to restrict all traffic will encourage least
privilege security group development and mindful placement of AWS resources into
security groups which will in-turn reduce the exposure of those resources.
`,
		Links: []string{
			"https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/default-custom-security-groups.html",
		},
		Severity: severity.Low,
	},
	func(s *state.State) (results scan.Results) {
		for _, vpc := range s.AWS.EC2.VPCs {
			for _, sg := range vpc.SecurityGroups {
				if sg.IsDefault.IsTrue() {
					if len(sg.IngressRules) > 0 || len(sg.EgressRules) > 0 {
						results.Add(
							"Default security group for VPC has ingress or egress rules.",
							&vpc,
						)
					}
				} else {
					results.AddPassed(&vpc)
				}
			}
		}
		return
	},
)

Functions

This section is empty.

Types

This section is empty.

Source Files

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL