Skip to main content

Classic Load Balancer Should Be Configured with Defensive or Strictest Desync Mitigation Mode

Overview

This check verifies that your Classic Load Balancer has desync mitigation mode set to either "defensive" or "strictest." Desync mitigation protects your applications from HTTP Desync attacks, which exploit inconsistencies in how servers parse HTTP requests.

Risk

Without proper desync mitigation, your Classic Load Balancer may be vulnerable to HTTP request smuggling attacks. These attacks can lead to:

  • Request queue or cache poisoning - Attackers inject malicious requests that get processed by your backend
  • Session hijacking - Unauthorized access to other users' sessions
  • Credential theft - Sensitive authentication data could be exposed
  • Unauthorized command execution - Attackers may trigger unintended actions on your backend

Remediation Steps

Prerequisites

You need:

  • Access to the AWS Console with permissions to modify load balancers, OR
  • AWS CLI configured with appropriate credentials

AWS Console Method

  1. Open the EC2 Console
  2. In the left navigation, click Load Balancers (under "Load Balancing")
  3. Select your Classic Load Balancer from the list
  4. Click the Attributes tab
  5. Click Edit
  6. Under Traffic configuration, find Desync mitigation mode
  7. Select either:
    • Defensive (recommended) - Balances security with application availability
    • Strictest - Only allows RFC 7230-compliant requests
  8. Click Save changes
AWS CLI (optional)

Check Current Setting

First, verify the current desync mitigation mode:

aws elb describe-load-balancer-attributes \
--load-balancer-name <your-load-balancer-name> \
--region us-east-1 \
--query 'LoadBalancerAttributes.AdditionalAttributes'

Set to Defensive Mode

Create a JSON file named attributes.json:

{
"AdditionalAttributes": [
{
"Key": "elb.http.desyncmitigationmode",
"Value": "defensive"
}
]
}

Then apply the change:

aws elb modify-load-balancer-attributes \
--load-balancer-name <your-load-balancer-name> \
--load-balancer-attributes file://attributes.json \
--region us-east-1

Set to Strictest Mode

If you need maximum protection, use strictest instead:

{
"AdditionalAttributes": [
{
"Key": "elb.http.desyncmitigationmode",
"Value": "strictest"
}
]
}
CloudFormation (optional)

CloudFormation's AWS::ElasticLoadBalancing::LoadBalancer resource does not natively support the AdditionalAttributes property for desync mitigation mode at creation time.

Recommended Approach: Post-Creation Configuration

After deploying your Classic Load Balancer via CloudFormation, use a Custom Resource with AWS Lambda to set the desync mitigation mode, or configure it manually using the AWS CLI.

Example: Custom Resource Lambda

Add this to your CloudFormation template:

AWSTemplateFormatVersion: '2010-09-09'
Description: Classic Load Balancer with Desync Mitigation Mode via Custom Resource

Parameters:
Subnets:
Type: List<AWS::EC2::Subnet::Id>
Description: Subnets for the load balancer

Resources:
ClassicLoadBalancer:
Type: AWS::ElasticLoadBalancing::LoadBalancer
Properties:
LoadBalancerName: my-classic-elb
Subnets: !Ref Subnets
Listeners:
- LoadBalancerPort: 80
InstancePort: 80
Protocol: HTTP

DesyncMitigationLambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: ELBModifyAttributes
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- elasticloadbalancing:ModifyLoadBalancerAttributes
Resource: '*'

DesyncMitigationLambda:
Type: AWS::Lambda::Function
Properties:
Runtime: python3.11
Handler: index.handler
Role: !GetAtt DesyncMitigationLambdaRole.Arn
Timeout: 60
Code:
ZipFile: |
import boto3
import cfnresponse

def handler(event, context):
if event['RequestType'] == 'Delete':
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
return

try:
elb = boto3.client('elb')
elb.modify_load_balancer_attributes(
LoadBalancerName=event['ResourceProperties']['LoadBalancerName'],
LoadBalancerAttributes={
'AdditionalAttributes': [
{
'Key': 'elb.http.desyncmitigationmode',
'Value': event['ResourceProperties']['DesyncMode']
}
]
}
)
cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
except Exception as e:
cfnresponse.send(event, context, cfnresponse.FAILED, {'Error': str(e)})

SetDesyncMitigation:
Type: Custom::DesyncMitigation
DependsOn: ClassicLoadBalancer
Properties:
ServiceToken: !GetAtt DesyncMitigationLambda.Arn
LoadBalancerName: !Ref ClassicLoadBalancer
DesyncMode: defensive

Outputs:
LoadBalancerDNS:
Description: DNS name of the load balancer
Value: !GetAtt ClassicLoadBalancer.DNSName
Terraform (optional)

Terraform's aws_elb resource supports desync mitigation mode directly via the desync_mitigation_mode attribute.

resource "aws_elb" "example" {
name = "my-classic-elb"
availability_zones = ["us-east-1a", "us-east-1b"]

listener {
instance_port = 80
instance_protocol = "HTTP"
lb_port = 80
lb_protocol = "HTTP"
}

health_check {
healthy_threshold = 2
unhealthy_threshold = 2
timeout = 3
target = "HTTP:80/"
interval = 30
}

# Set desync mitigation mode to defensive (recommended)
desync_mitigation_mode = "defensive"

tags = {
Name = "my-classic-elb"
}
}

For Strictest Mode

Change the attribute value:

desync_mitigation_mode = "strictest"

Valid Values

  • monitor - Allows all requests but logs non-compliant ones (NOT compliant with this check)
  • defensive - Recommended balance of security and availability (COMPLIANT)
  • strictest - Maximum security, only RFC 7230-compliant requests allowed (COMPLIANT)

Verification

After making changes, confirm the setting is correct:

  1. In the AWS Console, go to EC2 > Load Balancers
  2. Select your Classic Load Balancer
  3. Click the Attributes tab
  4. Verify that Desync mitigation mode shows "Defensive" or "Strictest"
CLI Verification
aws elb describe-load-balancer-attributes \
--load-balancer-name <your-load-balancer-name> \
--region us-east-1 \
--query 'LoadBalancerAttributes.AdditionalAttributes[?Key==`elb.http.desyncmitigationmode`].Value' \
--output text

Expected output: defensive or strictest

Additional Resources

Notes

Understanding Desync Mitigation Modes

ModeBehaviorUse Case
MonitorAllows all requests, only logs issuesTesting/debugging only - NOT COMPLIANT
DefensiveBlocks severe threats, handles ambiguous requests safelyMost production environments
StrictestOnly allows fully RFC-compliant requestsHigh-security environments

Request Classifications

The load balancer classifies incoming HTTP requests as:

  • Compliant - Fully RFC 7230 compliant, allowed in all modes
  • Acceptable - Minor deviations with no known risk, blocked only in strictest mode
  • Ambiguous - Potential security risk (e.g., multiple Content-Length headers)
  • Severe - High security risk, blocked in all modes except monitor

Monitoring Non-Compliant Requests

After enabling defensive or strictest mode, monitor the DesyncMitigationMode_NonCompliant_Request_Count CloudWatch metric to track how many requests are being classified as non-compliant.

Potential Impact

  • Defensive mode: Minimal impact on legitimate traffic; closes connections for ambiguous requests
  • Strictest mode: May block some legitimate but non-compliant HTTP clients; test thoroughly in staging before production deployment