Am I affected?

type your erlang.org/otp version to check

Description

Improper Validation of Consistency within Input vulnerability in Erlang OTP ssl (tls_handshake_1_3, ssl_handshake and tls_client_ticket_store modules) allows a malicious TLS 1.3 server to cause a denial of service of the ssl application on the client node.

The TLS 1.3 client decodes the extensions of a NewSessionTicket message as if they came from EncryptedExtensions. It therefore accepts a 0-length early_data extension, a form that is only valid in ClientHello and EncryptedExtensions. With {session_tickets, auto}, the client stores the ticket in the node-global tls_client_ticket_store. On the next automatic resumption, tls_handshake_1_3:get_max_early_data/1 crashes the store with a case_clause. Repeated crashes can exceed the restart intensity of the ssl supervisors, which use the rest_for_one strategy, and take down ssl for all connections on the node.

This issue affects OTP from OTP 23.3 before OTP 27.3.4.19, OTP 28.5.0.8, and OTP 29.1.2, corresponding to ssl from 10.3 before 11.2.12.14, 11.6.0.7, and 11.7.8.

Technical analysis

1. Decoding. tls_handshake_1_3:decode_handshake/2 decodes the extensions of a NewSessionTicket with the message type encrypted_extensions. ssl_handshake:decode_extensions/4 does not check the message type for most extensions. A 0-length early_data extension therefore decodes to #early_data_indication{}, the ClientHello and EncryptedExtensions form, and not to #early_data_indication_nst{}, the 4-byte max_early_data_size form that RFC 8446 requires in a NewSessionTicket.

2. Storage. In auto mode the client sends the ticket to the node-global tls_client_ticket_store gen_server, which keeps it for later resumption.

3. Crash. When a later connection resumes automatically, the store calls tls_handshake_1_3:get_max_early_data/1 on the stored extensions, from maybe_use_ticket and get_tickets. That function only handles undefined and #early_data_indication_nst{}, so the store process crashes with a case_clause.

4. Escalation. The store is a permanent child of ssl_admin_sup. Each restart of the store also restarts the children after it, because the supervisor uses rest_for_one. A server that keeps sending the malformed ticket makes the crashes repeat. When the crashes exceed the supervisor restart intensity, the failure goes up through ssl_sup and stops the ssl application for the whole node.

The fix makes ssl_handshake:decode_extensions/4 accept each extension form only in the handshake messages where it is permitted, and decodes NewSessionTicket extensions with the message type new_session_ticket.

Weaknesses & attack patterns

Weakness

CWE-1288 · Improper Validation of Consistency within Input in catalog → MITRE ↗

Attack patterns

CAPEC-153 · Input Data Manipulation MITRE ↗

A malicious TLS 1.3 server can crash the client node's session ticket store, and by repeating the attack it can stop the ssl application for all TLS connections on that node. Only clients that use {session_tickets, auto} are affected.

Affected — Erlang

≥ 23.3 and up affected
→ 27.3.4.19 not affected
→ 28.5.0.8 not affected
→ 29.1.2 not affected
every other version: unaffected
cpe cpe:2.3:a:erlang:erlang/otp:*:*:*:*:*:*:*:*
version type otp
modules · source files · routines
modules ssl_handshake · tls_handshake_1_3 · tls_client_ticket_store
source files lib/ssl/src/ssl_handshake.erl · lib/ssl/src/tls_handshake_1_3.erl · lib/ssl/src/tls_client_ticket_store.erl
routines ssl_handshake:decode_extensions/4 · tls_handshake_1_3:decode_handshake/2 · tls_handshake_1_3:get_max_early_data/1 · tls_client_ticket_store:find_ticket/5 · tls_client_ticket_store:get_tickets/2

Affected — Erlang / ssl Repository ↗

≥ 10.3 and up affected
→ 11.2.12.14 not affected
→ 11.6.0.7 not affected
→ 11.7.8 not affected
every other version: unaffected
cpe cpe:2.3:a:erlang:erlang/otp:*:*:*:*:*:*:*:*
version type otp
modules · source files · routines
modules ssl_handshake · tls_handshake_1_3 · tls_client_ticket_store
source files src/ssl_handshake.erl · src/tls_handshake_1_3.erl · src/tls_client_ticket_store.erl
routines ssl_handshake:decode_extensions/4 · tls_handshake_1_3:decode_handshake/2 · tls_handshake_1_3:get_max_early_data/1 · tls_client_ticket_store:find_ticket/5 · tls_client_ticket_store:get_tickets/2

Affected — GitHub / erlang/otp Repository ↗

≥ 0abe6f6 and up affected
→ 66febc1 not affected
→ 00a333b not affected
→ cd03348 not affected
every other version: unaffected
cpe cpe:2.3:a:erlang:erlang/otp:*:*:*:*:*:*:*:*
version type git
modules · source files · routines
modules ssl_handshake · tls_handshake_1_3 · tls_client_ticket_store
source files lib/ssl/src/ssl_handshake.erl · lib/ssl/src/tls_handshake_1_3.erl · lib/ssl/src/tls_client_ticket_store.erl
routines ssl_handshake:decode_extensions/4 · tls_handshake_1_3:decode_handshake/2 · tls_handshake_1_3:get_max_early_data/1 · tls_client_ticket_store:find_ticket/5 · tls_client_ticket_store:get_tickets/2

Workarounds

Do not set {session_tickets, auto} on TLS 1.3 clients. Use manual ticket handling, or keep the default value disabled.

Configurations

Only TLS 1.3 clients that set the ssl option {session_tickets, auto} are affected. The default value of session_tickets is disabled, and clients that use manual ticket handling do not store tickets in the node-global ticket store. The client must also connect to a server that the attacker controls, or that the attacker can impersonate.

References

Credits

Lukas Backström / Erlang Solutions Reporter
Ingela Anderton Andin Remediation developer
Jonatan Männchen / EEF Coordinator Analyst

CVSS breakdown

CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
« All CVEs