Skip to main content
emnode / learn
Compliance Medium severity

AWS Security Hub · ELB

ELB.14: CLB desync mitigation mode

Written and reviewed by Emnode · Last reviewed

What does AWS Security Hub ELB.14 check?

ELB.14 fails when a Classic Load Balancer has desync mitigation mode set to monitor. The control accepts only defensive or strictest, where the CLB actively handles ambiguous HTTP requests rather than just logging them.

Why does ELB.14 matter?

Request smuggling exploits a parsing disagreement between the load balancer and the back end, letting an attacker tunnel a hidden request to bypass front-end controls or hijack another user's session. Monitor mode records these requests but still forwards them; defensive mode blocks the attack while staying compatible with normal traffic. It is a single attribute change with a large payoff.

How do I fix ELB.14?

  1. Audit each CLB's desync mitigation mode attribute across the region.
  2. Set it to defensive with modify-load-balancer-attributes for broadly safe protection.
  3. Reserve strictest for cases where you can drop technically non-conforming legacy clients, and roll it out cautiously against fragile back ends.
  4. This is ELB.14's ALB counterpart, ELB.12 — apply the same default everywhere via IaC.

Remediation script · bash

# Harden every Application Load Balancer in the region: reject invalid headers and
# require defensive (or strictest) desync mode. Both are instant, non-disruptive flips.
for arn in $(aws elbv2 describe-load-balancers \
    --query 'LoadBalancers[?Type==`application`].LoadBalancerArn' --output text); do
  aws elbv2 modify-load-balancer-attributes --load-balancer-arn "$arn" \
    --attributes \
      Key=routing.http.drop_invalid_header_fields.enabled,Value=true \
      Key=routing.http.desync_mitigation_mode,Value=defensive
  echo "$arn: hardened"
done

# Switch load-balanced Auto Scaling groups to ELB health checks with a safe grace period
# (confirm the target-group probe reflects real app health first).
for g in $(aws autoscaling describe-auto-scaling-groups \
    --query 'AutoScalingGroups[?(LoadBalancerNames!=`[]` || TargetGroupARNs!=`[]`) && HealthCheckType==`EC2`].AutoScalingGroupName' \
    --output text); do
  aws autoscaling update-auto-scaling-group --auto-scaling-group-name "$g" \
    --health-check-type ELB --health-check-grace-period 300
  echo "$g: now using ELB health checks"
done

Full walkthrough (console steps, edge cases and verification) in the lesson Harden load balancers (ALB/NLB/CLB).

Part of the learning path Build in resilience
  • ELB.1 ALB serves HTTP without redirecting to HTTPS
  • ELB.2 CLB SSL/HTTPS listeners should use ACM certs
  • ELB.3 CLB listeners should use HTTPS/TLS termination
  • ELB.4 ALB accepts malformed HTTP headers
  • ELB.5 Load balancers are not writing access logs
  • ELB.6 Load balancers can be deleted by accident
  • ELB.7 CLBs should have connection draining
  • ELB.8 CLB SSL listeners should use strong policy
  • ELB.9 CLBs should have cross-zone balancing
  • ELB.10 CLBs should span multiple AZs
  • ELB.12 ALB desync mitigation mode
  • ELB.13 A single-AZ load balancer is a data-plane single point of failure