URL-Kodierung erklärt: Was ist Prozentkodierung
Jedes Mal, wenn Sie auf einen Link klicken, ein Formular absenden oder eine Webadresse eingeben, verarbeitet Ihr Browser im Hintergrund die URL-Kodierung. Diese kryptischen Zeichenketten aus Prozentzeichen und hexadezimalen Ziffern, die Sie in URLs sehen, sind nicht zufällig – sie sind ein sorgfältig entwickelter Mechanismus, der das Internet zuverlässig funktionieren lässt. Das Verständnis der URL-Kodierung ist für Webentwickler, API-Designer und jeden, der mit Webtechnologien arbeitet, von entscheidender Bedeutung. Dieser Leitfaden erklärt, was URL-Kodierung ist, warum sie existiert, wie sie funktioniert und welche Sicherheitsauswirkungen Sie kennen müssen.
Was ist URL-Kodierung?
URL-Kodierung, offiziell als Prozentkodierung bezeichnet, ist ein in RFC 3986 definierter Mechanismus, der Zeichen in ein Format umwandelt, das sicher in Uniform Resource Identifiers (URIs) übertragen werden kann. Die URL-Spezifikation erlaubt nur eine Teilmenge von ASCII-Zeichen, die direkt in URLs erscheinen dürfen. Jedes Zeichen, das nicht zu dieser erlaubten Menge gehört, muss als Prozentzeichen (%) gefolgt von zwei hexadezimalen Ziffern kodiert werden, die den Byte-Wert des Zeichens darstellen.
< zu %3C, da der ASCII-Code von < 60 ist, hexadezimal 3C.
Warum URL-Kodierung notwendig ist
URLs haben eine spezifische Syntax, die bestimmte Zeichen als Trennzeichen verwendet. Das Fragezeichen ? trennt den Pfad vom Query-String. Das &-Zeichen trennt Query-Parameter. Das Gleichheitszeichen = trennt Parameternamen und -wert. Der Schrägstrich / trennt Pfadsegmente. Wenn diese Zeichen in den übertragenen Daten vorkommen, würden sie als URL-Struktur und nicht als Inhalt missverstanden werden.
Überlegen Sie, was passiert, wenn ein Nutzer auf einer Website nach "rock & roll" sucht. Ohne Kodierung wäre die URL /search?q=rock & roll. Der Browser würde das & als Query-Parameter-Trennzeichen interpretieren und die Abfrage in zwei Parameter aufteilen: q=rock und einen zweiten Parameter namens roll (ohne Wert). Die URL-Kodierung behebt dieses Problem: /search?q=rock%20%26%20roll.
Wie Prozentkodierung funktioniert
Der Kodierungsprozess folgt einem einfachen, in der URI-Spezifikation definierten Algorithmus:
- Nicht-reservierte Zeichen identifizieren: Die Zeichen A-Z, a-z, 0-9, -, ., _ und ~ sind nicht reserviert. Sie müssen nie kodiert werden und können direkt in URLs erscheinen.
- Reservierte Zeichen identifizieren: Die Zeichen :, /, ?, #, [, ], @, !, $, &, ', (, ), *, +, ,, ; und = sind für die URL-Syntax reserviert. Sie müssen kodiert werden, wenn sie als Daten und nicht als Trennzeichen verwendet werden.
- Alle anderen Zeichen kodieren: Jedes Zeichen, das nicht in der nicht-reservierten oder reservierten Menge enthalten ist, muss prozentkodiert werden. Dies umfasst Leerzeichen, Steuerzeichen, Nicht-ASCII-Zeichen und alle Zeichen außerhalb des ASCII-Bereichs.
Der Kodierungsprozess für Nicht-ASCII-Zeichen
Nicht-ASCII-Zeichen (wie akzentuierte Buchstaben, CJK-Schriftzeichen und Emojis) erfordern einen zusätzlichen Schritt. Zuerst wird das Zeichen in seine UTF-8-Bytesequenz umgewandelt. Dann wird jedes Byte einzeln prozentkodiert. Das bedeutet, dass ein einzelnes Zeichen mehrere Prozentkodierungs-Tripel erzeugen kann.
Zum Beispiel ist die UTF-8-Bytesequenz des Euro-Zeichens (€) E2 82 AC. URL-kodiert wird es zu %E2%82%AC. Das deutsche Schriftzeichen "ü" hat die UTF-8-Sequenz C3 BC und ergibt %C3%BC. Das Emoji 😀 (Grinsendes Gesicht) hat eine 4-Byte-UTF-8-Sequenz und wird als %F0%9F%98%80 kodiert.
Häufig kodierte Zeichen
Die folgende Tabelle zeigt die am häufigsten URL-kodierten Zeichen:
| Zeichen | Kodierung | ASCII-Code | Grund |
|---|---|---|---|
| Leerzeichen | %20 | 32 (0x20) | In URLs nicht erlaubt |
| ! | %21 | 33 (0x21) | Reserviert (Sub-Delimiter) |
| # | %23 | 35 (0x23) | Reserviert (Fragment-Trennzeichen) |
| $ | %24 | 36 (0x24) | Reserviert (Sub-Delimiter) |
| & | %26 | 38 (0x26) | Reserviert (Query-Trennzeichen) |
| ' | %27 | 39 (0x27) | Reserviert (Sub-Delimiter) |
| ( | %28 | 40 (0x28) | Reserviert (Sub-Delimiter) |
| ) | %29 | 41 (0x29) | Reserviert (Sub-Delimiter) |
| + | %2B | 43 (0x2B) | Reserviert (Leerzeichen in Query) |
| , | %2C | 44 (0x2C) | Reserviert (Sub-Delimiter) |
| / | %2F | 47 (0x2F) | Reserviert (Pfad-Trennzeichen) |
| : | %3A | 58 (0x3A) | Reserviert (Protokoll-Trennzeichen) |
| ; | %3B | 59 (0x3B) | Reserviert (Parameter-Trennzeichen) |
| = | %3D | 61 (0x3D) | Reserviert (Wert-Trennzeichen) |
| ? | %3F | 63 (0x3F) | Reserviert (Query-Trennzeichen) |
| @ | %40 | 64 (0x40) | Reserviert (Autorisierungs-Trennzeichen) |
| [ | %5B | 91 (0x5B) | Reserviert (IPv6-Literal) |
| ] | %5D | 93 (0x5D) | Reserviert (IPv6-Literal) |
URL-Kodierung vs. HTML-Kodierung
URL-Kodierung und HTML-Entity-Kodierung werden oft verwechselt, aber sie dienen völlig unterschiedlichen Zwecken und arbeiten in unterschiedlichen Kontexten.
URL-Kodierung
URL-Kodierung wandelt Zeichen in das %XX-Format um, damit sie sicher in URLs übertragen werden können. Sie wird durch RFC 3986 spezifiziert und auf URL-Komponenten wie Pfade, Query-Strings und Fragmente angewendet.
HTML-Kodierung
HTML-Kodierung wandelt Zeichen in Entity-Referenzen wie &, < und > um, damit sie sicher in HTML-Dokumenten gerendert werden können. Sie verhindert, dass Browser Inhalte als HTML-Markup interpretieren. Die HTML-Kodierung wird durch die HTML-Spezifikation geregelt.
Wesentliche Unterschiede
| Aspekt | URL-Kodierung | HTML-Kodierung |
|---|---|---|
| Kontext | URLs und URIs | HTML-Dokumente |
| Format | %XX (Prozentzeichen + Hexadezimal) | oder NNN; |
| < | %3C | < |
| Beispiel für & | %26 | Beispiel für " |
| %22 | " | Zweck |
| Sichere URL-Übertragung | Schutz vor HTML-Injection | Spezifikation |
| RFC 3986 | HTML Living Standard | HTML Living Standard |
(HTML-kodiertes &) geschrieben werden. Beides ist gültig, aber die URL-Kodierung des &-Zeichens ist die korrektere Vorgehensweise, da sie die beabsichtigte Bedeutung der Daten bewahrt.
URL-Kodierung in verschiedenen Programmiersprachen
Jede größere Programmiersprache bietet integrierte Funktionen zur URL-Kodierung und -Dekodierung. Das genaue Verhalten variiert jedoch, und das Verständnis der Unterschiede ist entscheidend, um Fehler zu vermeiden.
JavaScript
JavaScript bietet drei Kodierungsfunktionen mit jeweils unterschiedlichem Verhalten:
// encodeURI - encodes a complete URL
// Preserves: :, /, ?, #, &, =, +, @, ;, ,, !, ~, *, ', (, )
const url = encodeURI("https://example.com/search?q=hello world");
// Result: "https://example.com/search?q=hello%20world"
// encodeURIComponent - encodes a URL component
// Encodes ALL special characters including URL delimiters
const param = encodeURIComponent("price=100&discount=20");
// Result: "price%3D100%26discount%3D20"
// Never use escape() - it is deprecated
// It does not handle Unicode correctlyDer wesentliche Unterschied besteht darin, dass encodeURI URL-Strukturzeichen beibehält, während encodeURIComponent alles kodiert. Verwenden Sie encodeURI, wenn Sie eine vollständige URL haben, und encodeURIComponent zum Kodieren einzelner Parameterwerte.
Python
from urllib.parse import quote, quote_plus, urlencode
# quote - standard URL encoding (spaces as %20)
encoded = quote("hello world&more")
# Result: "hello%20world%26more"
# quote_plus - spaces become + instead of %20
encoded_plus = quote_plus("hello world")
# Result: "hello+world"
# urlencode - encodes a dictionary as a query string
params = {"q": "hello world", "lang": "en"}
query = urlencode(params)
# Result: "q=hello+world&lang=en"PHP
// urlencode - spaces become +
$encoded = urlencode("hello world&more");
// Result: "hello+world%26more"
// rawurlencode - RFC 3986 compliant (spaces as %20)
$raw = rawurlencode("hello world&more");
// Result: "hello%20world%26more"Das Leerzeichen: %20 vs. +
Das Leerzeichen hat zwei gängige Kodierungen, und es ist wichtig zu verstehen, wann welche zu verwenden ist:
- %20: Die von RFC 3986 definierte Standard-Prozentkodierung. Dies ist die korrekte Kodierung für Leerzeichen in URL-Pfadkomponenten und immer sicher.
- + (Pluszeichen): Definiert durch den Medientyp application/x-www-form-urlencoded zur Kodierung von Formulardaten in Query-Strings. Bei dieser Kodierung werden Leerzeichen durch Pluszeichen ersetzt und Pluszeichen selbst als %2B kodiert.
Diese Unterscheidung ist wichtig, da die Dekodierung von + als Leerzeichen nur im Kontext von application/x-www-form-urlencoded-Daten korrekt ist. In URL-Pfadkomponenten ist + ein literales Pluszeichen, kein Leerzeichen. Die meisten serverseitigen Frameworks behandeln Query-Strings korrekt, aber bei der Kodierung von Pfaden oder bei benutzerdefinierten URL-Schemata kann dies zu subtilen Fehlern führen.
Sicherheitsauswirkungen
URL-Kodierung hat wichtige Sicherheitsauswirkungen, die jeder Webentwickler kennen muss.
Double-Encoding-Angriffe
Double-Encoding tritt auf, wenn Daten mehrfach URL-kodiert werden. Ein Angreifer könnte %2527 übermitteln, das bei der ersten Dekodierung zu %27 und bei der zweiten zu einem einfachen Anführungszeichen ' wird. Wenn der Sicherheitsfilter nur die erste Dekodierung prüft, übersieht er die bösartigen Zeichen. Dies kann Eingabevalidierung, Cross-Site-Scripting-(XSS)-Filter und SQL-Injection-Schutz umgehen.