Skip to main content
emnode
Compliance Medium severity

AWS Security Hub · NetworkFirewall

NetworkFirewall.10: Firewalls should have subnet change protection

Written and reviewed by Emnode · Last reviewed

What does AWS Security Hub NetworkFirewall.10 check?

NetworkFirewall.10 checks whether a firewall has SubnetChangeProtection enabled. AWS initialises it to TRUE at creation, so a failing finding means someone actively turned it off, leaving any principal with AssociateSubnets or DisassociateSubnets permission free to re-point the firewall in a single call.

Why does NetworkFirewall.10 matter?

With protection off, one DisassociateSubnets call can move the firewall's endpoints out of the path of production traffic, and nothing alarms: the firewall stays READY, the hourly and per-GB charges keep accruing, and dashboards show a healthy firewall. The only thing that changed is that traffic you believed was inspected now isn't: the silent inspection bypass auditors care most about.

How do I fix NetworkFirewall.10?

  1. Set SubnetChangeProtection to TRUE on every firewall.
  2. Require the deliberate two-step (disable protection, then change associations) for any legitimate subnet change.
  3. Pin the setting in IaC and add deletion protection alongside it.

Remediation script · bash

# Attach the AWS Managed Rules common baseline to an empty web ACL, in Count mode.
# update-web-acl REPLACES the entire Rules array, so supply the full desired set and the current LockToken.
aws wafv2 update-web-acl \
  --scope REGIONAL --name public-alb-waf --id a1b2c3d4-0000-1111-2222-3333 \
  --lock-token e4f5g6h7 --default-action Allow={} \
  --visibility-config SampledRequestsEnabled=true,CloudWatchMetricsEnabled=true,MetricName=public-alb-waf \
  --rules '[{"Name":"AWS-CommonRuleSet","Priority":0,"Statement":{"ManagedRuleGroupStatement":{"VendorName":"AWS","Name":"AWSManagedRulesCommonRuleSet"}},"OverrideAction":{"Count":{}},"VisibilityConfig":{"SampledRequestsEnabled":true,"CloudWatchMetricsEnabled":true,"MetricName":"AWS-CommonRuleSet"}}]'

# Associate a baseline web ACL with an unprotected API Gateway stage (the resource ARN is the stage, not the API).
aws wafv2 associate-web-acl \
  --web-acl-arn arn:aws:wafv2:us-east-1:111122223333:regional/webacl/prod-api-baseline/1a2b3c4d \
  --resource-arn arn:aws:apigateway:us-east-1::/restapis/a1b2c3d4e5/stages/prod

# Protect a Network Firewall from accidental deletion.
aws network-firewall update-firewall-delete-protection \
  --firewall-name prod-egress-inspection --delete-protection

Full walkthrough (console steps, edge cases and verification) in the lesson Protect APIs and edge with WAF.

Is NetworkFirewall.10 a false positive?

A few teams deliberately leave SubnetChangeProtection FALSE on firewalls that a deployment pipeline re-homes on every run (for example blue/green or AZ-migration automation that calls DisassociateSubnets and AssociateSubnets unattended), where forcing the protect/unprotect two-step on each apply just adds a failure mode. That is a legitimate trade-off when the only principal that can change associations is a tightly scoped pipeline role and the change itself is gated in CI. Don't flip the flag on to silence the finding and then have your next deploy fail; instead suppress it deliberately: set the finding's workflow status to SUPPRESSED (manually or with a Security Hub automation rule matching ComplianceSecurityControlID and the specific ResourceId) and record the pipeline-owned-rotation reason in the note so the exception is auditable.

Part of the learning path Lock down access