Network Firewall policies should have default stateless action set to drop or forward for full packets
With aws:pass as the default stateless action, any packet that doesn't match an explicit stateless rule flows through the firewall without being blocked or inspected. That's the opposite of what you deployed a network firewall for: traffic that skips stateless matching gets a free pass unless something else in the stack catches it.
aws:drop blocks unmatched traffic outright. aws:forward_to_sfe sends it to the stateful engine for deeper inspection. Both are acceptable. The goal is that unknown traffic doesn't slide through by default.
Retrofit consideration
Changing the default from pass to drop on an existing firewall policy may immediately block legitimate traffic that previously relied on the permissive default. Audit stateless rule coverage before switching.
Implementation
Choose the approach that matches how you manage Terraform.
Use the compliance.tf module to enforce this control by default. See get started with compliance.tf.
module "network_firewall" {
source = "pcidss.compliance.tf/terraform-aws-modules/network-firewall/aws//modules/policy"
version = ">=1.0.0"
name = "abc123-policy"
}
module "network_firewall" {
source = "nistcsf.compliance.tf/terraform-aws-modules/network-firewall/aws//modules/policy"
version = ">=1.0.0"
name = "abc123-policy"
}
module "network_firewall" {
source = "nistcsfv11.compliance.tf/terraform-aws-modules/network-firewall/aws//modules/policy"
version = ">=1.0.0"
name = "abc123-policy"
}
If you use terraform-aws-modules/network-firewall/aws//modules/policy, set the right module inputs for this control. You can later migrate to the compliance.tf module with minimal changes because it is compatible by design.
module "network_firewall" {
source = "terraform-aws-modules/network-firewall/aws//modules/policy"
version = ">=1.0.0"
name = "abc123-policy"
}
Use AWS provider resources directly. See docs for the resources involved: aws_networkfirewall_firewall_policy.
resource "aws_networkfirewall_firewall_policy" "this" {
firewall_policy {
stateless_default_actions = ["aws:drop"]
stateless_fragment_default_actions = ["aws:drop"]
}
name = "pofix-abc123"
}
What this control checks
stateless_default_actions lives in the firewall_policy block of the aws_networkfirewall_firewall_policy resource. It takes a list of action strings applied to full packets when no stateless rule matches. The control passes when the list includes "aws:drop" or "aws:forward_to_sfe" and fails when it is set to ["aws:pass"]. A typical passing configuration is stateless_default_actions = ["aws:forward_to_sfe"] to hand unmatched packets to the stateful engine, or stateless_default_actions = ["aws:drop"] to silently discard them.
Common pitfalls
Confusing full packet and fragment default actions
There are two distinct default action arguments:
stateless_default_actionsfor full packets, andstateless_fragment_default_actionsfor fragmented packets. This control only checks the first. You can setstateless_fragment_default_actionsto drop and still fail here ifstateless_default_actionsisaws:pass. A separate check covers fragments.Custom action names masking a pass
Defining a
stateless_custom_actionfor metrics publishing is common, and including that custom action name instateless_default_actionsis fine. The problem is when that list also containsaws:pass. A custom action alongsideaws:passdoesn't neutralize the pass. The standard action in the list must beaws:droporaws:forward_to_sfe.Terraform import of existing policies
Get this wrong on an import and you won't know until you run a plan against corrected config.
terraform importon an existing firewall policy reflects whatever default action is already live. If the policy was created withaws:pass, that ends up in state and Terraform won't flag it until your configuration explicitly sets something different. Always inspectstateless_default_actionsin imported state before treating the resource as compliant.
Audit evidence
Config rule networkfirewall-policy-default-action-full-packets should return COMPLIANT for each in-scope firewall policy. A screenshot of the Stateless default actions section on the firewall policy detail page confirms the full packet default is Drop or Forward to stateful rule groups. CloudTrail UpdateFirewallPolicy and CreateFirewallPolicy events show no policy was created or modified with a pass default during the audit period.
Framework-specific interpretation
PCI DSS v4.0: Requirement 1 covers network security controls, and PCI DSS v4.0 is explicit about default-deny intent for unauthorized traffic. A stateless default of aws:pass can conflict with that intent unless compensating rules enforce effective deny-by-default behavior elsewhere in the policy.
NIST Cybersecurity Framework v2.0: PR.PS under the Protect function calls for implemented, managed protections for platforms and infrastructure. Restricting the default stateless action to drop or forward is the kind of explicit network traffic control that satisfies that expectation.
Related controls
Tool mappings
Use these identifiers to cross-reference this control across tools, reports, and evidence.
Compliance.tf Control:
networkfirewall_firewall_policy_default_stateless_action_check_full_packetsAWS Config Managed Rule:
NETFW_POLICY_DEFAULT_ACTION_FULL_PACKETSPowerpipe Control:
aws_compliance.control.networkfirewall_firewall_policy_default_stateless_action_check_full_packetsProwler Check:
networkfirewall_policy_default_action_full_packetsAWS Security Hub Control:
NetworkFirewall.4
Last reviewed: 2026-03-09