Das Thema Sicherheit ist in der heutigen Zeit wichtiger denn je. Beinahe alles wurde digitalisiert und befindet sich in einem eigenen Netzwerk oder ist mit dem Internet verbunden. Somit ist es theoretisch möglich, von einem Client sämtliche Server anzusprechen, die mit dem Internet verbunden sind. Wenn man es mit der Realität vergleichen würde, stehen sämtliche Gebäude auch irgendwo auf der Welt und könnten betreten werden, wenn es nicht die Sicherheitsvorkehrungen geben würde. Genau solche Sicherheitsvorkehrungen gibt es im Internet auch, um das unerlaubte Eindringen zu verhindern.
Ich bin anfänglich sehr blauäugig an das Thema herangegangen und habe gedacht, beim Programmieren einer Internetseite würde es ausreichen eine Login-Maske zu erstellen. Somit hätte ich alle anderen ausgesperrt und es hätten nur die Nutzer Zugriff auf die Seite, denen ich den Zutritt vorher erlaubt hätte. Doch dann wurde ich mit Man-in-the-Middle, DOS-Angriffen und Zertifikaten konfrontiert. Zum Glück gibt es Organisationen wie die OWASP (Open Web Application Security Project), die es sich zur Aufgabe gemacht haben, die Sicherheit im World Wide Web zu verbessern. Dafür stellen sie kostenfrei Informationen, Werkzeuge und Methoden zur Verfügung, mit denen sich jeder ein gewisses Grundwissen aneignen kann. Auf der Internetseite der OWASP gibt es eine Auflistung der Top-10-Sicherheitslücken, die in vielen der aktuellen Applikationen vorhanden sind. Diese Sicherheitslücken werden dort erläutert und Maßnahmen erklärt, wie sie so gut wie möglich geschlossen werden können. Dabei geht es von der SQL-Injektion und der unsicheren Authentifizierung bis zum Upload von Dateien.
Um besser auf die Sicherheitslücken und möglichen Sicherheitsvorkehrungen einzugehen werde ich dem Entwickler Sebastian Sicher bei der Programmierung seiner Website folgen. Auf der Internetseite können sich Schlosser registrieren, die einen Schlüsseldienst anbieten. Sebastian hat die Internetseite grundlegend erstellt und befasst sich nun mit der Authentifizierung der Benutzer – der Digital Identity. Dabei geht es darum zu beweisen, dass es sich bei der Person, die das System nutzen möchte, auch wirklich um die Person handelt, die die Berechtigung dazu besitzt. Dafür wird ein Session Management genutzt, welches die Aufgabe besitzt, die Sitzung des Nutzers zu überprüfen, damit dieser sich nicht ständig neu anmelden muss, während er am System arbeitet. Es wurde auch ein Standard (NIST 800-63b) vom NIST (National Institute of Standards and Technology) aufgesetzt, welcher den Nutzer bei der Einrichtung einer Digital Identity leitet. Sebastian hat für die Authentifizierung ein Login-Fenster erstellt, dass dazu dient, sich zu registrieren und anzumelden. Damit die Website von Sebastian nicht gehackt werden kann, gehe ich hier auf ein paar wichtige Punkte ein, die bei der Authentifizierung beachtet werden sollten und die aus QA-Sicht wichtig sind.
Das simpelste Beispiel für die Authentifizierung, welches man finden kann, ist ein einfaches Passwort. Das vom Benutzer erstellte einfache Passwort speichert Sebastian in seinem System ab und überprüft es, wenn der Benutzer sich anmelden möchte. Dabei ist allgemein bekannt, dass ein komplexes Passwort genutzt werden sollte, damit dieses nicht über das Bruteforce-Verfahren zu schnell ermittelt werden kann. Das NIST gibt dabei mehrere Empfehlungen oder Richtlinien vor, die eingehalten werden sollten, damit die Passwörter sicher sind. So wird empfohlen, dass ein Passwort mindestes 8, wenn nicht sogar 12 Zeichen lang sein sollte, da die Anzahl an Zeichen die Varianten für das Bruteforce-Verfahren exponentiell steigert. Weiterhin sollten keine Standardwörter verwendet werden, selbst wenn Sonderzeichen hineingesetzt werden. Ein Beispiel wäre das Wort „Passwort“ zu „Pa§§w0r1“ zu ändern. Die meisten Brutefore-Algorithmen erkennen solche Konstrukte schnell. Sonderzeichen erbringen heute nicht mehr dieselbe Effizienz wie früher, da die Verfahren zum Entschlüsseln eines Passwortes sämtliche Sonderzeichen mit einbeziehen. Es wird daher eher empfohlen, für ein sicheres Passwort lange und kryptische Passphrasen zu verwenden.
Der wichtigere Punkt an dieser Stelle ist allerdings die Speicherung der Passwörter auf Sebastians System. Bei kleineren Anwendungen können die Passwörter in JSON-Dateien abgelegt werden, doch unser Entwickler möchte eine große und weiterreichende Applikation erstellen. Da die Strukturen hier somit komplexer werden, werden die Passwörter in einer Datenbank gespeichert. Weil Sebastian keine größeren Sicherheitskenntnisse besitzt, speichert er die Passwörter in seiner Datenbank ohne Verschlüsselung ab. Er vermutet, dass sowieso niemand auf sein System käme, ohne dass er sich offiziell registriert hätte. Die Top-10-Sicherheitslücken von OWASP zeigen allerdings, dass Datenbank-Leaks zu einer der häufigsten Sicherheitsschwachstellen gehören. Er muss daher davon ausgehen, dass die Angreifer auf die Daten der Datenbank zugreifen können. Dadurch, dass sie dort unverschlüsselt gespeichert wurden, könnte sich ein Angreifer problemlos die Login-Informationen aller User seiner Website aneignen. Darum ist es sehr wichtig, alle Passwörter verschlüsselt zu speichern. Hierzu können verschiedene Hash-Algorithmen, z. B. SHA256, WHIRLPOOL oder TIGER2 verwendet werden. Diese Algorithmen liefern eine Zeichenkette, die nach heutigem Wissenstand nicht entschlüsselt werden kann.
Somit wären die Passwörter gesichert, auch wenn sie gestohlen werden. Leider werden viele dieser Algorithmen mit der Zeit effizienter „geknackt“. Man kann die Hashes zwar nicht entschlüsseln, aber es ist möglich, mit Hilfe von Rainbow-Tabellen die Passwörter aus den Hashes zurückzuverfolgen. Rainbow-Tabellen sind eine Auflistung von unzähligen Passwörtern, die mit dem speziellen Algorithmus codiert wurden. Dem entsprechend ist es möglich, mit dem Hash über solche Rainbow-Tabellen die Passwörter zu finden. Hier ist beispielsweise eine solche Rainbow-Tabelle.
Beispiel Passwort Rückführung:
NTLM Hash: 2b5cec7f00f89013efd8d2b0b5f6ac23
Entschlüsseltes Passwort: NecoPasswort
Daher ist es wichtig, dass ein sicherer Algorithmus zur Verschlüsselung gewählt wird. Der Hash-Algorithmus NTLM kann mit den heutigen Verfahren bei einer Länge von 8 Zeichen innerhalb von wenigen Minuten gelöst werden. Um solche Rückführungen über Rainbow-Tabellen zu erschweren, ist es für Sebastian notwendig, weitere Vorkehrungen zur Verschlüsselung zu verwenden. Hier fällt die Wahl auf die SALT & PEPPER-Variante. Das Passwort, welches der Nutzer zum Login verwendet, wird mit einem SALT-String ergänzt und daraufhin gehashed. Dadurch wird das Passwort komplexer und kann nicht mit einfachen Rainbow-Tabellen entschlüsselt werden. Es wird empfohlen, für jeden Benutzer einen eigenen SALT-String zu erzeugen, um eine höhere Varianz zu bekommen. Die Schwachstelle vom SALT ist, dass sie genauso wie die Passwort-Hashes auch in der Datenbank gespeichert werden. Sie können zwar in unterschiedlichen Tabellen gespeichert werden, doch sobald ein Angreifer sich Zugriff auf die Datenbank verschafft hat, ist es dem Angreifer möglich, die SALTs auszulesen und zum Entschlüsseln zu verwenden. Daher kommt noch eine zweite Stufe der Verschlüsselung hinzu – der PEPPER. Der PEPPER-String funktioniert auf dieselbe Weise wie der SALT. Es wird ein String vor dem Hashen des Passwortes hinzugefügt, um die Rückführung zu erschweren. Der PEPPER wird allerdings nicht in der Datenbank gespeichert, sondern im Quellcode hartkodiert. Somit ist es Angreifern, die nur auf die Datenbank zugreifen können, nicht möglich, zusammen mit den Hashes auch den PEPPER aus dem Quellcode zu lesen.
Sebastian hat damit seine Passwort-Hashes gesalzen und gepfeffert. Was noch angemerkt werden muss, ist, dass die Sicherheit eines Passwortes damit nicht gesteigert wird. Es wird einem Angreifer aber erschwert, mit Hilfe von Rainbow-Tabellen die Passwörter der Nutzer zu entschlüsseln.
Ein anderer Weg für Sebastian, um den Zugriff auf seine Website zu sichern, ist die Verwendung von Multi-Faktor-Authentifizierung (MFA) für das Login. MFA-Verfahren sind heutzutage bereits sehr verbreitet. Microsoft Azure mit seinem SMS-Code, Banken mit ihrer Chip-TAN oder der Google Authenticator. Sie alle erzeugen einen Code, sobald ein Login getriggert wurde. Diese Codes werden über einen separaten Kanal übertragen und bieten daher eine sehr geringe Angriffsfläche, um die Codes auszulesen. Somit hat Sebastian eine doppelte Absicherung dafür, dass nur legitimierte Nutzer sich auf seinem System einloggen können. Unter Umständen wäre es möglich, über den Weg von SQL-Injections die Passwörter zu stehlen, doch ein Login wäre unmöglich, solange der Angreifer nicht zusätzlich über den MFA-Code verfügt.
Aus der QA-Sicht ist es wichtig zu ermitteln, wie die Passwörter auf einem System gespeichert sind und sich die folgenden Fragen zu stellen:
- Wo befinden sich die Passwörter?
- Sind sie verschlüsselt und wie sind sie es?
- Ist aufgrund von Metadaten ersichtlich, welche Hash-Algorithmen verwendet wurden?
- Gibt es zusätzliche Vorkehrungen für die Passwort-Sicherung (MFA, SALT & PEPPER)?
Für den Selbsttest können Online Hash-Generatoren verwendet werden, um Passwörter zu verschlüsseln und im Anschluss zu versuchen, diese mit Hilfe von Rainbow-Tabellen zu entschlüsseln.
Mit diesen Gedanken möchte ich den ersten Teil meines Sicherheits-Talks beenden. Ich hoffe, ich konnte euch einen kleinen Einblick darüber geben, worauf bei der Passwortsicherung geachtet werden muss.