AWS Security Hub · ELB
ELB.4: ALB accepts malformed HTTP headers
Written and reviewed by Emnode · Last reviewed
What does AWS Security Hub ELB.4 check?
ELB.4 fails when an Application Load Balancer has the drop_invalid_header_fields attribute set to false. With the attribute off, the ALB forwards requests whose headers contain characters that are not valid per the HTTP spec.
Why does ELB.4 matter?
When a front-end load balancer and a back-end target disagree on where one request ends and the next begins, an attacker can smuggle a hidden request inside a malformed Content-Length or Transfer-Encoding header — HTTP desync. That can poison caches, bypass auth on the front end, or hijack another user's session. Dropping invalid headers removes the ambiguity the attack depends on.
How do I fix ELB.4?
- Audit each ALB with describe-load-balancer-attributes and check routing.http.drop_invalid_header_fields.enabled.
- Set it to true with modify-load-balancer-attributes; the change is non-disruptive to well-formed traffic.
- Pair this with ELB.5 (access logs) and ELB.12 (defensive desync mode) for a hardened perimeter.
- Default the attribute on in your IaC so new ALBs are compliant from creation.
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).
More ELB controls
- 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.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
- ELB.14 CLB desync mitigation mode