feat(ec2): Add ResourceArn (#1649)

Co-authored-by: sergargar <sergio@verica.io>
This commit is contained in:
Gabriel Soltz
2023-01-04 11:55:58 +01:00
committed by GitHub
parent 54fbaa808e
commit 6ed0c59762
75 changed files with 565 additions and 16 deletions

View File

@@ -65,6 +65,10 @@ class Test_ec2_ami_public:
assert result[0].status == "PASS"
assert result[0].status_extended == f"EC2 AMI {image_id} is not public."
assert result[0].resource_id == image_id
assert (
result[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:image/{image_id}"
)
@mock_ec2
def test_one_public_ami(self):
@@ -111,3 +115,7 @@ class Test_ec2_ami_public:
result[0].status_extended == f"EC2 AMI {image_id} is currently public."
)
assert result[0].resource_id == image_id
assert (
result[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:image/{image_id}"
)

View File

@@ -72,6 +72,10 @@ class Test_ec2_ebs_public_snapshot:
snap.status_extended
== f"EBS Snapshot {snapshot.id} is currently Public."
)
assert (
snap.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:snapshot/{snapshot.id}"
)
@mock_ec2
def test_ec2_private_snapshot(self):
@@ -109,3 +113,7 @@ class Test_ec2_ebs_public_snapshot:
snap.status_extended
== f"EBS Snapshot {snapshot.id} is not Public."
)
assert (
snap.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:snapshot/{snapshot.id}"
)

View File

@@ -66,6 +66,10 @@ class Test_ec2_ebs_snapshots_encrypted:
snap.status_extended
== f"EBS Snapshot {snapshot.id} is unencrypted."
)
assert (
snap.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:snapshot/{snapshot.id}"
)
@mock_ec2
def test_ec2_encrypted_snapshot(self):
@@ -103,3 +107,7 @@ class Test_ec2_ebs_snapshots_encrypted:
snap.status_extended
== f"EBS Snapshot {snapshot.id} is encrypted."
)
assert (
snap.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:snapshot/{snapshot.id}"
)

View File

