feat(route53): add route53_dangling_ip_subdomain_takeover check (#2288)

Co-authored-by: Pepe Fagoaga <pepe@verica.io>
This commit is contained in:
Sergio Garcia
2023-05-03 11:47:36 +02:00
committed by GitHub
parent 244b540fe0
commit 26a507e3db
11 changed files with 602 additions and 13 deletions

View File

@@ -29,7 +29,9 @@ class EC2:
self.snapshots = []
self.__threading_call__(self.__describe_snapshots__)
self.__get_snapshot_public__()
self.__threading_call__(self.__describe_network_interfaces__)
self.network_interfaces = []
self.__threading_call__(self.__describe_public_network_interfaces__)
self.__threading_call__(self.__describe_sg_network_interfaces__)
self.images = []
self.__threading_call__(self.__describe_images__)
self.volumes = []
@@ -220,10 +222,37 @@ class EC2:
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
def __describe_network_interfaces__(self, regional_client):
def __describe_public_network_interfaces__(self, regional_client):
logger.info("EC2 - Describing Network Interfaces...")
try:
# Get SGs Network Interfaces
# Get Network Interfaces with Public IPs
describe_network_interfaces_paginator = regional_client.get_paginator(
"describe_network_interfaces"
)
for page in describe_network_interfaces_paginator.paginate():
for interface in page["NetworkInterfaces"]:
if interface.get("Association"):
self.network_interfaces.append(
NetworkInterface(
public_ip=interface["Association"]["PublicIp"],
type=interface["InterfaceType"],
private_ip=interface["PrivateIpAddress"],
subnet_id=interface["SubnetId"],
vpc_id=interface["VpcId"],
region=regional_client.region,
tags=interface.get("TagSet"),
)
)
except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
def __describe_sg_network_interfaces__(self, regional_client):
logger.info("EC2 - Describing Network Interfaces...")
try:
# Get Network Interfaces for Security Groups
for sg in self.security_groups:
regional_client = self.regional_clients[sg.region]
describe_network_interfaces_paginator = regional_client.get_paginator(
@@ -241,7 +270,6 @@ class EC2:
):
for interface in page["NetworkInterfaces"]:
sg.network_interfaces.append(interface["NetworkInterfaceId"])
except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
@@ -425,6 +453,16 @@ class NetworkACL(BaseModel):
tags: Optional[list] = []
class NetworkInterface(BaseModel):
public_ip: str
private_ip: str
type: str
subnet_id: str
vpc_id: str
region: str
tags: Optional[list] = []
class ElasticIP(BaseModel):
public_ip: Optional[str]
association_id: Optional[str]

View File

@@ -0,0 +1,32 @@
{
"Provider": "aws",
"CheckID": "route53_dangling_ip_subdomain_takeover",
"CheckTitle": "Check if Route53 Records contains dangling IPs.",
"CheckType": [],
"ServiceName": "route53",
"SubServiceName": "",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "AWSRoute53RecordSet",
"Description": "Check if Route53 Records contains dangling IPs.",
"Risk": "When an ephemeral AWS resource such as an Elastic IP (EIP) is released into the Amazon's Elastic IP pool, an attacker may acquire the EIP resource and effectively control the domain/subdomain associated with that EIP in your Route 53 DNS records.",
"RelatedUrl": "",
"Remediation": {
"Code": {
"CLI": "aws route53 change-resource-record-sets --hosted-zone-id <resource_id>",
"NativeIaC": "",
"Other": "https://www.trendmicro.com/cloudoneconformity/knowledge-base/aws/Route53/dangling-dns-records.html",
"Terraform": ""
},
"Recommendation": {
"Text": "Ensure that any dangling DNS records are deleted from your Amazon Route 53 public hosted zones in order to maintain the integrity and authenticity of your domains/subdomains and to protect against domain hijacking attacks.",
"Url": "https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/resource-record-sets-deleting.html"
}
},
"Categories": [
"forensics-ready"
],
"DependsOn": [],
"RelatedTo": [],
"Notes": ""
}

View File

@@ -0,0 +1,40 @@
from ipaddress import ip_address
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.ec2.ec2_client import ec2_client
from prowler.providers.aws.services.route53.route53_client import route53_client
class route53_dangling_ip_subdomain_takeover(Check):
def execute(self) -> Check_Report_AWS:
findings = []
for record_set in route53_client.record_sets:
# Check only A records and avoid aliases (only need to check IPs not AWS Resources)
if record_set.type == "A" and not record_set.is_alias:
# Gather Elastic IPs and Network Interfaces Public IPs inside the AWS Account
public_ips = []
public_ips.extend([eip.public_ip for eip in ec2_client.elastic_ips])
public_ips.extend(
[interface.public_ip for interface in ec2_client.network_interfaces]
)
for record in record_set.records:
report = Check_Report_AWS(self.metadata())
report.resource_id = record_set.hosted_zone_id
report.resource_arn = route53_client.hosted_zones[
record_set.hosted_zone_id
].arn
report.resource_tags = route53_client.hosted_zones[
record_set.hosted_zone_id
].tags
report.region = record_set.region
report.status = "PASS"
report.status_extended = f"Route53 record {record} in Hosted Zone {route53_client.hosted_zones[record_set.hosted_zone_id].name} is not a dangling IP."
# If Public IP check if it is in the AWS Account
if not ip_address(record).is_private and record not in public_ips:
report.status = "FAIL"
report.status_extended = f"Route53 record {record} in Hosted Zone {route53_client.hosted_zones[record_set.hosted_zone_id].name} is a dangling IP which can lead to a subdomain takeover attack!"
findings.append(report)
return findings

View File

@@ -10,6 +10,7 @@ class route53_public_hosted_zones_cloudwatch_logging_enabled(Check):
if not hosted_zone.private_zone:
report = Check_Report_AWS(self.metadata())
report.resource_id = hosted_zone.id
report.resource_arn = hosted_zone.arn
report.resource_tags = hosted_zone.tags
report.region = hosted_zone.region
if (

View File

@@ -15,6 +15,7 @@ class Route53:
self.audited_partition = audit_info.audited_partition
self.audit_resources = audit_info.audit_resources
self.hosted_zones = {}
self.record_sets = []
global_client = generate_regional_clients(
self.service, audit_info, global_service=True
)
@@ -24,6 +25,7 @@ class Route53:
self.__list_hosted_zones__()
self.__list_query_logging_configs__()
self.__list_tags_for_resource__()
self.__list_resource_record_sets__()
def __get_session__(self):
return self.session
@@ -55,6 +57,36 @@ class Route53:
f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
def __list_resource_record_sets__(self):
logger.info("Route53 - Listing Hosting Zones...")
try:
list_resource_record_sets_paginator = self.client.get_paginator(
"list_resource_record_sets"
)
for zone_id in self.hosted_zones.keys():
for page in list_resource_record_sets_paginator.paginate(
HostedZoneId=zone_id
):
for record in page["ResourceRecordSets"]:
self.record_sets.append(
RecordSet(
name=record["Name"],
type=record["Type"],
records=[
resource_record["Value"]
for resource_record in record["ResourceRecords"]
],
is_alias=True if "AliasTarget" in record else False,
hosted_zone_id=zone_id,
region=self.region,
)
)
except Exception as error:
logger.error(
f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
def __list_query_logging_configs__(self):
logger.info("Route53 - Listing Query Logging Configs...")
try:
@@ -105,6 +137,15 @@ class HostedZone(BaseModel):
tags: Optional[list] = []
class RecordSet(BaseModel):
name: str
type: str
is_alias: bool
records: list = []
hosted_zone_id: str
region: str
################## Route53Domains
class Route53Domains:
def __init__(self, audit_info):

View File

@@ -344,7 +344,7 @@ class Test_EC2_Service:
# Test EC2 Describe Network Interfaces
@mock_ec2
def test__describe_network_interfaces__(self):
def test__describe_sg_network_interfaces__(self):
# Generate EC2 Client
ec2_client = client("ec2", region_name=AWS_REGION)
ec2_resource = resource("ec2", region_name=AWS_REGION)
@@ -385,6 +385,46 @@ class Test_EC2_Service:
}
]
@mock_ec2
def test__describe_public_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")
eni = subnet.create_network_interface(
SubnetId=subnet.id,
TagSpecifications=[
{
"ResourceType": "network-interface",
"Tags": [
{"Key": "string", "Value": "string"},
],
},
],
)
eip = ec2_client.allocate_address(Domain="vpc")
ec2_client.associate_address(
NetworkInterfaceId=eni.id, AllocationId=eip["AllocationId"]
)
# EC2 client for this test class
audit_info = self.set_mocked_audit_info()
ec2 = EC2(audit_info)
assert len(ec2.network_interfaces) == 1
assert ec2.network_interfaces[0].public_ip == eip["PublicIp"]
assert ec2.network_interfaces[0].private_ip == eni.private_ip_address
assert ec2.network_interfaces[0].type == eni.interface_type
assert ec2.network_interfaces[0].subnet_id == subnet.id
assert ec2.network_interfaces[0].vpc_id == vpc.id
assert ec2.network_interfaces[0].region == AWS_REGION
assert ec2.network_interfaces[0].tags == [
{"Key": "string", "Value": "string"},
]
# Test EC2 Describe Images
@mock_ec2
def test__describe_images__(self):

View File

@@ -0,0 +1,358 @@
from re import search
from unittest import mock
from boto3 import client, resource, session
from moto import mock_ec2, mock_route53
from moto.core import DEFAULT_ACCOUNT_ID
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
AWS_REGION = "us-east-1"
class Test_route53_dangling_ip_subdomain_takeover:
# Mocked Audit Info
def set_mocked_audit_info(self):
audit_info = AWS_Audit_Info(
session_config=None,
original_session=None,
audit_session=session.Session(
profile_name=None,
botocore_session=None,
region_name=AWS_REGION,
),
audited_account=DEFAULT_ACCOUNT_ID,
audited_user_id=None,
audited_partition="aws",
audited_identity_arn=None,
profile=None,
profile_region=None,
credentials=None,
assumed_role_info=None,
audited_regions=[AWS_REGION],
organizations_metadata=None,
audit_resources=None,
)
return audit_info
@mock_ec2
@mock_route53
def test_no_hosted_zones(self):
from prowler.providers.aws.services.ec2.ec2_service import EC2
from prowler.providers.aws.services.route53.route53_service import Route53
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.route53.route53_dangling_ip_subdomain_takeover.route53_dangling_ip_subdomain_takeover.route53_client",
new=Route53(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.route53.route53_dangling_ip_subdomain_takeover.route53_dangling_ip_subdomain_takeover.ec2_client",
new=EC2(audit_info),
):
# Test Check
from prowler.providers.aws.services.route53.route53_dangling_ip_subdomain_takeover.route53_dangling_ip_subdomain_takeover import (
route53_dangling_ip_subdomain_takeover,
)
check = route53_dangling_ip_subdomain_takeover()
result = check.execute()
assert len(result) == 0
@mock_ec2
@mock_route53
def test_hosted_zone_no_records(self):
conn = client("route53", region_name=AWS_REGION)
conn.create_hosted_zone(
Name="testdns.aws.com.", CallerReference=str(hash("foo"))
)["HostedZone"]["Id"]
from prowler.providers.aws.services.ec2.ec2_service import EC2
from prowler.providers.aws.services.route53.route53_service import Route53
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.route53.route53_dangling_ip_subdomain_takeover.route53_dangling_ip_subdomain_takeover.route53_client",
new=Route53(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.route53.route53_dangling_ip_subdomain_takeover.route53_dangling_ip_subdomain_takeover.ec2_client",
new=EC2(audit_info),
):
# Test Check
from prowler.providers.aws.services.route53.route53_dangling_ip_subdomain_takeover.route53_dangling_ip_subdomain_takeover import (
route53_dangling_ip_subdomain_takeover,
)
check = route53_dangling_ip_subdomain_takeover()
result = check.execute()
assert len(result) == 0
@mock_ec2
@mock_route53
def test_hosted_zone_private_record(self):
conn = client("route53", region_name=AWS_REGION)
zone_id = conn.create_hosted_zone(
Name="testdns.aws.com.", CallerReference=str(hash("foo"))
)["HostedZone"]["Id"]
conn.change_resource_record_sets(
HostedZoneId=zone_id,
ChangeBatch={
"Changes": [
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "foo.bar.testdns.aws.com",
"Type": "A",
"ResourceRecords": [{"Value": "192.168.1.1"}],
},
}
]
},
)
from prowler.providers.aws.services.ec2.ec2_service import EC2
from prowler.providers.aws.services.route53.route53_service import Route53
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.route53.route53_dangling_ip_subdomain_takeover.route53_dangling_ip_subdomain_takeover.route53_client",
new=Route53(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.route53.route53_dangling_ip_subdomain_takeover.route53_dangling_ip_subdomain_takeover.ec2_client",
new=EC2(audit_info),
):
# Test Check
from prowler.providers.aws.services.route53.route53_dangling_ip_subdomain_takeover.route53_dangling_ip_subdomain_takeover import (
route53_dangling_ip_subdomain_takeover,
)
check = route53_dangling_ip_subdomain_takeover()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert search(
"is not a dangling IP",
result[0].status_extended,
)
assert result[0].resource_id == zone_id.replace("/hostedzone/", "")
assert (
result[0].resource_arn
== f"arn:{audit_info.audited_partition}:route53:::{zone_id.replace('/hostedzone/','')}"
)
@mock_ec2
@mock_route53
def test_hosted_zone_dangling_public_record(self):
conn = client("route53", region_name=AWS_REGION)
zone_id = conn.create_hosted_zone(
Name="testdns.aws.com.", CallerReference=str(hash("foo"))
)["HostedZone"]["Id"]
conn.change_resource_record_sets(
HostedZoneId=zone_id,
ChangeBatch={
"Changes": [
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "foo.bar.testdns.aws.com",
"Type": "A",
"ResourceRecords": [{"Value": "17.5.7.3"}],
},
}
]
},
)
from prowler.providers.aws.services.ec2.ec2_service import EC2
from prowler.providers.aws.services.route53.route53_service import Route53
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.route53.route53_dangling_ip_subdomain_takeover.route53_dangling_ip_subdomain_takeover.route53_client",
new=Route53(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.route53.route53_dangling_ip_subdomain_takeover.route53_dangling_ip_subdomain_takeover.ec2_client",
new=EC2(audit_info),
):
# Test Check
from prowler.providers.aws.services.route53.route53_dangling_ip_subdomain_takeover.route53_dangling_ip_subdomain_takeover import (
route53_dangling_ip_subdomain_takeover,
)
check = route53_dangling_ip_subdomain_takeover()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert search(
"is a dangling IP",
result[0].status_extended,
)
assert result[0].resource_id == zone_id.replace("/hostedzone/", "")
assert (
result[0].resource_arn
== f"arn:{audit_info.audited_partition}:route53:::{zone_id.replace('/hostedzone/','')}"
)
@mock_ec2
@mock_route53
def test_hosted_zone_eip_record(self):
conn = client("route53", region_name=AWS_REGION)
ec2 = client("ec2", region_name=AWS_REGION)
ec2.allocate_address(Domain="vpc", Address="17.5.7.3")
zone_id = conn.create_hosted_zone(
Name="testdns.aws.com.", CallerReference=str(hash("foo"))
)["HostedZone"]["Id"]
conn.change_resource_record_sets(
HostedZoneId=zone_id,
ChangeBatch={
"Changes": [
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "foo.bar.testdns.aws.com",
"Type": "A",
"ResourceRecords": [{"Value": "17.5.7.3"}],
},
}
]
},
)
from prowler.providers.aws.services.ec2.ec2_service import EC2
from prowler.providers.aws.services.route53.route53_service import Route53
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.route53.route53_dangling_ip_subdomain_takeover.route53_dangling_ip_subdomain_takeover.route53_client",
new=Route53(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.route53.route53_dangling_ip_subdomain_takeover.route53_dangling_ip_subdomain_takeover.ec2_client",
new=EC2(audit_info),
):
# Test Check
from prowler.providers.aws.services.route53.route53_dangling_ip_subdomain_takeover.route53_dangling_ip_subdomain_takeover import (
route53_dangling_ip_subdomain_takeover,
)
check = route53_dangling_ip_subdomain_takeover()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert search(
"is not a dangling IP",
result[0].status_extended,
)
assert result[0].resource_id == zone_id.replace("/hostedzone/", "")
assert (
result[0].resource_arn
== f"arn:{audit_info.audited_partition}:route53:::{zone_id.replace('/hostedzone/','')}"
)
@mock_ec2
@mock_route53
def test_hosted_zone_eni_record(self):
conn = client("route53", region_name=AWS_REGION)
ec2 = resource("ec2", region_name=AWS_REGION)
ec2_client = client("ec2", region_name=AWS_REGION)
vpc = ec2.create_vpc(CidrBlock="10.0.0.0/16")
subnet = ec2.create_subnet(VpcId=vpc.id, CidrBlock="10.0.0.0/18")
eni_id = ec2.create_network_interface(SubnetId=subnet.id).id
eip = ec2_client.allocate_address(Domain="vpc", Address="17.5.7.3")
ec2_client.associate_address(
NetworkInterfaceId=eni_id, AllocationId=eip["AllocationId"]
)
zone_id = conn.create_hosted_zone(
Name="testdns.aws.com.", CallerReference=str(hash("foo"))
)["HostedZone"]["Id"]
conn.change_resource_record_sets(
HostedZoneId=zone_id,
ChangeBatch={
"Changes": [
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "foo.bar.testdns.aws.com",
"Type": "A",
"ResourceRecords": [{"Value": "17.5.7.3"}],
},
}
]
},
)
from prowler.providers.aws.services.ec2.ec2_service import EC2
from prowler.providers.aws.services.route53.route53_service import Route53
audit_info = self.set_mocked_audit_info()
with mock.patch(
"prowler.providers.aws.lib.audit_info.audit_info.current_audit_info",
new=audit_info,
):
with mock.patch(
"prowler.providers.aws.services.route53.route53_dangling_ip_subdomain_takeover.route53_dangling_ip_subdomain_takeover.route53_client",
new=Route53(audit_info),
):
with mock.patch(
"prowler.providers.aws.services.route53.route53_dangling_ip_subdomain_takeover.route53_dangling_ip_subdomain_takeover.ec2_client",
new=EC2(audit_info),
):
# Test Check
from prowler.providers.aws.services.route53.route53_dangling_ip_subdomain_takeover.route53_dangling_ip_subdomain_takeover import (
route53_dangling_ip_subdomain_takeover,
)
check = route53_dangling_ip_subdomain_takeover()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert search(
"is not a dangling IP",
result[0].status_extended,
)
assert result[0].resource_id == zone_id.replace("/hostedzone/", "")
assert (
result[0].resource_arn
== f"arn:{audit_info.audited_partition}:route53:::{zone_id.replace('/hostedzone/','')}"
)

