FlawOpen

flawopen.com/Teardowns/cve-2026-84973-jupyterlab-snapshot-checkout-toctou

● CVE-2026-84973 · Hoch
Sicherheitsforschung · FlawOpen

CVE-2026-84973: TOCTOU-Fehler im JupyterLab-Snapshot-Workflow

Eine Zeitprüfung mit einer Sekunde Auflösung konnte dazu führen, dass der Snapshot-Workflow einen nicht genehmigten Pull-Request-Commit mit den Rechten des Jobs auscheckt und ausführt. Aktualisieren Sie update-snapshots-checkout auf Version 1.0.0 oder höher.

💡 Einfache Erklärung (ELI5)

Eine Prüferin genehmigt ein bestimmtes Paket, doch die Ausgabestelle prüft nur die Sekunde auf der Uhr. Tauscht jemand das Paket in derselben Sekunde aus, wirkt der Ersatz ebenfalls genehmigt. Die Action verglich Zeitstempel mit einer Sekunde Genauigkeit und ließ gleiche Werte zu; so konnte eine Pull-Request-Änderung gleichzeitig mit dem Kommentar des Maintainers durchrutschen.

Kernkonzepte & Begriffe

TOCTOU
Time-of-check to time-of-use: Eine Sicherheitsentscheidung betrifft eine Ressource, die sich vor ihrer Verwendung ändert.
Pull-Request-Head-SHA
Unveränderliche Kennung des Commits an der Spitze eines Pull-Request-Branches. Ein Workflow sollte nur den exakt freigegebenen Commit ausführen.
GitHub-Actions-Tokenrechte
Erlaubte Repository-Aktionen des GITHUB_TOKEN eines Jobs, etwa Inhalte oder Pull Requests zu lesen und zu ändern.
CWE-367 / CWE-829
Der Bericht ordnet das Zeitrennen CWE-367 und die Ausführung Pull-Request-kontrollierter Funktionalität CWE-829 zu.

Framework-Zuordnungen

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

Ursachenanalyse

Vor Version 1.0.0 rief update-snapshots-checkout pushed_at des Pull Requests und created_at des auslösenden Kommentars ab, wandelte beide Werte in Unix-Sekunden um und lehnte den Lauf nur ab, wenn pushed_at strikt größer war. Beide API-Zeitstempel haben eine Genauigkeit von einer Sekunde. Ein Push und ein autorisierter Kommentar in derselben Sekunde konnten daher gleiche Werte ergeben und die Prüfung bestehen. Anschließend speicherte die Action die aktuelle Head-SHA und prüfte sie nach dem Checkout; das bewies nur, dass der Checkout der gerade abgerufenen SHA entsprach, nicht dass der Maintainer diesen Commit freigegeben hatte. Die Upstream-Korrektur ersetzt -gt durch -ge und lehnt gleiche sowie spätere Zeitstempel ab. Betroffen sind nur Workflows mit einer verwundbaren Action-Version, die danach Inhalte des Pull Requests ausführen; die Auswirkungen richten sich nach Berechtigungen und Zugangsdaten des Workflows.

Schritt-für-Schritt Angriffsablauf

Schritt 1

Ein vertrauenswürdiger Maintainer löst den Workflow aus

Ein Pull Request wird geöffnet und ein OWNER, COLLABORATOR oder MEMBER veröffentlicht den Kommentar, der den Snapshot-Update-Workflow startet.

Schritt 2

Eine Angreiferänderung fällt mit dem Kommentar zusammen

Ein Beitragender aktualisiert den Branch in derselben Sekunde. Wegen der einsekündigen API-Auflösung können die Unix-Werte identisch sein.

Schritt 3

Der strikte Größer-als-Vergleich akzeptiert Gleichheit

Die verwundbare Action lehnt nur ab, wenn pushed_at größer als created_at ist. Gleiche Werte erfüllen die Bedingung nicht, daher wird die neue Head-SHA gespeichert.

Schritt 4

Der Workflow checkt diesen Commit aus und kann ihn ausführen

Der Checkout stimmt mit der gespeicherten SHA überein und besteht die spätere Prüfung. Führen weitere Schritte Actions oder Skripte aus dem Pull Request aus, gelten die Rechte und Zugangsdaten des Jobs.

Schritt 5

Aktualisieren und Workflow-Rechte reduzieren

Aktualisieren Sie auf 1.0.0 oder höher. Fixieren Sie Actions auf unveränderliche SHAs, vergeben Sie dem GITHUB_TOKEN nur nötige Rechte und halten Sie nicht vertrauenswürdigen Pull-Request-Code von Geheimnissen und privilegierten Jobs fern.

Quellcode: Verwundbar vs. Sicher

Dieser Ausschnitt entspricht der einzeiligen Upstream-Änderung: -ge lehnt bei der API-Zeitauflösung gleiche Werte ab. Damit wird der dokumentierte Angriff in derselben Sekunde geschlossen. Die Freigabe sollte trotzdem an eine unveränderliche SHA gebunden und Berechtigungen sollten minimiert werden; zeitliche Reihenfolge ersetzt keine unveränderliche Autorisierungsentscheidung. Der Upstream-Diff lässt die vorhandene Meldung unverändert; sie sagt „danach“, obwohl Gleichheit nun ebenfalls abgelehnt wird.

VERWUNDBARE IMPLEMENTIERUNG
if [[ $(date -d "$pushed_at" +%s) -gt $(date -d "$COMMENT_AT" +%s) ]]; then
    echo "Updating is not allowed because the PR was pushed to (at $pushed_at) after the triggering comment was issued (at $COMMENT_AT)"
    exit 1
fi
GEHÄRTETER SICHERHEITS-PATCH
if [[ $(date -d "$pushed_at" +%s) -ge $(date -d "$COMMENT_AT" +%s) ]]; then
    echo "Updating is not allowed because the PR was pushed to (at $pushed_at) after the triggering comment was issued (at $COMMENT_AT)"
    exit 1
fi

Checkliste für Engineering & Systemsicherheit

Quellen