Aller au contenu

STARTTLS : attaque par retrait, MTA-STS et TLS implicite

STARTTLS : attaque par retrait, MTA-STS et TLS implicite

Section intitulée « STARTTLS : attaque par retrait, MTA-STS et TLS implicite »

STARTTLS ouvre une connexion en clair, puis la bascule en TLS (Transport Layer Security) sur le même port grâce à une commande négociée en clair. Tout ce qui précède la bascule est donc modifiable par quiconque se trouve sur le chemin, et c’est là que se logent les attaques par retrait et par injection. Cette page indique ce qu’il faut garder, ce qu’il faut remplacer par du TLS implicite, et comment durcir le seul cas où STARTTLS reste incontournable : le courrier entre serveurs.

→ Lire l’explication complète de la marmotte

STARTTLS dans SMTP, IMAP et LDAP : un même schéma, trois protocoles

Section intitulée « STARTTLS dans SMTP, IMAP et LDAP : un même schéma, trois protocoles »

Le principe est identique partout. Le client se connecte au port historique, le serveur annonce ses capacités en clair, le client envoie une commande de bascule, puis la poignée de main TLS démarre.

  • SMTP (Simple Mail Transfer Protocol), RFC 3207 : le serveur annonce 250-STARTTLS dans sa réponse à EHLO (port 25 entre serveurs, 587 pour la soumission).
  • IMAP (Internet Message Access Protocol) et POP3 (Post Office Protocol version 3), RFC 2595 : capacité STARTTLS (ou STLS en POP3) sur les ports 143 et 110.
  • LDAP (Lightweight Directory Access Protocol), RFC 4511 et 4513 : opération étendue StartTLS (OID 1.3.6.1.4.1.1466.20037) sur le port 389.

En face, le TLS implicite démarre la poignée de main dès l’ouverture TCP, sans aucun échange applicatif préalable : 465 pour la soumission SMTP, 993 pour IMAPS, 995 pour POP3S, 636 pour LDAPS. La RFC 8314 (2018) a tranché pour le courrier côté client : TLS implicite recommandé, STARTTLS toléré. Le port 465, déclaré obsolète puis réhabilité, a eu la carrière d’un dossier qu’on croyait classé.

Le problème de fond tient en une phrase : avec STARTTLS, la décision de chiffrer est prise sur un canal que l’attaquant contrôle. Le TLS en lui-même n’est pas en cause (voir le fonctionnement de TLS) ; c’est la phase en clair qui le précède.

Attaque par retrait de STARTTLS (STARTTLS stripping)

Section intitulée « Attaque par retrait de STARTTLS (STARTTLS stripping) »

Un attaquant en position d’intermédiaire, MITM (Man-in-the-Middle), obtenue par l’un des moyens décrits dans l’attaque de l’intercepteur, retire la capacité STARTTLS de la réponse du serveur. Un client configuré en mode opportuniste (« chiffrer si possible ») conclut que le serveur ne sait pas chiffrer et continue en clair. Aucune alerte, aucun journal côté client, et le message arrive à destination : l’attaque ne casse rien de visible.

Séquence entre trois acteurs : un client SMTP, un attaquant placé en intermédiaire et un serveur MX. Le client envoie EHLO à l'attaquant, qui le transmet au serveur. Le serveur répond 250-STARTTLS, 250-SIZE, 250 8BITMIME ; l'attaquant renvoie au client 250-XXXXXXXA, 250-SIZE, 250 8BITMIME, où STARTTLS a disparu. Le client, s'il est en mode opportuniste, envoie alors MAIL FROM, RCPT TO et DATA en clair à l'attaquant, qui relaie le message au serveur en en conservant une copie.

Le schéma montre que le serveur et le client se comportent tous deux « correctement » : la variante qui remplace STARTTLS par une chaîne de même longueur évite même de recalculer les tailles de segments TCP. Des équipements de filtrage commerciaux ont longtemps pratiqué ce remplacement pour « inspecter » le courrier ; la frontière entre fonctionnalité de pare-feu et attaque tient parfois à la ligne de la plaquette.

