How do I resolve SSL/TLS cipher vulnerabilities on my Application Load Balancer?
A security or compliance scan flagged vulnerable SSL/TLS ciphers on my Application Load Balancer. I want to resolve the vulnerability, and I want to keep connectivity to the client.
Short description
Application Load Balancers use predefined security policies that determine available SSL/TLS protocol versions and cipher suites for SSL/TLS negotiation. Outdated security policies, such as ELBSecurityPolicy-2016-08, support CBC-mode ciphers, non-ECDHE key exchange, TLS 1.0, and TLS 1.1. These ciphers and protocol versions are insecure and fail compliance scans.
To resolve the issue, update your HTTPS listener to use ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09 that's the default security policy and is more restrictive. ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09 supports TLS 1.3 and TLS 1.2 with only GCM-mode ECDHE ciphers. For the most restrictive option, use the ELBSecurityPolicy-TLS13-1-3-2021-06 security policy that supports only TLS 1.3.
Note: You must use a predefined AWS security policy because Application Load Balancers don't support custom security policies.
Resolution
Note: If you receive errors when you run AWS Command Line Interface (AWS CLI) commands, then see Troubleshooting errors for the AWS CLI. Also, make sure that you're using the most recent AWS CLI version.
Prerequisite: Confirm that all clients that connect to your load balancer support the ciphers and TLS versions in the target security policy.
Identify your current security policy
Note: In the following commands, replace REGION with your AWS Region and ACCOUNT with your AWS account ID. Also, replace MY-ALB-NAME with your load balancer name and ALB-ID with your load balancer ID.
Run the following describe-listeners command to identify the security policy that your HTTPS listener uses:
aws elbv2 describe-listeners \--load-balancer-arn arn:aws:elasticloadbalancing:REGION:ACCOUNT:loadbalancer/app/MY-ALB-NAME/ALB-ID \--query "Listeners[?Protocol=='HTTPS'].{Port:Port,Policy:SslPolicy}" \--output table \--region REGION
Then, run the following describe-ssl-policies command to view the ciphers and protocols in the current security policy:
aws elbv2 describe-ssl-policies \--names "ELBSecurityPolicy-2016-08" \--query "SslPolicies[0].{Protocols:SslProtocols,Ciphers:Ciphers[*].Name}" \--output json \--region REGION
Externally test your load balancer to identify the ciphers that clients negotiate. In the output, look for CBC-mode ciphers, non-ECDHE ciphers, or TLS 1.0 and TLS 1.1 connections.
Note: In the following commands, replace MY-ALB-1234567890 with the DNS name of your load balancer.
Run the following nmap command to test the ciphers that your load balancer accepts:
nmap --script ssl-enum-ciphers -p 443 MY-ALB-1234567890.us-east-1.elb.amazonaws.com
Run the following openssl s_client command to test TLS 1.2 connectivity:
openssl s_client -connect MY-ALB-1234567890.us-east-1.elb.amazonaws.com:443 -tls1_2
Run the following openssl s_client command to test TLS 1.3 connectivity:
openssl s_client -connect MY-ALB-1234567890.us-east-1.elb.amazonaws.com:443 -tls1_3
Choose a security policy
Security scanners flag the following cipher types:
- CBC-mode ciphers, such as AES128-SHA, AES256-SHA, ECDHE-RSA-AES128-SHA, are vulnerable to padding oracle attacks, such as BEAST and Lucky13. These ciphers use Cipher Block Chaining mode encryption instead of the more secure Galois/Counter Mode (GCM).
- Non-ECDHE ciphers, such as AES128-GCM-SHA256 and AES256-GCM-SHA384, use RSA key exchange without forward secrecy. If an attacker compromises the server private key, then the attacker can decrypt all past sessions.
- TLS 1.0 and TLS 1.1 are vulnerable to POODLE, BEAST, and other protocol-level attacks. RFC 8996 no longer supports these versions since March 2021. PCI DSS requires at least TLS 1.2.
- SHA-1 based ciphers are vulnerable to collision attacks.
Choose a policy that removes the preceding ciphers based on your security and client compatibility requirements. Compare the ciphers and protocols in each security policy, and then select an appropriate policy for your requirements.
The following security policies are listed from the most secure to the most compatible:
- ELBSecurityPolicy-TLS13-1-3-2021-06 supports only TLS 1.3. The policy removes all CBC-mode ciphers, non ECDHE ciphers, TLS 1.0, and TLS 1.1. Use this policy when all clients support TLS 1.3, and you require maximum security.
- ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09 is the current default security policy on the Elastic Load Balancing (ELB) console. The policy supports TLS 1.3 and TLS 1.2 with only GCM-mode ECDHE ciphers. This policy removes all CBC-mode ciphers and non-ECDHE ciphers. The policy also includes post-quantum key exchange support. Use this policy for security and compatibility for most workloads.
- ELBSecurityPolicy-TLS13-1-2-2021-06 supports TLS 1.3 and TLS 1.2 with ECDHE GCM and CBC ciphers. The policy removes non-ECDHE ciphers but retains CBC-mode ciphers for legacy client support. Use this policy when you must support clients that require CBC ciphers but still require forward secrecy on all connections.
- ELBSecurityPolicy-TLS-1-2-2017-01 supports only TLS 1.2. The policy includes ECDHE GCM/CBC and non-ECDHE GCM/CBC ciphers. The policy removes TLS 1.0 and TLS 1.1 but retains CBC-mode and non-ECDHE ciphers. Use this policy to remove TLS 1.0 and TLS 1.1 when you can't use TLS 1.3.
Use other load balancer types
If your compliance requires a cipher configuration that predefined policies don't support, then take one of the following actions:
- Create a Classic Load Balancer that uses a custom security policy that allows you to activate or deactivate individual ciphers and protocol versions.
- Create a Network Load Balancer with a TCP listener on port 443 to forward encrypted traffic to your backend application. Terminate TLS on the target instance where you have full control over cipher suites, certificate, and protocol versions.
Update the listener security policy
For instructions, see Update the security policy.
Important: The update applies only to new connections. Existing connections remain active until clients reestablish them. There's no downtime during the policy update. However, if you update the security policy while the load balancer handles a high volume of traffic, then disruptions can occur. To decrease the possibility of disruptions, create an additional load balancer to help handle the traffic or request an Load balancer Capacity Unit (LCU) reservation.
Confirm that the listener security policy updated
Note: In the following commands, replace MY-ALB-1234567890 with your load balancer DNS name. Replace MY-ALB-NAME with your load balancer name, ALB-ID with your load balancer ID, and LISTENER-ID with your listener ID.
Run the following describe-listeners command to confirm that the new policy is active:
aws elbv2 describe-listeners \--listener-arn arn:aws:elasticloadbalancing:REGION:ACCOUNT:listener/app/MY-ALB-NAME/ALB-ID/LISTENER-ID \--query "Listeners[0].SslPolicy" \--output text \--region REGION
Run the following nmap command to confirm that your load balancer rejects vulnerable ciphers:
nmap --script ssl-enum-ciphers -p 443 MY-ALB-1234567890.us-east-1.elb.amazonaws.com
Run the following openssl s_client command to confirm that TLS 1.0 is rejected:
openssl s_client -connect MY-ALB-1234567890.us-east-1.elb.amazonaws.com:443 -tls1
Run the following openssl s_client command to confirm that TLS 1.1 is rejected:
openssl s_client -connect MY-ALB-1234567890.us-east-1.elb.amazonaws.com:443 -tls1_1
Run the following openssl s_client command to confirm that TLS 1.2 successfully connects:
openssl s_client -connect MY-ALB-1234567890.us-east-1.elb.amazonaws.com:443 -tls1_2
Run the following openssl s_client command to confirm that TLS 1.3 successfully connects:
openssl s_client -connect MY-ALB-1234567890.us-east-1.elb.amazonaws.com:443 -tls1_3
You can also use connection logs to check the TLS versions and ciphers that your clients use. Connection logs include the tls_protocol, tls_cipher, and tls_keyexchange fields for each connection. To identify clients that require vulnerable ciphers, review the fields before and after the policy change.
Troubleshoot client compatibility issues
You might get one of the following SSL/TLS negotiation errors:
- "ERR_SSL_VERSION_OR_CIPHER_MISMATCH" in browsers
- "Connection refused"
- "Timeout"
If a client doesn't support the ciphers or TLS versions in the new policy, then the client might not connect after you update the security policy.
To determine whether there's an issue with the client connection, check the ClientTLSNegotiationErrorCount Amazon CloudWatch metric for a spike after the policy update.
To identify the affected clients, activate connection logs and review the tls_protocol, tls_cipher, and tls_keyexchange fields. If TLS negotiation fails, then the tls_verify_status field changes to Failed:$error_code, and the tls_protocol and tls_cipher fields change to -. For more information, see Why do I get a client SSL/TLS negotiation error when I connect to my load balancer?
If you must temporarily support legacy clients, then use a less restrictive policy such as ELBSecurityPolicy-TLS13-1-2-2021-06, and then plan a migration timeline for the clients.
If your clients support only TLS 1.0 or TLS 1.1, then upgrade the TLS libraries.
Add security response headers to your load balancer
After you resolve cipher vulnerabilities, add security response headers to strengthen your TLS configuration. The compliance frameworks that flag vulnerable ciphers often require headers, such as Strict-Transport-Security and X-Content-Type-Options.
If Application Load Balancer listener attributes support the header, then add the header to your listener. For a list of supported headers, see HTTP header modification for your Application Load Balancer. To add headers to your listener, see Enable HTTP header modification for your Application Load Balancer.
If Application Load Balancer listener attributes don't support the header, such as the Referrer-Policy header, then configure the header in your application response. Or, use an Amazon CloudFront response headers policy.
Related information
- Language
- English

This article was reviewed and updated on 2026-07-08.
Relevant content
asked 3 years ago
asked 4 years ago