ELB application load balancers should be configured with defensive or strictest desync mitigation mode
HTTP desync (request smuggling) attacks exploit inconsistencies in how front-end proxies and back-end servers parse HTTP requests. An attacker who can smuggle a crafted request past the ALB can poison connection pools, hijack other users' sessions, or bypass security controls entirely. The "monitor" mode emits CloudWatch metrics for suspect requests but still forwards them, leaving back-end targets fully exposed.
Setting the mode to "defensive" causes the ALB to normalize known-ambiguous requests before routing. That stops most desync vectors with minimal application impact. The "strictest" mode goes further by rejecting any request that doesn't fully comply with RFC 7230. It may break some legacy clients, but it eliminates the attack surface almost entirely.
Retrofit consideration
Switching from "monitor" to "strictest" may reject legitimate but non-compliant HTTP requests from older clients. Test with "defensive" first and review the DesyncMitigationMode_NonCompliant_Request_Count metric before tightening.
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 "alb" {
source = "nistcsfv11.compliance.tf/terraform-aws-modules/alb/aws"
version = ">=10.0.0,<11.0.0"
access_logs = {
bucket = "example-bucket-abc123"
enabled = true
}
internal = true
listeners = {
https = {
certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
forward = {
target_group_key = "default"
}
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
}
}
load_balancer_type = "application"
name = "abc123"
security_groups = ["sg-abc12345"]
subnets = ["subnet-abc123", "subnet-def456"]
target_groups = {
default = {
create_attachment = false
name_prefix = "def-"
port = 443
protocol = "HTTPS"
target_type = "ip"
}
}
vpc_id = "vpc-12345678"
desync_mitigation_mode = "defensive"
}
module "alb" {
source = "pcidssv321.compliance.tf/terraform-aws-modules/alb/aws"
version = ">=10.0.0,<11.0.0"
access_logs = {
bucket = "example-bucket-abc123"
enabled = true
}
internal = true
listeners = {
https = {
certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
forward = {
target_group_key = "default"
}
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
}
}
load_balancer_type = "application"
name = "abc123"
security_groups = ["sg-abc12345"]
subnets = ["subnet-abc123", "subnet-def456"]
target_groups = {
default = {
create_attachment = false
name_prefix = "def-"
port = 443
protocol = "HTTPS"
target_type = "ip"
}
}
vpc_id = "vpc-12345678"
desync_mitigation_mode = "defensive"
}
If you use terraform-aws-modules/alb/aws, 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 "alb" {
source = "terraform-aws-modules/alb/aws"
version = ">=10.0.0,<11.0.0"
access_logs = {
bucket = "example-bucket-abc123"
enabled = true
}
internal = true
listeners = {
https = {
certificate_arn = "arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"
forward = {
target_group_key = "default"
}
protocol = "HTTPS"
ssl_policy = "ELBSecurityPolicy-TLS13-1-2-2021-06"
}
}
load_balancer_type = "application"
name = "abc123"
security_groups = ["sg-abc12345"]
subnets = ["subnet-abc123", "subnet-def456"]
target_groups = {
default = {
create_attachment = false
name_prefix = "def-"
port = 443
protocol = "HTTPS"
target_type = "ip"
}
}
vpc_id = "vpc-12345678"
desync_mitigation_mode = "defensive"
}
Use AWS provider resources directly. See docs for the resources involved: aws_lb.
resource "aws_lb" "this" {
access_logs {
bucket = "pofix-logs-abc123"
}
internal = true
name = "pofix-abc123"
subnets = ["subnet-abc123", "subnet-def456"]
desync_mitigation_mode = "defensive"
}
What this control checks
In the aws_lb resource with load_balancer_type = "application", the desync_mitigation_mode argument controls this behavior. Accepted values are "monitor", "defensive", and "strictest". The Terraform default is "defensive", which passes this control. A configuration explicitly set to "monitor" fails. To pass, either omit desync_mitigation_mode (taking the "defensive" default) or set it to "defensive" or "strictest". No other resources or arguments are involved.
Common pitfalls
Default is compliant but explicit overrides are common
The Terraform default for
desync_mitigation_modeonaws_lbis"defensive", so new ALBs pass without any explicit setting. The risk is older module code or configurations left over from a debugging session that set it to"monitor"and never got reverted. That override silently persists. Search your codebase fordesync_mitigation_modebefore assuming you're clean.Strictest mode can break chunked transfer encoding edge cases
"strictest"rejects any request with ambiguous headers, including some technically valid chunked-encoding patterns. Get this wrong on an ALB fronting file uploads or streaming payloads and you'll see 400 errors for legitimate traffic. Validate behavior at"defensive"first, confirmDesyncMitigationMode_NonCompliant_Request_Countstays low, then decide whether the extra restriction is worth it.Control applies only to ALBs, not NLBs or GLBs
desync_mitigation_modeis only valid onaws_lbresources withload_balancer_type = "application". Set it on a Network or Gateway Load Balancer and Terraform will error. If your modules iterate over multiple load balancer types, gate this attribute behind a conditional.
Audit evidence
AWS Config's alb-desync-mode-check managed rule provides evaluation results showing ALB compliance status across the account. Console evidence comes from EC2 > Load Balancers: select each ALB and check the "Desync mitigation mode" attribute on the Attributes tab for "Defensive" or "Strictest".
The DesyncMitigationMode_NonCompliant_Request_Count CloudWatch metric per ALB supplements evidence by showing whether suspect traffic is actually reaching the load balancer. Security Hub aggregates this control's finding status across accounts and regions into a single consolidated artifact.
Framework-specific interpretation
NIST Cybersecurity Framework v1.1: PR.PT under the Protect function covers protective technology for communications and control networks. Desync mitigation normalizes or rejects malformed HTTP before it reaches back-end services, which is exactly the kind of traffic hardening PR.PT calls for.
PCI DSS v3.2.1: Requirements 6.5 and 6.6 call for protection against web-facing application attacks, including injection and input validation failures. Desync mitigation is a complementary technical control that reduces exposure to malformed HTTP techniques, but it doesn't replace secure coding practices, code review, or WAF requirements.
Related controls
ELB classic load balancers should span multiple availability zones
ECS services should not have public IP addresses assigned automatically
Tool mappings
Use these identifiers to cross-reference this control across tools, reports, and evidence.
Compliance.tf Control:
elb_application_lb_desync_mitigation_modeAWS Config Managed Rule:
ALB_DESYNC_MODE_CHECKCheckov Check:
CKV_AWS_328Powerpipe Control:
aws_compliance.control.elb_application_lb_desync_mitigation_modeProwler Check:
elbv2_desync_mitigation_modeAWS Security Hub Control:
ELB.12
Last reviewed: 2026-03-09