View File

@@ -16,7 +16,7 @@ class Test_route53_public_hosted_zones_cloudwatch_logging_enabled:
route53.hosted_zones = {}
with mock.patch(
"prowler.providers.aws.services.route53.route53_service.Route53",
"prowler.providers.aws.services.route53.route53_public_hosted_zones_cloudwatch_logging_enabled.route53_public_hosted_zones_cloudwatch_logging_enabled.route53_client",
new=route53,
):
# Test Check
@@ -49,7 +49,7 @@ class Test_route53_public_hosted_zones_cloudwatch_logging_enabled:
}
with mock.patch(
"prowler.providers.aws.services.route53.route53_service.Route53",
"prowler.providers.aws.services.route53.route53_public_hosted_zones_cloudwatch_logging_enabled.route53_public_hosted_zones_cloudwatch_logging_enabled.route53_client",
new=route53,
):
# Test Check
@@ -84,7 +84,7 @@ class Test_route53_public_hosted_zones_cloudwatch_logging_enabled:
}
with mock.patch(
"prowler.providers.aws.services.route53.route53_service.Route53",
"prowler.providers.aws.services.route53.route53_public_hosted_zones_cloudwatch_logging_enabled.route53_public_hosted_zones_cloudwatch_logging_enabled.route53_client",
new=route53,
):
# Test Check
@@ -119,7 +119,7 @@ class Test_route53_public_hosted_zones_cloudwatch_logging_enabled:
}
with mock.patch(
"prowler.providers.aws.services.route53.route53_service.Route53",
"prowler.providers.aws.services.route53.route53_public_hosted_zones_cloudwatch_logging_enabled.route53_public_hosted_zones_cloudwatch_logging_enabled.route53_client",
new=route53,
):
# Test Check