Deux variantes aggravent le cas :

  • Pas de validation de certificat. Entre serveurs de messagerie, MTA (Mail Transfer Agent), la pratique historique (formalisée par la RFC 7435, Opportunistic Security) accepte n’importe quel certificat, auto-signé ou expiré compris. Même quand la bascule a lieu, un intermédiaire actif présente son propre certificat et déchiffre tout. STARTTLS opportuniste ne protège donc que contre l’écoute passive.
  • IMAP PREAUTH. Un serveur IMAP peut accueillir le client par * PREAUTH, ce qui le place directement en état authentifié. Or la RFC 3501 n’autorise STARTTLS qu’en état non authentifié : un client qui exige TLS doit couper la connexion, et beaucoup ont longtemps choisi de continuer en clair. L’attaquant injecte PREAUTH, le client n’envoie certes pas son mot de passe, mais lit et dépose les messages sur un canal contrôlé par l’attaquant.

La seule contre-mesure côté client est la configuration obligatoire : TLS requis, certificat validé, échec franc sinon. Pour un client de messagerie ou un client LDAP, c’est un réglage. Pour un MTA qui écrit à des milliers de domaines inconnus, c’est impossible sans information externe sur la politique du destinataire : c’est le rôle de MTA-STS et de DANE, plus bas.

Injection de commandes STARTTLS et désynchronisation du tampon

Section intitulée « Injection de commandes STARTTLS et désynchronisation du tampon »

La seconde famille d’attaques ne retire rien : elle ajoute. Un attaquant colle des commandes en clair derrière STARTTLS dans le même segment TCP. Une implémentation qui ne vide pas son tampon de lecture au moment de la bascule exécute ensuite ces commandes comme si elles avaient été reçues à l’intérieur du canal TLS, donc avec la confiance accordée au client authentifié.

Séquence entre trois acteurs : Client, Attaquant et Serveur. 1. Le client envoie STARTTLS, que l'attaquant reçoit. 2. L'attaquant transmet au serveur, dans un seul segment, « STARTTLS\r\nRSET\r\nMAIL FROM:attaquant@example.net\r\n ». 3. Si l'implémentation est vulnérable, le serveur traite STARTTLS et garde le reste en tampon. 4. Le client fait la poignée de main TLS avec le serveur, puis envoie ses propres commandes. 5. Le serveur exécute d'abord les commandes injectées, dans le contexte chiffré.

À lire dans l’ordre : le serveur ne distingue pas l’origine des octets restés dans le tampon, et la frontière clair/chiffré se décale. Le cas d’école est CVE-2011-0411 (Postfix, corrigé en 2011), mais la classe de bogue n’a jamais disparu : l’étude Why TLS is better without STARTTLS (USENIX Security 2021) a relevé plus de quarante vulnérabilités dans des clients et serveurs SMTP, IMAP et POP3 répandus, dont l’injection de réponses côté client (le client met en tampon une réponse forgée en clair et l’interprète après la bascule comme si elle venait du serveur authentifié, ce qui permet par exemple de lui présenter un contenu de boîte aux lettres fabriqué par l’attaquant).

La contre-mesure correcte est connue et triviale à énoncer : vider le tampon de lecture et rejeter toute donnée excédentaire au moment de la bascule, côté serveur comme côté client. Elle dépend entièrement de l’implémentation. Aucune configuration ne la remplace ; seul le maintien à jour des logiciels, ou l’abandon de STARTTLS au profit du TLS implicite, la rend inutile. Le TLS implicite n’a pas de tampon à désynchroniser, puisqu’il n’y a rien avant la poignée de main.

TLS implicite contre STARTTLS : la position à tenir

Section intitulée « TLS implicite contre STARTTLS : la position à tenir »

Le compromis central se formule ainsi : STARTTLS économise un port et garde la compatibilité avec des clients anciens ; il paie cette économie par une phase en clair qui reste attaquable tant que chaque client n’exige pas TLS et que chaque implémentation ne gère pas parfaitement son tampon. Ce prix n’a plus de justification pour les flux client vers serveur. La logique est celle de toute rétrogradation de protocole, traitée pour les versions de TLS dans la migration de TLS legacy : ce qui se négocie en clair se négocie aussi avec l’attaquant.

La recommandation, par flux :

FluxChoixCondition de validité
Soumission de courrier (MUA, Mail User Agent, vers MSA, Mail Submission Agent)TLS implicite, port 465Fermer 587 ou y exiger STARTTLS avant toute authentification
Relève de courrierIMAPS 993, POP3S 995Fermer 143 et 110 côté Internet
Annuaire LDAPLDAPS 636, ou StartTLS rendu obligatoire par le serveurLe serveur doit refuser tout bind avant la bascule
Relais entre MTA, port 25STARTTLS, faute d’alternativeDurcir par MTA-STS ou DANE, sinon il ne protège que de l’écoute passive

