flawopen.com/Teardowns/cve-2026-102422-shell-quote-comment-line-terminator-injection
CVE-2026-102422 : injection par jeton de commentaire dans shell-quote
Avant shell-quote 1.11.0, un jeton de commentaire suivi d’une chaîne contenant un terminateur de ligne pouvait modifier le sens de la sortie citée lorsqu’elle était transmise à un shell POSIX. Il faut des jetons influencés par un attaquant, un appel à quote() et l’exécution de sa sortie par un shell ; mettez à jour vers 1.11.0 ou une version ultérieure.
Un commentaire sur une étiquette peut masquer tout ce qui suit jusqu’à la fin de la ligne. Si la partie suivante contient un saut de ligne, le commentaire s’arrête et le reste redevient visible. Cette faille permettait à un jeton ultérieur de produire cet effet dans la sortie citée pour le shell.
Concepts Clés et Termes
shell-quote- Paquet JavaScript qui analyse et cite des jetons de style shell ; sa sortie reste destinée à la syntaxe shell, pas à un format universel de texte sûr.
Jeton de commentaire- Jeton représentant la syntaxe de commentaire du shell, qui peut s’étendre au texte suivant jusqu’à un terminateur de ligne.
Terminateur de ligne- Limite de ligne telle que CR, LF, U+2028 ou U+2029, que le shell peut traiter comme la fin du commentaire.
CWE-78- Neutralisation inadéquate d’éléments spéciaux utilisés dans une commande du système d’exploitation.
Correspondances de référentiels
- Référence CWE pour la faiblesse décrite dans ce guide : CWE-78
Analyse de Cause Racine
Le chemin vulnérable de quote() refusait les terminateurs dans le jeton de commentaire lui-même, mais ne mémorisait pas qu’un commentaire avait été émis. Un jeton chaîne ultérieur pouvait donc contenir un terminateur. Lorsque des jetons influencés par un attaquant traversent quote() et que le résultat est exécuté par un shell POSIX, la limite de ligne termine le commentaire et le shell interprète la suite comme une syntaxe. Le correctif mémorise l’état de commentaire et refuse les terminateurs dans toutes les chaînes suivantes. Ce cas diffère de CVE-2026-9277, dont le correctif refusait les terminateurs dans le jeton de commentaire. Les mainteneurs attribuent une gravité Élevée et CVSS 3.1 8,1 ; Ubuntu publie une évaluation distincte CVSS 4.0 9,2 Critique. Ces scores proviennent de versions différentes et ne sont pas interchangeables.
Déroulement de l'Attaque Étape par Étape
Les jetons atteignent la fonction de citation
L’application construit des jetons comprenant un commentaire et une chaîne ultérieure ; l’attaquant doit pouvoir influencer cette séquence.
La fonction émet la syntaxe de commentaire
Avant 1.11.0, quote() vérifiait le texte du commentaire, mais ne mémorisait pas les chaînes qui le suivent.
Un jeton ultérieur contient une limite de ligne
CR, LF, U+2028 ou U+2029 peut terminer le commentaire du shell.
L’application exécute le résultat dans un shell
L’interprétation documentée concerne les appelants qui transmettent le résultat à un shell POSIX.
La mise à jour refuse la séquence
La version 1.11.0 mémorise l’émission d’un commentaire et lève une erreur si une chaîne ultérieure contient un terminateur.
Code Source : Vulnérable vs Sécurisé
L’extrait vulnérable vérifie les terminateurs dans le jeton de commentaire, mais ne mémorise pas l’état pour les chaînes suivantes. La modification amont mémorise l’émission du commentaire et refuse toute chaîne ultérieure contenant un terminateur. Cet extrait illustre la frontière entre analyse et citation ; ce n’est ni un exploit ni une commande shell.
Extrait source: quote.js — focused upstream diff hunks
// quote.js avant le commit 6002b2e — extrait ciblé sur le jeton de commentaire
if ('comment' in s && typeof s.comment === 'string') {
if (LINE_TERMINATORS.test(s.comment)) {
throw new TypeError('`comment` must not contain line terminators');
}
return '#' + s.comment;
}
// quote.js après le commit 6002b2e — extrait exact de la nouvelle protection et de l’état du commentaire
var sawComment = false;
return xs.map(function (s) {
if (sawComment && typeof s === 'string' && LINE_TERMINATORS.test(s)) {
throw new TypeError('a token after a `comment` must not contain line terminators');
}
if ('comment' in s && typeof s.comment === 'string') {
if (LINE_TERMINATORS.test(s.comment)) {
throw new TypeError('`comment` must not contain line terminators');
}
sawComment = true;
return '#' + s.comment;
}
});
Liste de Contrôle de Sécurité pour l'Ingénierie
- ✓Mettez à jour les dépendances directes et transitives de
shell-quotevers 1.11.0 ou une version ultérieure ; vérifiez le lockfile et l’artefact déployé. - ✓Ne considérez pas
quote()comme sûr dans tout contexte ni comme un substitut à l’absence de shell. - ✓Si possible, lancez un exécutable fixe avec un tableau d’arguments et
shell: false, en validant chaque argument pour le programme cible. - ✓Si le shell est inévitable, gardez la structure de commande fixe et refusez avant exécution les séquences commentaire suivies de terminateurs.
- ✓Ajoutez des tests pour CR, LF, U+2028 et U+2029 dans les chaînes ultérieures, y compris les jetons issus de
parse(). - ✓Examinez les appels qui transmettent à
quote()des jetons influencés par un attaquant puis exécutent le résultat ; la seule présence du paquet ne prouve pas l’exploitabilité. - ✓Ne déduisez pas l’état des paquets Ubuntu de la version npm ; consultez l’avis de distribution correspondant.