FlawOpen

flawopen.com/Teardowns/cve-2026-102422-shell-quote-comment-line-terminator-injection

● CVE-2026-102422 · CVSS 8.1 · Hoch
Sicherheitsforschung · FlawOpen

CVE-2026-102422: Injection über Kommentar-Token in shell-quote

Vor shell-quote 1.11.0 konnte ein Kommentar-Token gefolgt von einer Zeichenfolge mit Zeilenabschluss die Bedeutung der zitierten Ausgabe ändern, wenn sie an eine POSIX-Shell übergeben wurde. Voraussetzung sind angreiferkontrollierte Tokens, ein Aufruf von quote() und die Ausführung der Ausgabe durch eine Shell; aktualisieren Sie auf 1.11.0 oder neuer.

💡 Einfache Erklärung (ELI5)

Ein Kommentar auf einem Etikett kann alles bis zum Zeilenende verbergen. Enthält der nächste Teil einen Zeilenumbruch, endet der Kommentar früher und der Rest wird wieder sichtbar. Dieser Fehler ließ ein späteres Token das in für die Shell zitierter Ausgabe bewirken.

Kernkonzepte & Begriffe

shell-quote
JavaScript-Paket zum Parsen und Zitieren von Shell-Tokens; die Ausgabe ist weiterhin Shell-Syntax und kein universelles Format für sichere Zeichenketten.
Kommentar-Token
Token für Shell-Kommentarsyntax, deren Wirkung bis zu einem Zeilenabschluss auf folgenden Text reichen kann.
Zeilenabschluss
Zeilengrenze wie CR, LF, U+2028 oder U+2029, die eine Shell als Ende eines Kommentars behandeln kann.
CWE-78
Unzureichende Neutralisierung spezieller Elemente in einem Betriebssystembefehl.

Framework-Zuordnungen

  • CWE-Referenz für die in diesem Leitfaden beschriebene Schwachstelle: CWE-78

Ursachenanalyse

Der betroffene quote()-Pfad wies Zeilenabschlüsse im Kommentar-Token selbst zurück, speicherte aber nicht, dass bereits ein Kommentar ausgegeben worden war. Ein späteres String-Token konnte daher einen Zeilenabschluss enthalten. Gelangen angreiferkontrollierte Tokens zu quote() und wird die Ausgabe von einer POSIX-Shell ausgeführt, beendet die Zeilengrenze den Kommentar und die Shell interpretiert den folgenden Text als Syntax. Der Fix merkt sich den Kommentarzustand und weist Zeilenabschlüsse in allen nachfolgenden Strings zurück. Das unterscheidet sich von CVE-2026-9277, dessen Fix Zeilenabschlüsse im Kommentar-Token selbst zurückwies. Die Maintainer bewerten den Fehler mit Hoch und CVSS 3.1 8,1; Ubuntu veröffentlicht eine separate Bewertung CVSS 4.0 9,2 Kritisch. Die Werte stammen aus verschiedenen CVSS-Versionen und sind nicht gleichzusetzen.

Schritt-für-Schritt Angriffsablauf

Schritt 1

Tokens erreichen die Zitierfunktion

Die Anwendung erstellt Tokens mit einem Kommentar und einem späteren String; der Angreifer muss diese Folge beeinflussen können.

Schritt 2

Die Funktion gibt Kommentarsyntax aus

Vor 1.11.0 prüfte quote() den Kommentartext, merkte sich aber nicht, dass danach Strings folgen.

Schritt 3

Ein späteres Token enthält eine Zeilengrenze

CR, LF, U+2028 oder U+2029 kann den Shell-Kommentar beenden.

Schritt 4

Die Anwendung führt die Ausgabe in einer Shell aus

Die dokumentierte Interpretation betrifft Aufrufer, die die Ausgabe an eine POSIX-Shell übergeben.

Schritt 5

Das Upgrade weist die Folge zurück

Version 1.11.0 speichert den Kommentarzustand und wirft einen Fehler, wenn ein späterer String einen Zeilenabschluss enthält.

Quellcode: Verwundbar vs. Sicher

Der verwundbare Ausschnitt prüft Zeilenabschlüsse im Kommentar-Token, speichert aber keinen Zustand für nachfolgende Strings. Die Änderung im Upstream merkt sich die Ausgabe eines Kommentars und weist einen späteren String mit Zeilenabschluss zurück. Der Ausschnitt zeigt die Parser- und Zitiergrenze; er ist weder ein Exploit noch ein Shell-Befehl.

Quelltextauszug: quote.js — focused upstream diff hunks

VERWUNDBARE IMPLEMENTIERUNG
// quote.js vor Commit 6002b2e — gezielter Ausschnitt zum Kommentar-Token
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;
}
GEHÄRTETER SICHERHEITS-PATCH
// quote.js nach Commit 6002b2e — exakter Ausschnitt der neuen Prüfung und des Kommentarstatus
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;
  }
});

Checkliste für Engineering & Systemsicherheit

Quellen