
Régression hors ligne indépendante de CVE-2026-44431 sur des versions épinglées d'urllib3, avec attribution du rapporteur d'origine.
CVE-2026-44431 · urllib3 2.6.3 → 2.7.0 · reproduit le 27 septembre 2026
Une requête transporte trois en-têtes sensibles vers une origine. Une redirection change la destination. La requête suivante les transporte-t-elle encore ?
Cette régression indépendante exécute l'implémentation réelle de redirection de deux versions exactes d'urllib3. La version 2.6.3 conserve les trois en-têtes à travers l'API de bas niveau affectée. La version 2.7.0 les supprime. Un en-tête bénin survit, et les requêtes ordinaires fonctionnent toujours.
| Fixture | urllib3 2.6.3 | urllib3 2.7.0 |
|---|---|---|
| Redirection cross-origin de bas niveau | 3 en-têtes sensibles conservés | 0 conservé |
| Même cas avec des noms en minuscules | 3 conservés | 0 conservé |
| Contrôle de l'API de haut niveau | 0 conservé | 0 conservé |
| Réponse directe 200 | 3 conservés comme prévu | 3 conservés comme prévu |
| Redirection explicitement désactivée | Un appel ; 302 retourné | Un appel ; 302 retourné |
| L'ensemble de suppression personnalisé ajoute un marqueur bénin | Les 4 en-têtes conservés | Les 4 supprimés |
12/12 attentes de scénario satisfaites. Chaque scénario vérifie également le statut de la réponse, le nombre d'appels de transport, l'ensemble d'en-têtes initial, le résultat de l'en-tête bénin, et que les en-têtes de l'appelant n'ont pas été mutés. Le résultat vulnérable est un résultat de référence attendu, et non une vérification de sécurité réussie.
Les résultats lisibles par machine incluent les arguments capturés, les hachages exacts des wheels, le runtime, les hachages des sources de test, l'attribution et l'heure de reproduction.
L'avis amont, publié le 7 mai 2026, identifie un problème d'exposition d'informations dans le chemin de redirection de bas niveau via proxy d'urllib3. Il liste les versions >=1.23, <2.7.0 comme affectées. Appeler ProxyManager.connection_from_url(...).urlopen(..., assert_same_host=False) pouvait transporter des en-têtes sensibles configurés dans une requête redirigée vers une autre origine. L'API de gestion de haut niveau les supprimait déjà.
Le correctif amont applique Retry.remove_headers_on_redirect avant la requête récursive de bas niveau. Notre cas d'en-têtes en minuscules suit l'attention portée par la régression amont à la casse des noms d'en-têtes. Le cas de suppression personnalisée vérifie que la règle respecte l'ensemble configuré, au-delà des trois noms par défaut.
L'avis crédite christos-cantina-security comme rapporteur, illia-v comme coordinateur, et sethmlarson comme relecteur de la remédiation. La contribution de Sergio Rodriguez ici est le harnais hors ligne indépendant et l'analyse avant/après. Il s'agit d'une reproduction de leur CVE publiée.
Utilisez Python 3.10 ou une version ultérieure. Aucun pip install ni environnement virtuel n'est nécessaire : chaque version est importée directement depuis son wheel en pur Python dans un sous-processus isolé frais.
Depuis la racine du dépôt portfolio :
python -B ./labs/cve-replay/run_replay.py --fetch
python -B ./labs/cve-replay/run_replay.py
La première commande télécharge les deux wheels exacts dans le répertoire .cache/wheels/ ignoré du lab et vérifie leurs hachages SHA-256 par rapport au manifeste. La seconde commande utilise ce cache sans télécharger. Pour une copie source autonome, exécutez python -B run_replay.py --fetch, puis la même commande sans --fetch. --cache accepte un répertoire de cache local différent.
HTTPConnectionPool._make_request est remplacé par un transport à deux réponses : un 302 avec une location fixe, puis un 200. La fixture capture les arguments atteignant cette frontière. L'analyse syntaxique, la politique de retry, le filtrage des en-têtes et la gestion récursive des redirections d'urllib3 s'exécutent sans modification depuis le wheel sélectionné.
Toutes les destinations sont des noms .invalid réservés fixes ; toutes les valeurs d'en-têtes commencent par DUMMY. La construction de sockets et les fonctions DNS lèvent immédiatement une exception. La sonde de capacité IPv6 à l'import de la bibliothèque est refusée et enregistrée séparément ; les scénarios de replay ne tentent aucune opération réseau. Il n'y a ni serveur en écoute ni cible live.
Ceci valide la gestion des arguments de redirection. Cela ne mesure pas le trafic proxy de bout en bout. La version 2.7.0 est le premier correctif pour cette CVE particulière ; cette comparaison historique n'est pas une recommandation de la choisir plutôt que des versions supportées plus récentes.
Les scripts de fixture et l'analyse sont un travail de portfolio original. urllib3 est un projet amont distribué sous sa licence MIT ; son code et ses wheels de version ne sont pas redistribués dans l'archive source du portfolio. Ils sont téléchargés séparément depuis PyPI et importés sans modification pour l'expérience.