Zum Hauptinhalt springen

10. Sicherheitsüberlegungen (Security Considerations)

Implementierer von UTF-8 müssen sich mehrerer Sicherheitsprobleme bewusst sein. Viele dieser Probleme ergeben sich aus bestimmten Arten fehlerhafter Sequenzen, die erstellt werden können, um Sicherheitsprüfungen zu umgehen oder anderen Schaden zu verursachen.

Ungültige Sequenzen (Invalid Sequences)

Eine UTF-8-Byte-Sequenz KANN (MAY) ungültig sein, weil:

  1. Sie verbotene Bytes enthält
  2. Sie keine gültige Sequenz vervollständigen kann
  3. Sie eine zu große Zahl oder eine reservierte Zeichennummer kodiert
  4. Sie zu lang ist oder
  5. Sie nicht in der kürzesten möglichen Form kodiert ist

Kürzeste Form (Shortest Form)

Die Anforderung der „kürzesten Form" ist für die Sicherheit besonders wichtig, wie unten erläutert.

Verarbeitungsanforderungen (Processing Requirements)

Ungültige Byte-Sequenzen SOLLTEN NICHT (SHOULD NOT) als Zeichen interpretiert werden; beispielsweise sollte ein Shift-In/Shift-Out-ähnlicher Interpreter NICHT (SHOULD NOT) beginnen, Bytes nach einem anderen Schema mitten in einer UTF-8-Byte-Sequenz zu interpretieren.

Reaktion auf ungültige Sequenzen

Eine ungültige Sequenz SOLLTE (SHOULD) entweder:

  1. Vollständig verworfen werden, oder
  2. Durch ein Ersatzzeichen (wie U+FFFD REPLACEMENT CHARACTER) ersetzt werden, je nach Kontext

Um Invarianten in statischen Dokumenten zu bewahren, insbesondere (wie digital signierte Dokumente), kann es notwendig sein, solche Sequenzen an Ort und Stelle zu belassen; in diesem Fall muss ihre Anwesenheit dem Implementierer signalisiert werden.

Erkennung auf Byte-Ebene

Die Überprüfung der kürzesten Form SOLLTE (SHOULD) auf UTF-8-Sequenzen auf Byte-Ebene durchgeführt werden (wie in der obigen Syntax beschrieben), nicht durch:

  • Zunächst UTF-8 in UCS-Zeichen konvertieren und dann die Werte auf Gültigkeit prüfen
  • Byte-Sequenzen nur auf Formungültigkeit prüfen

Angriffe mit nicht-kürzester Form (Non-Shortest Form Attacks)

Das Problem

Eine wichtige Beobachtung, die vielen Sicherheitsschwachstellen mit UTF-8 zugrunde liegt, ist, dass eine beliebige Anzahl längerer (und ungültiger) als der kürzesten Form erstellt werden kann (insbesondere für ASCII-Zeichen), die:

  • Dasselbe Zeichen kodieren, aber
  • Sich aus Byte-Sicht unterscheiden

Angriffsvektor