Pour LDAP, StartTLS sur 389 reste défendable si et seulement si le serveur impose un niveau de sécurité minimal avant toute opération sensible (olcSecurity: tls=128 sur OpenLDAP, signature et liaison de canal exigées sur Active Directory). Sinon, un client mal configuré envoie un bind simple, donc le mot de passe, en clair : le sujet est détaillé dans la désactivation du bind simple en clair et du bind anonyme. LDAPS sur 636 a l’avantage de se filtrer au pare-feu : un port, un comportement.

Le port 25 est le seul où STARTTLS ne se remplace pas : la RFC 5321 ne prévoit aucun port implicite entre serveurs, et aucun écosystème ne bascule d’un bloc. Le choix ne porte donc pas sur STARTTLS mais sur le mécanisme qui le rend obligatoire.

MTA-STS et DANE : rendre STARTTLS obligatoire entre MTA

Section intitulée « MTA-STS et DANE : rendre STARTTLS obligatoire entre MTA »

Les deux mécanismes publient la même information (« ce domaine exige TLS avec un certificat valide sur ses MX ») par deux canaux de confiance différents.

MTA-STS (Mail Transfer Agent Strict Transport Security), RFC 8461, repose sur le DNS (Domain Name System) non signé et sur HTTPS :

  • un enregistrement TXT _mta-sts.example.com contenant v=STSv1; id=... signale l’existence d’une politique et sa version ;
  • la politique est servie en HTTPS sur https://mta-sts.example.com/.well-known/mta-sts.txt, avec un certificat validé par les autorités publiques ;
  • elle liste les MX autorisés, un mode (enforce, testing, none) et une durée de mise en cache max_age (au plus 31 557 600 secondes, soit un an).

Séquence entre cinq acteurs : MTA émetteur, DNS, mta-sts.example.com, MX et file d'attente. Le MTA émetteur demande au DNS le TXT _mta-sts.example.com et reçoit v=STSv1; id=2026100801. Si la politique est absente du cache ou si l'id a changé, il envoie GET /.well-known/mta-sts.txt à mta-sts.example.com, qui répond mode enforce, mx autorisés et max_age. Il envoie ensuite EHLO puis STARTTLS au MX. Si le MX est listé, STARTTLS présent et le certificat valide pour le nom du MX, il livre ; si une condition échoue en mode enforce, le message est reporté en file d'attente, sans livraison en clair.

Le point à retenir du schéma est la dernière ligne : en mode enforce, un échec ne dégrade pas en clair, il diffère la livraison. Le retrait de STARTTLS devient une attaque par déni de service, plus une attaque de confidentialité.

MTA-STS a une limite structurelle : il fonctionne en confiance au premier usage, TOFU (Trust On First Use). Un émetteur qui n’a jamais vu la politique et dont la requête DNS ou HTTPS est bloquée par l’attaquant n’en saura rien. Le cache long réduit cette fenêtre au tout premier contact et aux expirations.

DANE (DNS-based Authentication of Named Entities) pour SMTP, RFC 7672, publie des enregistrements TLSA (_25._tcp.mx1.example.com) qui épinglent la clé ou le certificat du MX. Il exige DNSSEC (DNS Security Extensions) sur toute la chaîne. Pas de TOFU, pas de dépendance aux autorités publiques, et un certificat auto-signé devient légitime s’il est épinglé (usage TLSA 3 1 1). Les liens entre DNS et TLS sont développés dans DNS et TLS.

Le choix dépend d’une seule question : la zone DNS est-elle signée et opérée par une équipe capable de faire un roulement de clés DNSSEC sans casser la résolution ? Si oui, DANE est techniquement supérieur, et la RFC 8461 interdit qu’une politique MTA-STS valide l’emporte sur un échec de validation DANE. Sinon, MTA-STS. Publier les deux est cohérent : les grands fournisseurs de messagerie ne valident pas tous DANE, et MTA-STS couvre ceux-là.

