Contexte et portée

GoAhead est un serveur web embarqué utilisé dans des centaines de millions d’appareils IoT, de firewalls, de systèmes OT et de matériels militaires. Il supporte deux implémentations TLS : un backend compatible OpenSSL (et donc LibreSSL) et un backend Mbed TLS. Les trois vulnérabilités décrites affectent des versions allant de 3.4.5 à 6.1.0 et sont classées CVSS 9.1, 7.4 et 5.9 respectivement, avec les identifiants GOAHEAD‑SA‑2026‑0006, ‑0004 et ‑0005.

Bug de révocation dans le backend OpenSSL

Le code

sslOpen() { X509_STORE_load_locations(...); /* CRL loaded */ }
charge le fichier CRL dans le magasin de certificats, mais n’active jamais le drapeau X509_V_FLAG_CRL_CHECK requis par OpenSSL. En l’absence de ce drapeau, la fonction check_revocation() renvoie immédiatement success, même si le certificat figure dans la liste de révocation. Ainsi, sur GoAhead 6.1.0 avec OpenSSL 3.6.2, un certificat client révoqué passe le handshake mTLS alors que VERIFY_PEER=1, VERIFY_ISSUER=1 et un bundle CA de confiance sont configurés. La faille persiste tant que le CRL est présent, même si la vérification d’émetteur est désactivée. La correction, introduite dans la version 6.1.1, active explicitement le drapeau de vérification après le chargement du CRL.

Vulnérabilité de profondeur de chaîne sous LibreSSL

Lorsque le backend OpenSSL est lié à LibreSSL, le vérificateur hérité accepte des chaînes de certificats dépassant la limite de profondeur définie (10 par défaut via VERIFY_DEPTH) si la vérification d’émetteur est désactivée (ME_GOAHEAD_SSL_VERIFY_ISSUER=0). Le code ne rejette pas les chaînes trop longues, contournant ainsi la restriction de profondeur et permettant à un attaquant de présenter un certificat client valide mais issu d’une chaîne artificiellement allongée. Le score CVSS 7.4 reflète le risque d’escalade d’accès dans les déploiements où les certificats clients sont obligatoires.

Erreur de paramètre DH dans le backend Mbed TLS

Le backend Mbed TLS configure le groupe DH de 2048 bits (RFC 3526) via

mbedtls_ssl_conf_dh_param_bin(..., dhm_g, sizeof(dhm_g), dhm_p, sizeof(dhm_g));
. La seconde taille utilise sizeof(dhm_g) alors que dhm_g ne fait qu’un octet. En conséquence, mbedtls_ssl_conf_dh_param_bin ne lit que le premier octet de dhm_p (0xFF) au lieu des 256 octets attendus. Le serveur envoie alors un paramètre DH de un octet (00 01 ff) dans le ServerKeyExchange. Cette réduction limite l’espace de secret partagé à huit valeurs possibles (01, 02, 04, 08, 10, 20, 40, 80), rendant les sessions TLS 1.2 DHE_RSA triviales à décrypter pour un observateur. Le score CVSS 5.9 indique un impact modéré, mais la facilité d’exploitation (simple interception) augmente la menace pour les appareils utilisant ce backend.