Eine bestimmte Zeichensequenz, die ein Unicode-Zeichen mit niedrigem Wert enthält (wie „/"), kann in einem Sicherheitskontext kritisch sein (z. B. als Pfadtrennzeichen).

Warnung: Eine byte-für-byte ungültige Sequenz, die dennoch dieselbe Zeichennummer kodieren würde, kann bei naiven String-Scans unentdeckt bleiben und dann bei nachfolgenden Operationen korrekt interpretiert werden, wodurch eine Schwachstelle ausgelöst wird.

Angriffsbeispiele

Beispiel 1: Überlange Sequenz

Zeichen: '/' (Schrägstrich)
Unicode: U+002F

Korrekte Form:
UTF-8: 2F (1 Byte)

Überlange Formen (UNGÜLTIG):
C0 AF (2 Bytes)
E0 80 AF (3 Bytes)
F0 80 80 AF (4 Bytes)

Gefahr: Eine Sicherheitsprüfung könnte nach 2F suchen, aber ein fehlerhafter Decoder könnte C0 AF akzeptieren und einen Path-Traversal-Angriff ermöglichen.

Beispiel 2: XSS-Angriff

Zeichen: '<' (kleiner als)
Unicode: U+003C

Korrekte Form:
UTF-8: 3C (1 Byte)

Überlange Form (UNGÜLTIG):
C0 BC (2 Bytes)

Gefahr: Umgehung von Anti-XSS-Filtern, die nur nach 3C suchen.

Ersatzpaare (Surrogate Pairs)

Das Problem

Ebenso ist die Verwendung von UTF-8-Byte-Sequenzen, die Zeichennummern im Ersatzpaar-Bereich kodieren, ungültig, kann aber von einer einfachen Implementierung erzeugt werden, die UTF-16-Daten durch Byte-für-Byte-Übersetzung in UTF-8 konvertiert.

Angriffsvektor

Wiederum kann eine solche ungültige Sequenz einer Sicherheitsprüfung entgehen und dann später korrekt interpretiert werden, wodurch Probleme ausgelöst werden.

Beispiel

Zeichen: '𣎴' (seltenes chinesisches Zeichen)
Unicode: U+233B4

In UTF-16 (Ersatzpaare):
D84C DF34

UNGÜLTIGE Kodierung in UTF-8 (CESU-8):
ED A1 8C ED BE B4

KORREKTE Kodierung in UTF-8:
F0 A3 8E B4

Gefahr: Einige Systeme könnten die ungültige 6-Byte-Sequenz akzeptieren, was zu Inkonsistenzen führt.

Unicode-Normalisierungsformen (Unicode Normalization Forms)

Das Problem

Schließlich haben viele Zeichennummern eine „kanonische Äquivalenz"- oder „Kompatibilitäts"-Beziehung zu anderen Zeichennummern. Wenn zwei Zeichensequenzen in einer Äquivalenzbeziehung stehen, haben sie (zumindest in einigen Kontexten) dieselbe Bedeutung.

Sicherheitsimplikationen

Es kann nicht angenommen werden, dass zwei Sequenzen, selbst wenn sie identisch in UTF-8 kodiert sind, aber nicht byte-für-byte identisch sind, nicht als äquivalent von einem Empfänger behandelt werden, insbesondere wenn Normalisierung durchgeführt wird (siehe [UTR-15] für weitere Informationen zur Unicode-Normalisierung).

Beispiel

Zusammengesetztes Zeichen: 'é' (e mit Akut)
Unicode: U+00E9
UTF-8: C3 A9

Zerlegte Form: 'é' (e + kombinierender Akzent)
Unicode: U+0065 U+0301
UTF-8: 65 CC 81

Darstellung: é = é (visuell identisch)
Bytes: C3 A9 ≠ 65 CC 81 (verschieden)

Gefahr: Sicherheitsprüfungen basierend auf rohen Byte-Vergleichen können fehlschlagen.

Sicherheitsempfehlungen (Security Recommendations)

✅ 1. Strenge Validierung

Immer validieren, dass UTF-8-Sequenzen:

  • In der kürzesten Form sind
  • Im gültigen Zeichenbereich liegen (≤ U+10FFFF)
  • Keine Ersatzpaare kodieren (U+D800-U+DFFF)

✅ 2. Ablehnung ungültiger Sequenzen

Sofort ablehnen jede ungültige Sequenz. Nicht versuchen zu „reparieren" oder die Absicht zu „erraten".

✅ 3. Unicode-Normalisierung

Normalisieren Zeichenketten vor Sicherheitsvergleichen. NFC- oder NFD-Formen konsistent verwenden.

✅ 4. Analyse auf Byte-Ebene

Validieren UTF-8-Sequenzen auf Byte-Ebene vor jeder Konvertierung in UCS-Zeichen.

✅ 5. Mehrfache Konvertierungen vermeiden

Minimieren Hin- und Rückkonvertierungen zwischen verschiedenen Kodierungen, um Fehlerrisiken zu reduzieren.

✅ 6. Dokumentation

Dokumentieren klar das Verhalten Ihrer Implementierung beim Antreffen ungültiger Sequenzen.