flawopen.com/Teardowns/cve-2026-84973-jupyterlab-snapshot-checkout-toctou
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.
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-367und die Ausführung Pull-Request-kontrollierter FunktionalitätCWE-829zu.
Framework-Zuordnungen
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
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.
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.
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.
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.
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.
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
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
- ✓Aktualisieren Sie alle Verwendungen von update-snapshots-checkout auf 1.0.0 oder höher und suchen Sie auch nach Kopien und Forks.
- ✓Fixieren Sie Actions auf geprüfte, unveränderliche SHAs und prüfen Sie Änderungen vor einer Aktualisierung der Referenzen.
- ✓Autorisieren Sie keinen beweglichen Pull-Request-Branch nur anhand von Zeitstempeln; binden Sie die Freigabe an die genaue Head-SHA.
- ✓Legen Sie minimale Rechte pro Job fest und lassen Sie contents: write sowie pull-requests: write weg, sofern nicht erforderlich.
- ✓Geben Sie Jobs, die Code externer Pull Requests ausführen, keine Geheimnisse oder privilegierten Deployment-Zugangsdaten.
- ✓Ergänzen Sie Regressionstests, die gleiche und spätere Zeitstempel ablehnen.