Secure Coding: CWE-377 – TOCTOU-Race-Conditions in den Griff bekommen
TOCTOU-Schwachstellen zählen zu den schwerwiegendsten in der Common Weakness Enumeration CWE-377 beschriebenen. Sie bedürfen besonderer Vorkehrungen.
- Sven Ruppert
Aufbauend auf der Diskussion über "CWE-377 – Unsichere temporäre Dateien und wie man sie vermeidet" ist es wichtig, sich eingehender mit einer heimtückischen Schwachstelle zu befassen, die in diesem Zusammenhang auftreten kann: die TOCTOU-Race-Condition (Time-of-Check to Time-of-Use). TOCTOU-Schwachstellen treten auf, wenn zwischen der Überprüfung einer Ressource (z. B. einer Datei) und ihrer anschließenden Verwendung eine zeitliche Lücke besteht. Böswillige Akteure können diese Lücke insbesondere in Verbindung mit temporären Dateien ausnutzen – und so schwerwiegende Sicherheitsverletzungen auslösen.
In diesem Folgeartikel wird untersucht, wie sich TOCTOU-Bedingungen in Anwendungen manifestieren, vor allem bei der Verwaltung temporärer Dateien. Der Beitrag erörtert aber auch Strategien zur Minderung dieser Risiken, um eine robuste und sichere Anwendungsentwicklung zu gewährleisten.
Verständnis von TOCTOU im Kontext von CWE-377
TOCTOU (Time-of-Check to Time-of-Use) ist eine Art Race Condition, die auftritt, wenn der Status einer Ressource (z. B. einer Datei, eines Speichers oder einer Variablen) überprüft (validiert oder verifiziert) und dann in separaten Schritten verwendet (geändert oder darauf zugegriffen) wird. Erlangt ein Angreifer zwischen diesen beiden Schritten Zugriff auf die Ressource und ändert sie, kann er diese Lücke aktiv ausnutzen, um ein schädliches Verhalten einzuleiten oder die Sicherheit einer Anwendung zu gefährden.
TOCTOU bei temporären Dateien
Im Zusammenhang mit dem Erstellen temporärer Dateien entstehen TOCTOU-Schwachstellen, wenn ein Programm auf das Vorhandensein einer Temp-Datei prüft, und diese dann öffnet oder erst erstellt. Gelingt es einem Angreifer, in der Zeit zwischen diesen Vorgängen eine Datei mit demselben Namen zu erstellen, kann er den Inhalt oder die Eigenschaften der Datei kontrollieren, von der das Programm annimmt, dass sie sicher erstellt wird oder auf die zugegriffen werden kann.
Betrachten wir beispielhaft die Abfolge der Vorgänge:
- Das Programm prüft, ob bereits eine temporäre Datei (z. B. tempfile.txt) existiert.
- Existiert die Datei nicht, wird sie vom Programm erstellt – ggf. geöffnet.
Legt ein Angreifer eine Datei mit dem Namen tempfile.txt in der Zeit zwischen der Überprüfung und dem Erstellen einer Temp-Datei durch die Anwendung an, interagiert das Programm möglicherweise versehentlich mit der Datei des Angreifers und nicht mit der legitimen, sicheren Datei. Dies kann zu Problemen wie unbefugtem Datenzugriff, Beschädigung oder Rechteausweitung führen.
Detailliertes Codebeispiel einer TOCTOU-SicherheitslĂĽcke:
import java.io.File;
import java.io.IOException;
public class TOCTOUVulnerabilityExample {
public static void main(String[] args) throws IOException {
File tempFile = new File("/tmp/tempfile.txt");
// Time-of-check: Verify whether the file exists
if (!tempFile.exists()) {
// Time-of-use: Create the file
tempFile.createNewFile();
System.out.println("Temporary file created at: " + tempFile.getAbsolutePath());
}
}
}
- Das Programm prüft zunächst mithilfe der
exists()
-Methode, obtempfile.txt
existiert. - Wenn die Datei nicht existiert, wird mit dem Befehl
createNewFile()
eine neue Datei mit demselben Namen erstellt.
Die Schwachstelle liegt hier genau zwischen den Zeitpunkten der Methodenaufrufe exists()
zum ĂśberprĂĽfen, ob die Datei existiert und dem Aufruf createNewFile()
, um die Datei dann auch tatsächlich zu erzeugen. Die zeitliche Lücke zwischen den beiden Methodenaufrufen können Angreifer ausnutzen, um eine eigene, potenziell gefährliche Datei mit dem Namen tempfile.txt einzuschleusen.
Ausnutzen von TOCTOU in temporären Dateien
Angreifer können TOCTOU-Schwachstellen auf verschiedene Arten ausnutzen:
File Pre-Creation: Der Angreifer erstellt eine Datei mit demselben Namen wie die beabsichtigte temporäre Datei in einem Verzeichnis, auf das die Anwendung zugreifen kann. Wenn die Dateiberechtigungen schwach sind, kann der Angreifer die Kontrolle über den Inhalt dieser Datei erlangen.
Symlink Attack: Der Angreifer kann einen symbolischen Link (Symlink) erstellen, der auf eine vertrauliche Datei (z. B. /etc/passwd) mit demselben Namen wie die temporäre Datei verweist. Wenn das Programm versucht, in die temporäre Datei zu schreiben oder daraus zu lesen, greift es möglicherweise stattdessen auf die vertrauliche Datei zu, was zu Datenbeschädigung oder Informationslecks führen kann.
Privilege Escalation: Wird ein Programm mit erhöhten Rechten ausgeführt (z. B. als Root), könnte ein Angreifer die TOCTOU-Race-Condition ausnutzen, um Dateien oder Daten zu ändern, auf die er sonst nicht zugreifen oder die er nicht ändern darf.
Verhindern von TOCTOU-Schwachstellen in Java
Um TOCTOU-Schwachstellen zu verhindern, insbesondere beim Umgang mit temporären Dateien, sollten Entwickler verschiedene Best Practices befolgen, die das Risiko einer Race Condition minimieren:
1. Verwenden Sie atomare Operationen
Atomare Operationen sind untrennbar miteinander verbunden. Sie werden entweder vollständig abgeschlossen oder treten überhaupt nicht auf, sodass ein Angreifer keine Möglichkeit zum Eingreifen hat. Die Methode File.createTempFile()
von Java ist beim Erstellen temporärer Dateien atomar. Das bedeutet, dass die Dateierstellung und Namensgenerierung in einem einzigen Schritt erfolgt, wodurch das typische TOCTOU-Zeitfenster entfällt.
import java.io.File;
import java.io.IOException;
public class AtomicTempFileCreation {
public static void main(String[] args) throws IOException {
// Atomic operation to create a temporary file
File tempFile = File.createTempFile("tempfile_", ".tmp");
tempFile.deleteOnExit();
System.out.println("Secure temporary file created at: " + tempFile.getAbsolutePath());
}
}
File.createTempFile()
stellt sicher, dass die Datei sowohl einen eindeutigen Namen hat als auch sicher erstellt wird, ohne dass die Anwendung Race Conditions ausgesetzt wird.
2. Verwenden von sicheren Verzeichnissen
Temporäre Dateien müssen in einem sicheren, privaten Verzeichnis, auf das andere Benutzer keinen Zugriff haben, platziert werden. Dies schränkt die Möglichkeiten von Angreifern deutlich ein, TOCTOU-Schwachstellen auszunutzen, da sie Dateien in diesen Verzeichnissen nicht einfach ablegen oder manipulieren können.
3. Nutzen von Files und Path (NIO.2-API)
Die NIO.2-API von Java (java.nio.file) bietet erweiterte Dateiverarbeitungsmechanismen, einschließlich atomarer Dateioperationen. Beispielsweise ermöglicht Files.createTempFile()
das Erstellen atomarer Dateien mit anpassbaren Dateiattributen, wie etwa sicheren Berechtigungen, wodurch sich das Risiko von TOCTOU-Schwachstellen weiter reduzieren lässt.
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.PosixFilePermissions;
import java.util.Set;
public class SecureAtomicTempFile {
public static void main(String[] args) throws IOException {
// Create a temporary file with atomic operations and secure permissions
Path tempFile = Files.createTempFile("secure_tempfile_", ".tmp",
PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rw-------")));
System.out.println("Secure temporary file created at: " + tempFile.toAbsolutePath());
}
}
Dieser Ansatz kombiniert das Erstellen atomarer Dateien mit restriktiven Dateiberechtigungen und verringert sowohl das Auftreten von TOCTOU-Schwachstellen als auch andere potenzielle Sicherheitsrisiken.
Fazit
TOCTOU-Schwachstellen stellen ein erhebliches Sicherheitsrisiko beim Umgang mit temporären Dateien dar, insbesondere wenn diese Dateien auf unsichere oder nicht-atomare Weise erstellt werden. Der Schlüssel zur Vermeidung dieser Schwachstellen liegt in der Beseitigung der Lücke zwischen dem Zeitpunkt der Überprüfung und dem Zeitpunkt der Nutzung, typischerweise durch den Einsatz atomarer Dateierstellungsmethoden – etwa die von sicheren APIs wie File.createTempFile()
oder Files.createTempFile()
.
Durch das Verständnis der mit den TOCTOU-Race-Conditions verbundenen Risiken und das Befolgen von Best Practices können Entwickler sicherstellen, dass ihre Java-Anwendungen diesen Angriffen standhalten und die Integrität und Sicherheit der Software aufrechterhalten bleibt.
Happy Coding
Sven
(map)