Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(networkfirewall): add new check networkfirewall_policy_rule_group_associated #5225

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"Provider": "aws",
"CheckID": "networkfirewall_policy_rule_group_associated",
"CheckTitle": "Ensure Network Firewall Policies Have at Least One Rule Group Associated",
"CheckType": [
"Software and Configuration Checks/Industry and Regulatory Standards/NIST 800-53"
],
"ServiceName": "Network Firewall",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"ServiceName": "Network Firewall",
"ServiceName": "network-firewall",

"SubServiceName": "Firewall Policy",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"SubServiceName": "Firewall Policy",
"SubServiceName": "",

"ResourceIdTemplate": "arn:partition:network-firewall::account-id:firewall-policy/policy-name",
"Severity": "medium",
"ResourceType": "AwsNetworkFirewallFirewallPolicy",
"Description": "This control checks whether a Network Firewall policy has any stateful or stateless rule groups associated. The control fails if stateless or stateful rule groups are not assigned.",
"Risk": "If a Network Firewall policy does not have at least one rule group associated, it may fail to properly filter and handle traffic, leaving the network vulnerable to unauthorized access and attacks.",
"RelatedUrl": "https://docs.aws.amazon.com/network-firewall/latest/developerguide/rule-groups.html",
"Remediation": {
"Code": {
"CLI": "aws network-firewall update-firewall-policy --firewall-policy-arn <policy-arn> --rule-group-arn <rule-group-arn>",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"CLI": "aws network-firewall update-firewall-policy --firewall-policy-arn <policy-arn> --rule-group-arn <rule-group-arn>",
"CLI": "",

Since this cannot be done with only one single command.

"NativeIaC": "",
"Other": "https://docs.aws.amazon.com/securityhub/latest/userguide/networkfirewall-controls.html#networkfirewall-3",
"Terraform": ""
},
"Recommendation": {
"Text": "Regularly review your Network Firewall policies to ensure they have the necessary rule groups associated. Create and manage rule groups as needed to maintain effective traffic filtering and security.",
"Url": "https://docs.aws.amazon.com/network-firewall/latest/developerguide/firewall-policy-updating.html"
}
},
"Categories": [],
"DependsOn": [],
"RelatedTo": [],
"Notes": ""
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.networkfirewall.networkfirewall_client import (
networkfirewall_client,
)


class networkfirewall_policy_rule_group_associated(Check):
def execute(self):
findings = []
for firewall in networkfirewall_client.network_firewalls.values():
report = Check_Report_AWS(self.metadata())
report.region = firewall.region
report.resource_id = firewall.name
report.resource_arn = firewall.arn
report.resource_tags = firewall.tags
report.status = "PASS"
report.status_extended = f"Network Firewall {firewall.name} policy has at least one rule group associated."
print(firewall.stateless_rule_groups)
print(firewall.stateful_rule_groups)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
print(firewall.stateless_rule_groups)
print(firewall.stateful_rule_groups)

if (
firewall.stateful_rule_groups == []
and firewall.stateless_rule_groups == []
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
firewall.stateful_rule_groups == []
and firewall.stateless_rule_groups == []
not firewall.stateful_rule_groups
and not firewall.stateless_rule_groups

):
report.status = "FAIL"
report.status_extended = f"Network Firewall {firewall.name} policy does not have rule groups associated."

findings.append(report)

return findings
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
from prowler.providers.aws.lib.service.service import AWSService


################## NetworkFirewall
class NetworkFirewall(AWSService):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__("network-firewall", provider)
self.network_firewalls = {}
self.__threading_call__(self._list_firewalls)
self._describe_firewall()
self._describe_firewall_policy()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use threading call for both functions, please?


def _list_firewalls(self, regional_client):
logger.info("Network Firewall - Listing Network Firewalls...")
Expand All @@ -30,10 +30,10 @@
self.network_firewalls[
network_firewall.get("FirewallArn", "")
] = Firewall(
arn=network_firewall.get("FirewallArn"),
region=regional_client.region,
name=network_firewall.get("FirewallName"),
)

