From 52ffa95696518f89d7a6535380a56e8996dba45d Mon Sep 17 00:00:00 2001 From: Dirk Date: Wed, 14 Jan 2026 20:22:59 +0100 Subject: [PATCH 1/3] Flag absence of extended master secret extension This PR fixes #2806 and implements a feature request. TLS >=1.2 MUST support support the extended_master_secret extension to address an attack resulting from TLS session parameters not being properly authenticated in a Triple Handshake scanario (https://ieeexplore.ieee.org/document/6956559). Only if the extension is missing there will be a medium severity level finding. JSON output will be generated in any case. Also in determine_tls_extensions() some documenation about tls extensions to be send were added. --- testssl.sh | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index e716009..57997f9 100755 --- a/testssl.sh +++ b/testssl.sh @@ -8223,6 +8223,12 @@ determine_tls_extensions() { "$SSL_NATIVE" && using_sockets=false if "$using_sockets"; then + # 01 max_fragment_length, RFC 6066 + # 02 client_certificate_url, RFC 6066 + # 04 truncated_hmac, RFC 6066 + # signed_certificate_timestamp, RFC 6962 + # encrypt_then_mac, RFC 7366 + # extended_master_secret, RFC 7627 tls_extensions="00,01,00,01,02, 00,02,00,00, 00,04,00,00, 00,12,00,00, 00,16,00,00, 00,17,00,00" if [[ -z $STARTTLS ]]; then for alpn_proto in $ALPN_PROTOs; do @@ -10407,6 +10413,7 @@ certificate_info() { return $ret } + run_server_defaults() { local ciph newhostcert sni local match_found @@ -10421,6 +10428,7 @@ run_server_defaults() { local -a -i success local cn_nosni cn_sni sans_nosni sans_sni san tls_extensions extn client_auth_ca local using_sockets=true + local spaces=" " "$SSL_NATIVE" && using_sockets=false @@ -10677,7 +10685,7 @@ run_server_defaults() { pr_headlineln " Testing server defaults (Server Hello) " outln - pr_bold " TLS extensions (standard) " + pr_bold " TLS extensions " if [[ ${#TLS_EXTENSIONS[*]} -eq 0 ]]; then outln "(none)" fileout "TLS_extensions" "INFO" "(none)" @@ -10702,6 +10710,28 @@ run_server_defaults() { outln "$tls_extensions" fi + # We want to check whether the (for >=TLS 1.2) mandatory "extended master secret" extension is supported by + # the server. Otherwise it would violate RFC 9325 https://www.rfc-editor.org/rfc/rfc9325#section-3.5 + # and cause connection problems. + jsonID="TLS_misses_extension_23" + if [[ $(has_server_protocol "tls1_2") -eq 1 ]] && [[ $(has_server_protocol "tls1_3") -eq 1 ]] ; then + : + elif [[ $tls_extensions =~ \#23 ]]; then + # Was the last handshake >= TLS 1.2 ? + if grep -qE 'Protocol.*(TLSv1.3|TLSv1.2)' $TEMPDIR/$NODEIP.parse_tls_serverhello.txt ; then + fileout "$jsonID" "INFO" "Extended master secret extension detected" + debugme outln "${spaces}Extended master secret extension detected" + else + out "$spaces" + prln_warning "Fixme: Server supports TLS 1.2 or 1.3 but last ServerHello was < TLS 1.2" + fileout "$jsonID" "WARN" "Server supports TLS 1.2 or 1.3 but last ServerHello was < TLS 1.2" + fi + else + out "$spaces" + prln_svrty_medium "No extended master secret extension, violates RFC 9325 & may cause connection problems" + fileout "$jsonID" "MEDIUM" "No extended master secret extension, violates RFC 9325 & may cause connection problems" + fi + pr_bold " Session Ticket RFC 5077 hint " jsonID="TLS_session_ticket" if [[ -z "$sessticket_lifetime_hint" ]]; then @@ -10923,6 +10953,7 @@ run_server_defaults() { return $ret } + get_session_ticket_lifetime_from_serverhello() { awk '/session ticket.*lifetime/ { print $(NF-1) "$1" }' } From d78fae2dce40a0477e276b0911675b7aad3ad007 Mon Sep 17 00:00:00 2001 From: Dirk Date: Wed, 14 Jan 2026 20:37:33 +0100 Subject: [PATCH 2/3] Add extended_master_secret extension --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a546b5..a72ad4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * QUIC protocol check * TLS 1.3 early data (0-RTT) +* Adds a check for mandatory extended master secret TLS extension * Bump SSLlabs rating guide to 2009r * Check for Opossum vulnerability * Enable IPv6 automagically, i.e. if target via IPv6 is reachable just (also) scan it From ca55c5b1808127946e4eb14b255a3505ee62d4ea Mon Sep 17 00:00:00 2001 From: Dirk Date: Thu, 15 Jan 2026 11:20:01 +0100 Subject: [PATCH 3/3] Exempt the debug statement "Extended master secret extension detected" --- t/32_isHTML_valid.t | 1 + 1 file changed, 1 insertion(+) diff --git a/t/32_isHTML_valid.t b/t/32_isHTML_valid.t index 39ea276..853cc1d 100755 --- a/t/32_isHTML_valid.t +++ b/t/32_isHTML_valid.t @@ -96,6 +96,7 @@ $debughtml =~ s/No engine or GOST support via engine with your.*\n//g; $debughtml =~ s/.*built: .*\n//g; $debughtml =~ s/.*Using bash .*\n//g; $debughtml =~ s/.*has_compression.*\n//g; +$debughtml =~ s/.*Extended master secret extension detected.*\n//g; # is whole line: s/.* .*\n//g; # Extract and mask IP address as it can change