View File

@@ -218,3 +218,42 @@ class Test_Route53_Service:
assert not route53.hosted_zones[hosted_zone_id].logging_config
assert route53.hosted_zones[hosted_zone_id].region == AWS_REGION
@mock_route53
def test__list_resource_record_sets__(self):
# Create Hosted Zone
r53_client = client("route53", region_name=AWS_REGION)
zone = r53_client.create_hosted_zone(
Name="testdns.aws.com", CallerReference=str(hash("foo"))
)
zone_id = zone["HostedZone"]["Id"]
r53_client.change_resource_record_sets(
HostedZoneId=zone_id,
ChangeBatch={
"Changes": [
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "foo.bar.testdns.aws.com",
"Type": "A",
"ResourceRecords": [{"Value": "1.2.3.4"}],
},
}
]
},
)
# Set partition for the service
route53 = Route53(self.set_mocked_audit_info())
assert (
len(route53.record_sets) == 3
) # Default NS and SOA records plus the A record just created
for set in route53.record_sets:
if set.type == "A":
assert set.name == "foo.bar.testdns.aws.com."
assert set.type == "A"
assert not set.is_alias
assert set.records == ["1.2.3.4"]
assert set.hosted_zone_id == zone_id.replace("/hostedzone/", "")
assert set.region == AWS_REGION

