2 Punkte von GN⁺ 2024-09-15 | 1 Kommentare | Auf WhatsApp teilen

FlowTracker: Verfolgung von Datenflüssen in Java-Programmen

FlowTracker ist ein Java-Agent, der nachverfolgt, wie ein Programm Daten liest, verarbeitet und schreibt. Dadurch lassen sich Datei- und Netzwerk-I/O nachvollziehen, Eingaben und Ausgaben miteinander verknüpfen und zeigen, woher eine Ausgabe stammt. So kann man besser verstehen, was die Ausgabe eines Java-Programms bedeutet.

Demo

Spring PetClinic ist eine Demo-Anwendung des Spring-Frameworks. Um die Funktionen von FlowTracker zu demonstrieren, wird beobachtet, wie PetClinic HTTP-Anfragen verarbeitet und aus Templates und der Datenbank HTML-Seiten erzeugt. Die Demo kann im Browser ausgeführt oder als Video angesehen werden.

  • HTTP-Verarbeitung: FlowTracker zeigt, welcher Code welche Ausgabe erzeugt hat. Wenn man zum Beispiel auf "HTTP/1.1" oder einen HTTP-Header klickt, sieht man, dass dieser Teil von Klassen aus dem Paket org.apache.coyote erzeugt wurde.
  • Thymeleaf-Templates: Es wird gezeigt, wie die vom Programm gelesene Eingabe (HTML-Templates) mit der Ausgabe verknüpft ist. Klickt man auf den Namen eines HTML-Tags, sieht man, dass dieser Teil aus der Datei layout.html stammt.
  • Datenbank: Es wird gezeigt, dass die Informationen in der Tabelle auf der HTML-Seite aus der Datenbank stammen. Klickt man zum Beispiel auf George in der Tabelle, sieht man, dass dieser Wert aus der Datenbank kommt.

Diese Demo verwendet eine In-Memory-Datenbank, sodass sich sogar bis zum SQL-Skript zurückverfolgen lässt. Wenn eine MySQL-Datenbank verwendet wird, kann die Verfolgung bis zur Datenbankverbindung reichen.

Verwendung

FlowTracker befindet sich derzeit im Proof-of-Concept-Stadium und funktioniert möglicherweise nicht bei allen Programmen zuverlässig. Außerdem verursacht es erheblichen Overhead und verlangsamt die Programmausführung. Zur Verwendung lädt man die Agent-JAR-Datei von FlowTracker herunter und fügt sie der Java-Kommandozeile hinzu.

Interne Funktionsweise

Kurze Erklärung

FlowTracker injiziert Code in Klassen-Dateien (Bytecode), um Daten im Speicher und deren Herkunft zu verfolgen. Verfolgt werden vor allem Text- und Binärdaten (Strings sowie char- und byte-Arrays).

  • JDK-Methodenaufrufe werden durch Methodenaufrufe von FlowTracker ersetzt.
  • An wichtigen Stellen im JDK wird Code injiziert, um Eingaben und Ausgaben zu verfolgen.
  • Innerhalb von Methoden werden Datenflussanalyse und tiefergehende Instrumentierung eingesetzt, um Werte in lokalen Variablen und auf dem Stack zu verfolgen.
  • Vor und nach Methodenaufrufen sowie am Anfang und Ende von Methoden wird Code hinzugefügt, um Methodenargumente und Rückgabewerte zu verfolgen.

Datenmodell: Tracker

Die zentralen Klassen und Konzepte im Datenmodell von FlowTracker:

  • Tracker: Hält Informationen über den Inhalt eines verfolgten Objekts und dessen Herkunft.
    • content: Der Inhalt, durch den Daten geflossen sind. Beispiel: alle Bytes, die einen InputStream oder OutputStream passiert haben.
    • source: Verknüpft Bereiche des Inhalts mit Quellbereichen anderer Tracker.
  • TrackerRepository: Enthält eine globale Map, die interessante Objekte mit ihren Trackern verknüpft.
  • TrackerPoint: Verweist auf eine Position in einem Tracker, die einen einzelnen primitiven Wert darstellt.

Grundlegende Instrumentierung

Damit Tracker aktuell bleiben, werden bei bestimmten JDK-Methodenaufrufen Aufrufe von FlowTracker-Hook-Methoden eingefügt. Zum Beispiel wird ein Aufruf von System.arraycopy durch einen Aufruf von com.coekie.flowtracker.hook.SystemHook.arraycopy ersetzt.

Primitive Werte, Datenflussanalyse

