Wikipedia · einfach zusammengefasst · Stand
Time-of-Check-to-Time-of-Use-Problem
Allgemein wird damit eine Form der Wettlaufsituation (Race Condition) bezeichnet, bei der der Zeitraum zwischen der Überprüfung eines Systemzustandes (Time …
Inhalt5 Abschnitte
Grundidee
Das Time-of-Check-to-Time-of-Use-Problem, abgekürzt TOCTOU, TOCTTOU oder TOC/TOU, bezeichnet einen Programmfehler, der bei der Ausführung von Computerprogrammen auftreten kann. Es ist eine Form der Wettlaufsituation, also einer Race Condition: Zwischen der Überprüfung eines Systemzustands und der späteren Verwendung des Prüfergebnisses kann sich genau dieser Zustand ändern.
Der Name beschreibt die beiden entscheidenden Zeitpunkte: Time-of-check ist der Zeitpunkt der Prüfung, zum Beispiel ob Schreibzugriff auf eine Datei besteht. Time-of-use ist der Zeitpunkt, an dem das Programm das Ergebnis dieser Prüfung verwendet, zum Beispiel um die Datei tatsächlich zu ändern. Wenn ein Angreifer oder ein anderer Vorgang den geprüften Zustand in der Zwischenzeit verändert, ist das frühere Prüfergebnis für den weiteren Programmlauf möglicherweise nicht mehr gültig.
Bedeutung für Sicherheit
Das Problem ist sicherheitsrelevant, weil ein Programm eine Entscheidung auf Grundlage eines alten Zustands treffen kann. Dadurch können Berechtigungen oder Sicherheitsprüfungen umgangen werden.
Ein einfaches Beispiel ist ein Virencheck: Eine Datei kann zunächst als virenfrei geprüft werden. Wenn sie aber zwischen dieser Prüfung und ihrer späteren Verwendung so verändert wird, dass sie einen Virus enthält oder dessen Aktivierung beziehungsweise Ausführung ermöglicht, ist der ursprüngliche Virencheck unter Umständen hinfällig.
Der Begriff wurde 1996 von Matt Bishop und Michael Dilger in diesem Zusammenhang eingeführt. Andrey Kolishak beschrieb 2003 dasselbe Problem für die Verwendung von Windows Hooks.
Webanwendung als Beispiel
Eine Webanwendung kann Benutzern erlauben, bestimmte Seiten zu verändern. Gleichzeitig kann sie dem Administrator die Möglichkeit geben, Seiten gegen Änderungen zu sperren.
Ein TOCTTOU-Problem entsteht, wenn die Anwendung nur beim Öffnen der Eingabemaske prüft, ob ein Benutzer die Seite ändern darf. Zu diesem Zeitpunkt wird die Änderung erlaubt, also beim Time-of-check. Wenn der Administrator danach die Seite sperrt, aber bevor der Benutzer seine Änderungen speichert, müsste diese neue Sperre beim Speichern berücksichtigt werden.
Ein fehlerhaftes System ignoriert die Administratoraktion beim späteren Abspeichern der Benutzerdaten. Es verwendet also beim Time-of-use weiterhin das alte Prüfergebnis, obwohl sich die Berechtigungslage inzwischen geändert hat.
Unix-Beispiel
In Unix kann das Problem bei einem in C geschriebenen Programm auftreten, besonders wenn es mit setuid-Rechten läuft. Das Beispiel prüft zuerst mit access(file, R_OK), ob der angemeldete Benutzer mit den Rechten des eigenen Benutzerkontos, der Real Userid, eine Datei lesen darf. Danach wird dieselbe Datei mit open(file, O_RDONLY) geöffnet.
Die Effective Userid kann andere Rechte enthalten als die Real Userid. Deshalb ist die getrennte Prüfung mit access und die spätere Nutzung mit open riskant: Zwischen Prüfung und Öffnen kann sich die Datei ändern.
Eine mögliche Angriffsmethode besteht darin, zuerst eine für den Benutzer lesbare Datei anzulegen, dann das Programm zu starten und anschließend die Datei in eine symbolische Verknüpfung, also einen symlink, zu verwandeln, die auf eine für den Benutzer nicht lesbare Datei zeigt. Für einen Angreifer kann es möglich sein, diese Bedingungen herzustellen, allerdings erfordert der Angriff eine genaue zeitliche Abstimmung.
Folgerung
Aus dem Unix-Beispiel folgt, dass der Systemaufruf access in dieser Form nur in speziellen Fällen eingesetzt werden sollte. Genannt wird etwa der Einsatz als erster Schritt zur Erlangung exklusiver Zugriffsrechte.
Exklusive Zugriffsrechte verhindern, dass mehrere Abläufe gleichzeitig denselben kritischen Zustand verändern. Im Artikel werden dafür Mutex sowie Test and Test-and-set genannt. Ein Mutex ist ein Mechanismus, mit dem ein Programmteil einen gemeinsamen Zugriff sperren kann, damit nicht gleichzeitig ein anderer Programmteil denselben kritischen Bereich verändert.