Der Tracking-Link-Bug, der signierte URLs zerstört
Ein Bug kann lange Zeit in Ihrem Code verborgen bleiben. Er funktioniert bei den meisten Links. Bei Marketing-Links bleibt er unbemerkt. Aber er zerstört die Links, die am wichtigsten sind.
Ich habe diesen Bug in meinem Tool, mail-history, gefunden. Er zerstört signierte URLs. Das sind Links, die für die E-Mail-Verifizierung oder sichere Downloads verwendet werden.
So ist es passiert.
Mein Tool schreibt das E-Mail-HTML um, um Klicks zu tracken. Es nimmt die ursprüngliche URL, verschlüsselt sie und wandelt sie in einen Tracking-Link um. Wenn ein Nutzer klickt, entschlüsselt das Tool die URL und leitet ihn an das eigentliche Ziel weiter.
Das Problem begann, als ich die URL aus dem gerenderten HTML ausgelesen habe.
Laravel und Blade maskieren (escapen) HTML-Attribute. Ein Et-Zeichen (&) in einer URL wird zu einer HTML-Entity. Es verwandelt sich von & in &.
Bei einem Standard-Link korrigiert der Browser dies automatisch. Man bemerkt den Unterschied nicht.
Aber mein Tool sendet den Link nicht an einen Browser. Es sendet den String an eine Entschlüsselungsfunktion.
Wenn Ihre signierte URL so aussieht: https://example.com/verify?expires=123&signature=abc
Sieht das HTML so aus: https://example.com/verify?expires=123&signature=abc
Mein Tool verschlüsselt die Version mit &. Wenn der Nutzer klickt, entschlüsselt das Tool sie und leitet ihn an die Version mit & weiter.
Laravel sieht das & und denkt, die Signatur sei falsch. Die Verifizierung schlägt fehl.
Die Lösung besteht aus einer einzigen Zeile Code. Ich verwende html_entity_decode, um & vor der Verschlüsselung wieder in & umzuwandeln.
Dies stellt sicher, dass die entschlüsselte URL bytegenau mit der ursprünglichen signierten URL übereinstimmt.
Eine Lehre für Ihre Arbeit:
- Wenn Sie Daten aus gerendertem HTML auslesen, um sie in einer Funktion zu verwenden, gehen Sie davon aus, dass sie maskiert (escaped) sind.
- Browser verzeihen Fehler. Verschlüsselung und Signaturvalidierung tun das nicht.
- Wenn Sie einen Einzeiler-Fix verwenden, schreiben Sie einen Test dafür.
Ich habe einen Test geschrieben, der gezielt auf das Vorhandensein von & prüft. Wenn ein zukünftiger Entwickler meine Korrektur im Zuge einer Bereinigung entfernt, wird der Test sofort fehlschlagen.
Quelle: https://dev.to/nasrulhazim/the-tracking-link-bug-that-only-breaks-signed-urls-38c