@@ -60,6 +60,10 @@ class Test_ec2_ebs_volume_encryption:
assert (
result[0].status_extended == f"EBS Snapshot {volume.id} is unencrypted."
)
assert (
result[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:volume/{volume.id}"
)
@mock_ec2
def test_ec2_encrypted_volume(self):
@@ -93,3 +97,7 @@ class Test_ec2_ebs_volume_encryption:
assert (
result[0].status_extended == f"EBS Snapshot {volume.id} is encrypted."
)
assert (
result[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:volume/{volume.id}"
)

View File

@@ -36,7 +36,9 @@ class Test_ec2_elastic_ip_unassgined:
def test_eip_unassociated(self):
# Create EC2 Mocked Resources
ec2_client = client("ec2", region_name=AWS_REGION)
ec2_client.allocate_address(Domain="vpc", Address="127.38.43.222")
allocation_id = ec2_client.allocate_address(
Domain="vpc", Address="127.38.43.222"
)["AllocationId"]
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.ec2.ec2_service import EC2
@@ -62,6 +64,10 @@ class Test_ec2_elastic_ip_unassgined:
"is not associated",
results[0].status_extended,
)
assert (
results[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:eip-allocation/{allocation_id}"
)
@mock_ec2
def test_eip_associated(self):
@@ -106,3 +112,7 @@ class Test_ec2_elastic_ip_unassgined:
"is associated",
results[0].status_extended,
)
assert (
results[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:eip-allocation/{eip.allocation_id}"
)

View File

@@ -73,6 +73,10 @@ class Test_ec2_instance_imdsv2_enabled:
result[0].status_extended,
)
assert result[0].resource_id == instance.id
assert (
result[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
)
@mock_ec2
def test_one_uncompliant_ec2(self):
@@ -115,3 +119,7 @@ class Test_ec2_instance_imdsv2_enabled:
result[0].status_extended,
)
assert result[0].resource_id == instance.id
assert (
result[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
)

View File

@@ -81,6 +81,10 @@ class Test_ec2_instance_internet_facing_with_instance_profile:
result[0].status_extended,
)
assert result[0].resource_id == instance.id
assert (
result[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
)
@mock_iam
@mock_ec2
@@ -130,3 +134,7 @@ class Test_ec2_instance_internet_facing_with_instance_profile:
"is internet-facing with Instance Profile", result[0].status_extended
)
assert result[0].resource_id == instance.id
assert (
result[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
)

View File

@@ -68,6 +68,10 @@ class Test_ec2_instance_older_than_specific_days:
f"EC2 Instance {instance.id} is not older", result[0].status_extended
)
assert result[0].resource_id == instance.id
assert (
result[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
)
@mock_ec2
def test_one_old_ec2(self):
@@ -107,3 +111,7 @@ class Test_ec2_instance_older_than_specific_days:
f"EC2 Instance {instance.id} is older", result[0].status_extended
)
assert result[0].resource_id == instance.id
assert (
result[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
)

View File

@@ -81,6 +81,10 @@ class Test_ec2_instance_profile_attached:
result[0].status_extended,
)
assert result[0].resource_id == instance.id
assert (
result[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
)
@mock_ec2
def test_one_non_compliant_ec2(self):
@@ -123,3 +127,7 @@ class Test_ec2_instance_profile_attached:
"not associated with an Instance Profile", result[0].status_extended
)
assert result[0].resource_id == instance.id
assert (
result[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
)

View File

@@ -75,6 +75,10 @@ class Test_ec2_instance_public_ip:
result[0].status_extended,
)
assert result[0].resource_id == instance.id
assert (
result[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
)
@mock_ec2
def test_one_ec2_with_public_ip(self):
@@ -118,3 +122,7 @@ class Test_ec2_instance_public_ip:
f"EC2 Instance {instance.id} has a Public IP", result[0].status_extended
)
assert result[0].resource_id == instance.id
assert (
result[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
)

View File

@@ -102,6 +102,10 @@ class Test_ec2_instance_secrets_user_data:
== f"Potential secret found in EC2 instance {instance.id} User Data."
)
assert result[0].resource_id == instance.id
assert (
result[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
)
@mock_ec2
def test_one_ec2_file_with_secrets(self):
@@ -140,6 +144,10 @@ class Test_ec2_instance_secrets_user_data:
== f"Potential secret found in EC2 instance {instance.id} User Data."
)
assert result[0].resource_id == instance.id
assert (
result[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
)
@mock_ec2
def test_one_launch_configurations_without_user_data(self):
@@ -173,3 +181,7 @@ class Test_ec2_instance_secrets_user_data:
== f"No secrets found in EC2 instance {instance.id} since User Data is empty."
)
assert result[0].resource_id == instance.id
assert (
result[0].resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:instance/{instance.id}"
)

View File

@@ -107,6 +107,10 @@ class ec2_networkacl_allow_ingress_any_port:
nacl.status_extended
== f"Network ACL {nacl_id} has every port open to the Internet."
)
assert (
nacl.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:network-acl/{nacl_id}"
)
@mock_ec2
def test_ec2_compliant_nacl(self):
@@ -153,3 +157,7 @@ class ec2_networkacl_allow_ingress_any_port:
nacl.status_extended
== f"Network ACL {nacl_id} has not every port open to the Internet."
)
assert (
nacl.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:network-acl/{nacl_id}"
)

View File

@@ -108,6 +108,10 @@ class Test_ec2_networkacl_allow_ingress_tcp_port_22:
nacl.status_extended
== f"Network ACL {nacl_id} has SSH port 22 open to the Internet."
)
assert (
nacl.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:network-acl/{nacl_id}"
)
@mock_ec2
def test_ec2_compliant_nacl(self):
@@ -155,3 +159,7 @@ class Test_ec2_networkacl_allow_ingress_tcp_port_22:
nacl.status_extended
== f"Network ACL {nacl_id} has not SSH port 22 open to the Internet."
)
assert (
nacl.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:network-acl/{nacl_id}"
)

View File