TLS-RPT (SMTP TLS Reporting), RFC 8460, complète les deux : un TXT _smtp._tls.example.com contenant v=TLSRPTv1; rua=mailto:... demande aux émetteurs d’envoyer un rapport quotidien des échecs TLS. Sans lui, un passage en enforce est une opération à l’aveugle.

Prérequis et conditions d’exploitation de MTA-STS

Section intitulée « Prérequis et conditions d’exploitation de MTA-STS »

Avant de publier une politique :

  • Chaque MX (y compris le MX secondaire, toujours oublié et toujours celui dont le certificat a expiré) présente un certificat valide pour son nom MX, signé par une autorité publique, chaîne complète. Un certificat issu d’une autorité de certification privée interne est valide pour DANE, pas pour MTA-STS.
  • Un serveur web joignable sur mta-sts.<domaine> avec son propre certificat public. C’est un nouveau service exposé, à superviser comme tel.
  • Côté émission, un MTA qui sait appliquer les politiques des autres : Postfix ne le fait pas nativement et s’appuie sur un résolveur externe (postfix-mta-sts-resolver) ; DANE y est natif depuis la version 2.11 (smtp_tls_security_level = dane).

En exploitation, la règle d’or : le certificat d’un MX en mode enforce est un composant de disponibilité. Une expiration ne déclenche plus de livraison en clair mais une file d’attente qui grossit, puis des rejets après le délai de réessai de l’émetteur (souvent cinq jours). Le renouvellement doit être automatisé (ACME, Automatic Certificate Management Environment) et supervisé ; voir la gestion du cycle de vie des certificats à l’échelle.

Autres pièges opérationnels, tous vérifiables :

  • L’id doit changer à chaque modification de la politique. Les émetteurs ne relisent la politique que si l’id du TXT diffère de celui en cache. Modifier le fichier sans toucher l’id revient à ne rien modifier avant l’expiration de max_age.
  • Ajouter un MX exige de l’ajouter à la politique avant de le publier dans le DNS. Dans l’ordre inverse, les émetteurs en enforce refusent de livrer au nouveau MX.
  • Le retour arrière n’est pas instantané. Passer en mode: none suppose de publier la nouvelle politique et un nouvel id ; un émetteur qui ne refait pas de livraison garde l’ancienne jusqu’à max_age. Commencer en testing avec un max_age d’un jour, lire les rapports TLS-RPT pendant plusieurs semaines, puis monter à enforce et une semaine ou plus.
  • Avec DANE, la rotation de clé du MX se prépare : publier le TLSA de la nouvelle clé, attendre au moins deux TTL (Time To Live), changer la clé, retirer l’ancien TLSA. Changer la clé d’abord rend le domaine injoignable pour tous les émetteurs DANE.

Ce que STARTTLS, MTA-STS et DANE ne garantissent pas

Section intitulée « Ce que STARTTLS, MTA-STS et DANE ne garantissent pas »
  • Pas de chiffrement de bout en bout. Chaque saut est protégé séparément ; chaque MTA intermédiaire lit le message en clair et le stocke en clair dans sa file. La confidentialité du contenu relève de S/MIME (Secure/Multipurpose Internet Mail Extensions) ou d’OpenPGP, traités dans messageries, courrier sécurisé et groupes chiffrés.
  • Pas d’authentification de l’expéditeur. MTA-STS authentifie le serveur destinataire, rien d’autre. L’usurpation se traite par SPF (Sender Policy Framework), DKIM (DomainKeys Identified Mail) et DMARC (Domain-based Message Authentication, Reporting and Conformance).
  • Pas de protection du premier saut. MTA-STS ne concerne que le port 25 entre serveurs. La soumission client vers serveur repose sur la configuration du client, d’où le TLS implicite.
  • Pas de protection contre l’injection de commandes. Une politique enforce garantit que la bascule a lieu, pas que l’implémentation gère son tampon correctement.
  • Pas de masquage des métadonnées. L’adresse IP, le nom du MX et le nom de domaine indiqué dans le SNI (Server Name Indication) restent visibles.

Pour les erreurs de chaîne et de nom rencontrées lors de la mise en place, le diagnostic des erreurs de validation TLS s’applique tel quel aux MX.

Exemple : vérifier STARTTLS et publier une politique MTA-STS

Section intitulée « Exemple : vérifier STARTTLS et publier une politique MTA-STS »

