Hashes, eine Tür für Hacker
Gerade im Web wird oft mit Hashes gearbeitet, sei es innerhalb einer URL z.B. https://example.com/file?hash=12345abcde oder als parametrische Abfrage.
Die Offenlegung von Hashes ist ein oft unterschätztes Sicherheitsproblem in Webanwendungen, das jedoch gravierende Folgen haben kann, wenn es nicht ordnungsgemäß behandelt wird. Ein Hash ist im Grunde eine Funktion, die aus einem Eingabewert eine feste Zeichenkette erzeugt, die wie eine digitale Signatur fungiert. Er wird oft verwendet, um Daten zu verschlüsseln oder zu schützen, sei es für Passwörter, Dateien oder Zugriffsberechtigungen. Doch wie bei vielen Technologien liegt die Sicherheit nicht allein in der Technik selbst, sondern in der Art und Weise, wie sie verwendet wird.
Der erste und vielleicht wichtigste Grundsatz in der Sicherheit von Hashes lautet: Gib niemals Hashes in der URL preis. URLs sind im Web so etwas wie die offenen Straßenschilder einer Stadt. Jeder, der die URL sieht, kann den Hash ebenfalls sehen. Wenn der Hash als Zugangsschlüssel fungiert, dann hat jeder, der den Hash in der URL sieht, automatisch dieselben Rechte wie der ursprüngliche Nutzer. Das Problem dabei ist, dass URLs oft in verschiedenen Logs oder Protokollen gespeichert werden. Webserver protokollieren sie, Browser speichern sie im Verlauf, und sogar Drittanbieter-Tools oder Browsererweiterungen könnten darauf zugreifen. Dadurch wird ein potenzieller Angreifer in die Lage versetzt, den Hash zu kopieren und unberechtigten Zugriff zu erhalten.
Es reicht jedoch nicht, Hashes nur nicht in URLs zu verwenden. Die Sicherheitsprobleme können tiefer gehen, besonders wenn der verwendete Hash-Algorithmus selbst veraltet oder unsicher ist. Ein Beispiel ist der SHA-1-Algorithmus. Obwohl er einst als sicher galt, hat sich inzwischen herausgestellt, dass SHA-1 für moderne Angreifer mit ausreichenden Ressourcen leicht zu brechen ist. Selbst wenn der Hash mit einem sogenannten „Salt“ (einem zufälligen Wert, der den Hash einzigartig macht) ergänzt wird, bleibt die Grundvoraussetzung eines unsicheren Algorithmus ein Problem. Moderne und sichere Algorithmen wie SHA-256, bcrypt oder Argon2 sind heute die Standards. Diese Algorithmen sind speziell darauf ausgelegt, Brute-Force-Angriffe zu erschweren, bei denen ein Angreifer durch systematisches Ausprobieren verschiedener Eingaben versucht, den ursprünglichen Wert des Hashes herauszufinden.
Ein weiteres Problem entsteht, wenn Hashes als alleinige Schutzmechanismen für den Zugang zu Dateien oder sensiblen Ressourcen verwendet werden. Ein Hash allein ist kein ausreichender Schutz. Webanwendungen sollten stattdessen auf Authentifizierungsmechanismen wie Token oder Sitzungen setzen. Token-basierte Authentifizierung, beispielsweise durch OAuth oder JSON Web Token (JWT), ermöglicht es, den Zugang zu bestimmten Ressourcen präzise zu kontrollieren und den Zugriff zeitlich zu begrenzen. Ein Token hat zudem den Vorteil, dass es verschlüsselt werden kann, sodass der eigentliche Inhalt für Außenstehende nicht sichtbar ist. Dadurch wird das Risiko einer unbefugten Nutzung minimiert.
Ein weiterer wichtiger Punkt betrifft die sichere Übertragung von Hashes oder Authentifizierungsdaten. Selbst wenn alle Sicherheitsvorkehrungen in Bezug auf die Algorithmen und die URL getroffen wurden, bleibt die Kommunikation über das Internet ein Schwachpunkt, wenn sie nicht verschlüsselt ist. Jegliche Übertragung von sicherheitsrelevanten Daten sollte immer über HTTPS erfolgen. HTTPS stellt sicher, dass die Daten während der Übertragung verschlüsselt werden und so nicht von Dritten abgefangen oder manipuliert werden können.
Ein oft übersehenes Detail ist, dass die Verarbeitung von sicherheitsrelevanten Informationen immer im Backend erfolgen sollte. Wenn Hashes oder andere sicherheitskritische Daten im Frontend (z. B. in JavaScript) verarbeitet werden, eröffnet dies eine breite Angriffsfläche. Im Frontend hat der Nutzer, oder potenziell ein Angreifer, viel mehr Kontrolle und Einsicht in den Code und die Daten, die verarbeitet werden. Dies kann dazu führen, dass Schwachstellen leichter ausgenutzt werden können. Ein Angreifer könnte versuchen, den Code zu manipulieren oder Daten zu stehlen, noch bevor sie den Server erreichen.
Zusätzlich zu diesen Maßnahmen ist es entscheidend, dass Hashes stets gesalzen werden. Ein Salt ist eine zufällig generierte Zeichenkette, die dem Eingabewert vor dem Hashen hinzugefügt wird, um sicherzustellen, dass jeder Hash einzigartig ist. Selbst wenn zwei Benutzer dasselbe Passwort haben, führt der Salt dazu, dass sie unterschiedliche Hashes haben. Ohne einen Salt könnten Angreifer mithilfe von „Rainbow Tables“ (vorgefertigte Listen von Hashes und ihren zugehörigen Eingabewerten) schnell den ursprünglichen Wert des Hashes ermitteln. Salts sollten niemals offengelegt und immer serverseitig verwaltet werden.
Die Verwendung von Zugriffstoken oder Sitzungsdaten anstelle von statischen Hashes ist ebenfalls ein wichtiger Schritt. Ein statischer Hash bleibt immer gleich, was bedeutet, dass er von Angreifern einfach kopiert und wiederverwendet werden kann. Zugriffstoken hingegen können zeitlich begrenzt und für eine einzige Sitzung gültig sein. Das bedeutet, selbst wenn ein Token gestohlen wird, ist sein Nutzen stark eingeschränkt, da es bald abläuft oder nur in einer bestimmten Sitzung verwendet werden kann.
Eine weitere Schutzmaßnahme ist die Verwendung von sicheren Cookies, um sensible Daten wie Sitzungsschlüssel oder Authentifizierungstoken zu speichern. Diese Cookies sollten als „HttpOnly“ und „Secure“ markiert sein. Das Attribut „HttpOnly“ verhindert, dass clientseitiges JavaScript auf den Cookie zugreifen kann, was das Risiko von Cross-Site-Scripting-Angriffen verringert. „Secure“ stellt sicher, dass der Cookie nur über HTTPS übertragen wird, was wiederum das Risiko eines Abfangens durch Dritte minimiert.
Zusammenfassend lässt sich sagen, dass die Offenlegung von Hashes in Webanwendungen ein ernstes Problem darstellen kann, insbesondere wenn unsichere Algorithmen verwendet oder Hashes in URLs oder Headern offengelegt werden. Webentwickler müssen sicherstellen, dass Hashes nicht als alleinige Schutzmaßnahme verwendet werden und immer durch sicherere Mechanismen wie Token-basierte Authentifizierung und Verschlüsselung ergänzt werden. Gleichzeitig sollte die sichere Übertragung und Verarbeitung von sicherheitsrelevanten Daten immer gewährleistet sein. Nur durch eine ganzheitliche Betrachtung der Sicherheit können Webanwendungen vor unbefugtem Zugriff und Datenlecks geschützt werden.