except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
Expand Down Expand Up @@ -70,12 +70,47 @@
f"{error.__class__.__name__}:{error.__traceback__.tb_lineno} -- {error}"
)

def _describe_firewall_policy(self):
logger.info("Network Firewall - Describe Network Firewall Policies...")
try:
for network_firewall in self.network_firewalls.values():
regional_client = self.regional_clients[network_firewall.region]
try:
describe_firewall_policy = regional_client.describe_firewall_policy(
FirewallPolicyArn=network_firewall.policy_arn,
)
firewall_policy = describe_firewall_policy.get("FirewallPolicy", {})
network_firewall.stateless_rule_groups = [

Check warning on line 83 in prowler/providers/aws/services/networkfirewall/networkfirewall_service.py

View check run for this annotation

Codecov / codecov/patch

prowler/providers/aws/services/networkfirewall/networkfirewall_service.py#L82-L83

Added lines #L82 - L83 were not covered by tests
group.get("ResourceArn", "")
for group in firewall_policy.get(
"StatelessRuleGroupReferences", []
)
]
network_firewall.stateful_rule_groups = [

Check warning on line 89 in prowler/providers/aws/services/networkfirewall/networkfirewall_service.py

View check run for this annotation

Codecov / codecov/patch

prowler/providers/aws/services/networkfirewall/networkfirewall_service.py#L89

Added line #L89 was not covered by tests
group.get("ResourceArn", "")
for group in firewall_policy.get(
"StatefulRuleGroupReferences", []
)
]
except Exception as error:
logger.error(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the logger pattern, please.

f"Error describing firewall policy {network_firewall.policy_arn} in region {network_firewall.region}: "
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
except Exception as error:
logger.error(

Check warning on line 101 in prowler/providers/aws/services/networkfirewall/networkfirewall_service.py

View check run for this annotation

Codecov / codecov/patch

prowler/providers/aws/services/networkfirewall/networkfirewall_service.py#L100-L101

Added lines #L100 - L101 were not covered by tests
f"{error.__class__.__name__}:{error.__traceback__.tb_lineno} -- {error}"
)


class Firewall(BaseModel):
arn: str
name: str
region: str
policy_arn: str = None
vpc_id: str = None
tags: list = []
encryption_type: str = None
deletion_protection: bool = False
stateless_rule_groups: list[str] = []
stateful_rule_groups: list[str] = []
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ def test_networkfirewall_deletion_protection_disabled(self):
networkfirewall_client.region = AWS_REGION_US_EAST_1
networkfirewall_client.network_firewalls = {
FIREWALL_ARN: Firewall(
arn=FIREWALL_ARN,
name=FIREWALL_NAME,
region=AWS_REGION_US_EAST_1,
policy_arn=POLICY_ARN,
Expand Down Expand Up @@ -95,6 +96,7 @@ def test_networkfirewall_deletion_protection_enabled(self):
networkfirewall_client.region = AWS_REGION_US_EAST_1
networkfirewall_client.network_firewalls = {
FIREWALL_ARN: Firewall(
arn=FIREWALL_ARN,
name=FIREWALL_NAME,
region=AWS_REGION_US_EAST_1,
policy_arn=POLICY_ARN,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ def test_vpcs_with_firewall_all(self):
networkfirewall_client.region = AWS_REGION_US_EAST_1
networkfirewall_client.network_firewalls = {
FIREWALL_ARN: Firewall(
arn=FIREWALL_ARN,
name=FIREWALL_NAME,
region=AWS_REGION_US_EAST_1,
policy_arn=POLICY_ARN,
Expand Down Expand Up @@ -285,6 +286,7 @@ def test_vpcs_with_and_without_firewall(self):
networkfirewall_client.region = AWS_REGION_US_EAST_1
networkfirewall_client.network_firewalls = {
FIREWALL_ARN: Firewall(
arn=FIREWALL_ARN,
name=FIREWALL_NAME,
region=AWS_REGION_US_EAST_1,
policy_arn=POLICY_ARN,
Expand Down
Loading