@@ -108,6 +108,10 @@ class Test_ec2_networkacl_allow_ingress_tcp_port_3389:
nacl.status_extended
== f"Network ACL {nacl_id} has Microsoft RDP port 3389 open to the Internet."
)
assert (
nacl.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:network-acl/{nacl_id}"
)
@mock_ec2
def test_ec2_compliant_nacl(self):
@@ -155,3 +159,7 @@ class Test_ec2_networkacl_allow_ingress_tcp_port_3389:
nacl.status_extended
== f"Network ACL {nacl_id} has not Microsoft RDP port 3389 open to the Internet."
)
assert (
nacl.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:network-acl/{nacl_id}"
)

View File

@@ -83,6 +83,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_any_port:
"has all ports open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_compliant_default_sg(self):
@@ -130,3 +134,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_any_port:
"has not all ports open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -89,6 +89,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_2
"has MongoDB ports 27017 and 27018 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_compliant_default_sg(self):
@@ -140,3 +144,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_2
"has not MongoDB ports 27017 and 27018 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -89,6 +89,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21:
"has FTP ports 20 and 21 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_compliant_default_sg(self):
@@ -140,3 +144,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21:
"has not FTP ports 20 and 21 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -85,6 +85,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22:
"has SSH port 22 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_compliant_default_sg(self):
@@ -134,3 +138,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22:
"has not SSH port 22 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -85,6 +85,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389:
"has Microsoft RDP port 3389 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_compliant_default_sg(self):
@@ -134,3 +138,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389:
"has not Microsoft RDP port 3389 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -89,6 +89,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7
"has Casandra ports 7199, 8888 and 9160 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_compliant_default_sg(self):
@@ -140,3 +144,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7
"has not Casandra ports 7199, 8888 and 9160 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -89,6 +89,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsear
"has Elasticsearch/Kibana ports 9200, 9300 and 5601 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_compliant_default_sg(self):
@@ -140,3 +144,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsear
"has not Elasticsearch/Kibana ports 9200, 9300 and 5601 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -88,6 +88,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092:
assert search(
"has Kafka port 9092 open to the Internet", sg.status_extended
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_compliant_default_sg(self):
@@ -139,3 +143,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092:
"has not Kafka port 9092 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -89,6 +89,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_1
"has Memcached port 11211 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_compliant_default_sg(self):
@@ -140,3 +144,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_1
"has not Memcached port 11211 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -89,6 +89,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306:
"has MySQL port 3306 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_compliant_default_sg(self):
@@ -140,3 +144,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306:
"has not MySQL port 3306 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -89,6 +89,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521
"has Oracle ports 1521 and 2483 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_compliant_default_sg(self):
@@ -140,3 +144,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521
"has not Oracle ports 1521 and 2483 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -89,6 +89,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_54
"has Postgres port 5432 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_compliant_default_sg(self):
@@ -140,3 +144,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_54
"has not Postgres port 5432 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -88,6 +88,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379:
assert search(
"has Redis port 6379 open to the Internet", sg.status_extended
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_compliant_default_sg(self):
@@ -139,3 +143,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379:
"has not Redis port 6379 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -89,6 +89,10 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_
"has Microsoft SQL Server ports 1433 and 1434 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_compliant_default_sg(self):
@@ -140,3 +144,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_
"has not Microsoft SQL Server ports 1433 and 1434 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -88,6 +88,10 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23:
assert search(
"has Telnet port 23 open to the Internet", sg.status_extended
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_compliant_default_sg(self):
@@ -139,3 +143,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23:
"has not Telnet port 23 open to the Internet",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -83,6 +83,10 @@ class Test_ec2_securitygroup_allow_wide_open_public_ipv4:
"has no potential wide-open non-RFC1918 address",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_default_sg_with_non_RFC1918_address(self):
@@ -130,3 +134,7 @@ class Test_ec2_securitygroup_allow_wide_open_public_ipv4:
"has potential wide-open non-RFC1918 address",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -77,6 +77,10 @@ class Test_ec2_securitygroup_default_restrict_traffic:
sg.status_extended
== f"Default Security Group ({default_sg_id}) is open to the Internet."
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_compliant_default_sg(self):
@@ -121,3 +125,7 @@ class Test_ec2_securitygroup_default_restrict_traffic:
sg.status_extended
== f"Default Security Group ({default_sg_id}) is not open to the Internet."
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -75,6 +75,10 @@ class Test_ec2_securitygroup_from_launch_wizard:
"was created using the EC2 Launch Wizard",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{sg_id}"
)
@mock_ec2
def test_ec2_compliant_default_sg(self):
@@ -122,3 +126,7 @@ class Test_ec2_securitygroup_from_launch_wizard:
"was not created using the EC2 Launch Wizard",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -84,6 +84,10 @@ class Test_ec2_securitygroup_in_use_without_ingress_filtering:
"has no ingress filtering and it is not being used",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_used_public_default_sg(self):
@@ -139,6 +143,10 @@ class Test_ec2_securitygroup_in_use_without_ingress_filtering:
"has no ingress filtering and it is being used",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_private_default_sg(self):
@@ -177,3 +185,7 @@ class Test_ec2_securitygroup_in_use_without_ingress_filtering:
"has ingress filtering",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -75,6 +75,10 @@ class Test_ec2_securitygroup_not_used:
"it is not being used",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_used_default_sg(self):
@@ -122,3 +126,7 @@ class Test_ec2_securitygroup_not_used:
"it is being used",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -85,6 +85,10 @@ class Test_ec2_securitygroup_with_many_ingress_egress_rules:
assert search(
"has 60 inbound rules and 1 outbound rules", sg.status_extended
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)
@mock_ec2
def test_ec2_compliant_default_sg(self):
@@ -134,3 +138,7 @@ class Test_ec2_securitygroup_with_many_ingress_egress_rules:
"has 1 inbound rules and 1 outbound rules",
sg.status_extended,
)
assert (
sg.resource_arn
== f"arn:{current_audit_info.audited_partition}:ec2:{AWS_REGION}:{current_audit_info.audited_account}:security-group/{default_sg_id}"
)

View File

@@ -1,6 +1,11 @@
import ipaddress
import re
from base64 import b64decode
from datetime import datetime
from boto3 import client, resource, session
from dateutil.tz import tzutc
from freezegun import freeze_time
from moto import mock_ec2
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
@@ -9,6 +14,7 @@ from prowler.providers.aws.services.ec2.ec2_service import EC2
AWS_ACCOUNT_NUMBER = 123456789012
AWS_REGION = "us-east-1"
EXAMPLE_AMI_ID = "ami-12c6146b"
MOCK_DATETIME = datetime(2023, 1, 4, 7, 27, 30, tzinfo=tzutc())
class Test_EC2_Service:
@@ -68,6 +74,7 @@ class Test_EC2_Service:
# Test EC2 Describe Instances
@mock_ec2
@freeze_time(MOCK_DATETIME)
def test__describe_instances__(self):
# Generate EC2 Client
ec2_resource = resource("ec2", region_name=AWS_REGION)
@@ -75,17 +82,38 @@ class Test_EC2_Service:
# Get AMI image
image_response = ec2_client.describe_images()
image_id = image_response["Images"][0]["ImageId"]
# Create EC2 Instances
# Create EC2 Instances running
ec2_resource.create_instances(
MinCount=2,
MaxCount=2,
MinCount=1,
MaxCount=1,
ImageId=image_id,
)
# EC2 client for this test class
audit_info = self.set_mocked_audit_info()
ec2 = EC2(audit_info)
assert len(ec2.instances) == len(
ec2_client.describe_instances()["Reservations"][0]["Instances"]
assert len(ec2.instances) == 1
assert re.match(r"i-[0-9a-z]{17}", ec2.instances[0].id)
assert (
ec2.instances[0].arn
== f"arn:{audit_info.audited_partition}:ec2:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:instance/{ec2.instances[0].id}"
)
assert ec2.instances[0].type == "m1.small"
assert ec2.instances[0].state == "running"
assert re.match(r"ami-[0-9a-z]{8}", ec2.instances[0].image_id)
assert ec2.instances[0].launch_time == MOCK_DATETIME
assert not ec2.instances[0].user_data
assert not ec2.instances[0].http_tokens
assert not ec2.instances[0].http_endpoint
assert not ec2.instances[0].instance_profile
assert ipaddress.ip_address(ec2.instances[0].private_ip).is_private
assert (
ec2.instances[0].private_dns
== f"ip-{ec2.instances[0].private_ip.replace('.', '-')}.ec2.internal"
)
assert ipaddress.ip_address(ec2.instances[0].public_ip).is_global
assert (
ec2.instances[0].public_dns
== f"ec2-{ec2.instances[0].public_ip.replace('.', '-')}.compute-1.amazonaws.com"
)
# Test EC2 Describe Security Groups
@@ -101,7 +129,28 @@ class Test_EC2_Service:
# EC2 client for this test class
audit_info = self.set_mocked_audit_info()
ec2 = EC2(audit_info)
assert sg_id in str(ec2.security_groups)
for security_group in ec2.security_groups:
if security_group.id == sg_id:
assert security_group.name == "test-security-group"
assert (
security_group.arn
== f"arn:{audit_info.audited_partition}:ec2:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:security-group/{security_group.id}"
)
assert re.match(r"sg-[0-9a-z]{17}", security_group.id)
assert security_group.region == AWS_REGION
assert security_group.network_interfaces == []
assert security_group.ingress_rules == []
assert security_group.egress_rules == [
{
"IpProtocol": "-1",
"IpRanges": [{"CidrIp": "0.0.0.0/0"}],
"Ipv6Ranges": [],
"PrefixListIds": [],
"UserIdGroupPairs": [],
}
]
# Test EC2 Describe Nacls
@mock_ec2
@@ -117,7 +166,16 @@ class Test_EC2_Service:
# EC2 client for this test class
audit_info = self.set_mocked_audit_info()
ec2 = EC2(audit_info)
assert nacl_id in str(ec2.network_acls)
for acl in ec2.network_acls:
if acl.id == nacl_id:
assert re.match(r"acl-[0-9a-z]{8}", acl.id)
assert (
acl.arn
== f"arn:{audit_info.audited_partition}:ec2:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:network-acl/{acl.id}"
)
assert acl.entries == []
# Test EC2 Describe Snapshots
@mock_ec2
@@ -137,7 +195,18 @@ class Test_EC2_Service:
# EC2 client for this test class
audit_info = self.set_mocked_audit_info()
ec2 = EC2(audit_info)
assert snapshot_id in str(ec2.snapshots)
for snapshot in ec2.snapshots:
if snapshot.id == snapshot_id:
assert re.match(r"snap-[0-9a-z]{8}", snapshot.id)
assert (
snapshot.arn
== f"arn:{audit_info.audited_partition}:ec2:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:snapshot/{snapshot.id}"
)
assert snapshot.region == AWS_REGION
assert not snapshot.encrypted
assert not snapshot.public
# Test EC2 Get Snapshot Public
@mock_ec2
@@ -165,8 +234,17 @@ class Test_EC2_Service:
# EC2 client for this test class
audit_info = self.set_mocked_audit_info()
ec2 = EC2(audit_info)
assert snapshot_id in str(ec2.snapshots)
for snapshot in ec2.snapshots:
if snapshot.id == snapshot_id:
assert re.match(r"snap-[0-9a-z]{8}", snapshot.id)
assert (
snapshot.arn
== f"arn:{audit_info.audited_partition}:ec2:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:snapshot/{snapshot.id}"
)
assert snapshot.region == AWS_REGION
assert not snapshot.encrypted
assert snapshot.public
# Test EC2 Instance User Data
@@ -185,7 +263,7 @@ class Test_EC2_Service:
ec2 = EC2(audit_info)
assert user_data == b64decode(ec2.instances[0].user_data).decode("utf-8")
# Test EC2 Instance User Data
# Test EC2 Get EBS Encryption by default
@mock_ec2
def test__get_ebs_encryption_by_default__(self):
ec2_client = client("ec2", region_name=AWS_REGION)
@@ -200,7 +278,7 @@ class Test_EC2_Service:
if result.region == AWS_REGION:
assert result.status
# Test EC2 Describe Snapshots
# Test EC2 Describe Addresses
@mock_ec2
def test__describe_addresses__(self):
# Generate EC2 Client
@@ -216,3 +294,117 @@ class Test_EC2_Service:
ec2.elastic_ips[0].arn
== f"arn:aws:ec2:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:eip-allocation/{allocation_id}"
)
# Test EC2 Describe Network Interfaces
@mock_ec2
def test__describe_network_interfaces__(self):
# Generate EC2 Client
ec2_client = client("ec2", region_name=AWS_REGION)
ec2_resource = resource("ec2", region_name=AWS_REGION)
# Create VPC, Subnet, SecurityGroup and Network Interface
vpc = ec2_resource.create_vpc(CidrBlock="10.0.0.0/16")
subnet = ec2_resource.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18")
sg = ec2_resource.create_security_group(
GroupName="test-securitygroup", Description="n/a"
)
eni_id = subnet.create_network_interface(Groups=[sg.id]).id
print(eni_id)
ec2_client.modify_network_interface_attribute(
NetworkInterfaceId=eni_id, Groups=[sg.id]
)
# EC2 client for this test class
audit_info = self.set_mocked_audit_info()
ec2 = EC2(audit_info)
assert sg.id in str(ec2.security_groups)
for security_group in ec2.security_groups:
if security_group.id == sg.id:
assert security_group.name == "test-securitygroup"
assert (
security_group.arn
== f"arn:{audit_info.audited_partition}:ec2:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:security-group/{security_group.id}"
)
assert re.match(r"sg-[0-9a-z]{17}", security_group.id)
assert security_group.region == AWS_REGION
assert eni_id in security_group.network_interfaces
assert security_group.ingress_rules == []
assert security_group.egress_rules == [
{
"IpProtocol": "-1",
"IpRanges": [{"CidrIp": "0.0.0.0/0"}],
"Ipv6Ranges": [],
"PrefixListIds": [],
"UserIdGroupPairs": [],
}
]
# Test EC2 Describe Images
@mock_ec2
def test__describe_images__(self):
# Generate EC2 Client
ec2_client = client("ec2", region_name=AWS_REGION)
ec2_resource = resource("ec2", region_name=AWS_REGION)
# Create AMI
tag_specifications = [
{
"ResourceType": "image",
"Tags": [
{
"Key": "Base_AMI_Name",
"Value": "Deep Learning Base AMI (Amazon Linux 2) Version 31.0",
},
{"Key": "OS_Version", "Value": "AWS Linux 2"},
],
},
]
instance = ec2_resource.create_instances(
ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1
)[0]
image_id = ec2_client.create_image(
InstanceId=instance.instance_id,
Name="test-image",
Description="test ami",
TagSpecifications=tag_specifications,
)["ImageId"]
# EC2 client for this test class
audit_info = self.set_mocked_audit_info()
ec2 = EC2(audit_info)
assert len(ec2.images) == 1
assert ec2.images[0].id == image_id
assert re.match(r"ami-[0-9a-z]{8}", ec2.images[0].id)
assert (
ec2.images[0].arn
== f"arn:{audit_info.audited_partition}:ec2:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:image/{ec2.images[0].id}"
)
assert not ec2.images[0].public
assert ec2.images[0].region == AWS_REGION
# Test EC2 Describe Volumes
@mock_ec2
def test__describe_volumes__(self):
# Generate EC2 Client
ec2_client = client("ec2", region_name=AWS_REGION)
# Create Volume
volume_id = ec2_client.create_volume(
AvailabilityZone=AWS_REGION,
Encrypted=False,
Size=40,
TagSpecifications=[],
)["VolumeId"]
# EC2 client for this test class
audit_info = self.set_mocked_audit_info()
ec2 = EC2(audit_info)
assert len(ec2.volumes) == 1
assert ec2.volumes[0].id == volume_id
assert re.match(r"vol-[0-9a-z]{8}", ec2.volumes[0].id)
assert (
ec2.volumes[0].arn
== f"arn:{audit_info.audited_partition}:ec2:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:volume/{ec2.volumes[0].id}"
)
assert ec2.volumes[0].region == AWS_REGION
assert not ec2.volumes[0].encrypted