Tester la bascule et la validité du certificat d’un MX, en échouant si la chaîne ne valide pas :

Fenêtre de terminal
# Bascule STARTTLS sur le port 25, SNI = nom du MX, échec si le certificat ne valide pas
openssl s_client -connect mx1.example.com:25 -starttls smtp \
-servername mx1.example.com -verify_return_error -brief </dev/null
# Même test pour IMAP (143) et LDAP (389) ; OpenSSL 1.1.1 ou plus pour "ldap"
openssl s_client -connect imap.example.com:143 -starttls imap -verify_return_error -brief </dev/null
openssl s_client -connect ldap.example.com:389 -starttls ldap -verify_return_error -brief </dev/null
# Client LDAP : -ZZ exige StartTLS et échoue sinon ; -Z seul continue en clair en cas d'échec
ldapsearch -ZZ -H ldap://ldap.example.com -x -b "dc=example,dc=com" -s base

L’option -Z d’ldapsearch illustre à elle seule l’attaque par retrait : une lettre de moins et l’échec de la bascule devient silencieux.

Publier MTA-STS et TLS-RPT pour example.com :

; Zone DNS : signal de politique et adresse des rapports
_mta-sts.example.com. IN TXT "v=STSv1; id=2026100801"
_smtp._tls.example.com. IN TXT "v=TLSRPTv1; rua=mailto:[email protected]"
# Contenu servi sur https://mta-sts.example.com/.well-known/mta-sts.txt
# Démarrer en testing avec max_age court ; passer en enforce après lecture des rapports
version: STSv1
mode: testing
mx: mx1.example.com
mx: mx2.example.com
max_age: 86400
Fenêtre de terminal
# Vérifier ce que verra un émetteur
dig +short TXT _mta-sts.example.com
curl -sS https://mta-sts.example.com/.well-known/mta-sts.txt

Côté Postfix, imposer le TLS implicite sur la soumission dans master.cf (smtpd_tls_wrappermode=yes sur le service submissions port 465) et, côté réception, laisser smtpd_tls_security_level = may sur le port 25 : exiger TLS en réception publique rejetterait les émetteurs qui ne savent pas chiffrer, ce qui est une décision de politique, pas un réglage de sécurité.

Sans TLS obligatoire ni politique publiée, chaque relais de courrier vers le domaine se décide sur une réponse en clair qu’un intermédiaire réseau peut réécrire. Retirer une ligne suffit pour récupérer le contenu des messages entrants, pièces jointes et liens de réinitialisation de mot de passe compris, sans qu’aucun journal côté émetteur ne signale autre chose qu’une livraison réussie. Côté annuaire, un client LDAP resté en mode opportuniste transmet ses identifiants de bind en clair dès que la bascule échoue, et ces comptes de service ouvrent ensuite l’annuaire entier. Sans TLS-RPT, ces dégradations ne laissent aucune trace exploitable : impossible de dater le début d’une interception ni de délimiter les messages exposés.

Quand un serveur de courrier envoie un message à un autre, ou quand un logiciel interroge un annuaire d’entreprise, la connexion commence sans protection. Le serveur qui reçoit annonce ce qu’il sait faire, dont la possibilité de passer en mode chiffré. L’envoyeur demande alors ce passage, les deux machines échangent leurs certificats, et la suite devient illisible pour les curieux. Le défaut tient au début : cette annonce circule en lisible. Une personne placée sur le trajet peut effacer la ligne qui propose le chiffrement. L’envoyeur croit que l’autre ne sait pas chiffrer et envoie tout en lisible. Elle peut aussi glisser ses propres ordres juste avant le passage au chiffré ; certains logiciels mal écrits les exécutent ensuite comme s’ils étaient protégés. Pour les ordinateurs des utilisateurs, la parade consiste à chiffrer dès la première seconde, sur un numéro de porte réservé à cela, sans phase lisible. Entre serveurs de courrier, ce n’est pas possible, alors le destinataire publie une règle sur un site web lui-même protégé par un certificat ; elle dit : chez moi, chiffrement obligatoire avec un certificat valide. Un envoyeur qui connaît cette règle refuse de livrer en lisible et met le message en attente. Contrepartie : si le certificat du serveur expire, le courrier n’arrive plus du tout, donc son renouvellement doit être automatique et surveillé.

À lire aussi

Pages voisines

: les deux pages se citent l’une l’autre.