View File

@@ -17,7 +17,7 @@ class Test_shield_advanced_protection_in_route53_hosted_zones:
"prowler.providers.aws.services.shield.shield_service.Shield",
new=shield_client,
), mock.patch(
"prowler.providers.aws.services.route53.route53_service.Route53",
"prowler.providers.aws.services.shield.shield_advanced_protection_in_route53_hosted_zones.shield_advanced_protection_in_route53_hosted_zones.route53_client",
new=route53_client,
):
# Test Check
@@ -67,7 +67,7 @@ class Test_shield_advanced_protection_in_route53_hosted_zones:
"prowler.providers.aws.services.shield.shield_service.Shield",
new=shield_client,
), mock.patch(
"prowler.providers.aws.services.route53.route53_service.Route53",
"prowler.providers.aws.services.shield.shield_advanced_protection_in_route53_hosted_zones.shield_advanced_protection_in_route53_hosted_zones.route53_client",
new=route53_client,
):
# Test Check
@@ -116,7 +116,7 @@ class Test_shield_advanced_protection_in_route53_hosted_zones:
"prowler.providers.aws.services.shield.shield_service.Shield",
new=shield_client,
), mock.patch(
"prowler.providers.aws.services.route53.route53_service.Route53",
"prowler.providers.aws.services.shield.shield_advanced_protection_in_route53_hosted_zones.shield_advanced_protection_in_route53_hosted_zones.route53_client",
new=route53_client,
):
# Test Check
@@ -165,7 +165,7 @@ class Test_shield_advanced_protection_in_route53_hosted_zones:
"prowler.providers.aws.services.shield.shield_service.Shield",
new=shield_client,
), mock.patch(
"prowler.providers.aws.services.route53.route53_service.Route53",
"prowler.providers.aws.services.shield.shield_advanced_protection_in_route53_hosted_zones.shield_advanced_protection_in_route53_hosted_zones.route53_client",
new=route53_client,
):
# Test Check