Das Verfolgen primitiver Werte ist eine größere Herausforderung. Um zum Beispiel einen byte-Wert zu verfolgen, werden innerhalb einer Methode Tracker in lokalen Variablen gespeichert.

Methodenaufrufe

Es wird modelliert, wie primitive Werte als Argumente und Rückgabewerte von Methodenaufrufen in andere Methoden fließen. Mit Invocation werden die PointTracker der Argumente und Rückgabewerte gespeichert.

Den Code selbst als Quelle verwenden

Es werden Werte verfolgt, die aus dem Code selbst stammen, etwa primitive Konstanten und String-Konstanten. Für jede Klasse wird ein Tracker erzeugt, und wenn auf eine Konstante verwiesen wird, wird dieser Tracker referenziert.

String-Literale

String-Literale werden neu kopiert, und der Inhalt des Strings wird mit ClassOriginTracker verknüpft. Zum Beispiel wird String s = "abc"; zu String s = StringHook.constantString("abc", 1234, 81); umgeschrieben.

Ersatzverfahren für nicht verfolgte Werte

Es werden nicht alle Werte im Programm verfolgt. Wenn ein nicht verfolgter Wert eine Stelle erreicht, an der verfolgt werden sollte, wird er ähnlich wie eine Konstante behandelt.

Zusammenfassung von GN⁺

  • FlowTracker verfolgt den Datenfluss in Java-Programmen und hilft dabei, die Programmausgabe zu verstehen.
  • Anhand der Spring-PetClinic-Demo lassen sich die Verarbeitung von HTTP-Anfragen, die Nutzung von Templates und die Anbindung an die Datenbank visuell nachvollziehen.
  • Das Projekt befindet sich derzeit im Proof-of-Concept-Stadium, funktioniert möglicherweise nicht bei allen Programmen zuverlässig und verursacht hohen Performance-Overhead.
  • Durch Datenflussanalyse und die Verfolgung von Methodenaufrufen wird die Herkunft primitiver Werte und von Objekten nachvollzogen.
  • Ähnliche Werkzeuge mit vergleichbarer Funktionalität sind etwa Dynatrace und New Relic.

1 Kommentare

 
GN⁺ 2024-09-15
Hacker-News-Kommentare
  • Es wird ein Tool namens FlowStorm für Clojure vorgestellt

    • Es forkt den offiziellen Clojure-Compiler und fügt zusätzlichen Bytecode ein
    • Da die meisten Werte unveränderlich sind, können Snapshots durch Beibehalten von Zeigern aufgenommen werden
    • Link zu einer Demo zum Debugging von Web-Apps: FlowStorm-Demo
  • Das Tooling im Java/JVM-Ökosystem wird als hervorragend gelobt

    • Es beeindruckt auf einem ähnlichen Niveau wie jitwatch
    • FlowTracker erinnert an Taint-Analyse
    • Relevantes Schlagwort: "dynamic taint tracking/analysis"
    • Links zu verwandten Projekten:
  • Die Demo, die HTML-Elemente bis zu SQL-Statements verfolgt, beeindruckt

    • Solche Tools könnten die erste Verteidigungslinie bei der Fehlersuche sein
  • Es erinnert an eine Smalltalk-Umgebung

    • Man kann alle Objekte und Nachrichten verfolgen und mit ihnen interagieren
  • Es wird betont, dass das Demo-Video sehr nützlich ist

    • Es dürfte hilfreich sein, wenn man sich in einer unbekannten Codebasis zurechtfindet
  • Es wird eine Erfahrung mit dem Experimentieren eines Konzepts ähnlich HTML Source Maps geteilt

    • Web-Entwicklungstools würden stark von dieser Full-Stack-Eigenschaft profitieren
    • Die Integration in bestehende Frameworks ist eine große Herausforderung
    • Link zu einem verwandten Projekt: HTML Source Maps
  • Es wird erwähnt, dass es der Eve-lang-Demo ähnelt

  • Jemand erinnert sich an eine ähnliche Arbeit zu einem Tool, das SQL-Injection dynamisch findet

  • Es wird eine Erfahrung mit der Vision geteilt, Daten im Internet zu verfolgen

    • Dies ist ein Schritt in die Richtung, den Ursprung eines Bildes oder den Weg eines Strings nachzuverfolgen
  • Es wird dafür gedankt, dieses Tool mit VSCode und im Projekt ausprobiert zu haben

    • Der Versuch wurde derzeit unterbrochen, aber es ist geplant, es noch einmal zu probieren