Applikation

Sicherheit in Web-Applikationen erhöhen

  • Gespeicherte Passwörter richtig verschlüsseln

    Mittlerweile dürfte jedem bekannt sein, dass Passwörter niemals im Klartext in der Datenbank gespeichert werden sollten. Stattdessen sollte ein Hash des Passworts erstellt werden. Hierfür wurde in der Vergangenheit gerne MD5 verwendet, dies gilt jedoch nicht mehr als sicher, da Dictionaries existieren, die MD5-gehashte Strings wieder in Klartext zurückverwandeln. Außerdem ist MD5 sehr performant, was in diesem Fall nicht gut ist, da Cracker sehr viele Passwortkombinationen in kurzer Zeit ausprobieren können. Zum Hashen sollte daher ein Algorithmus wie bcrypt oder PBKDF2 verwendet werden, da es den Prozessor mehr Rechenzeit kostet.

    Mit dem Hashen allein ist es aber noch nicht getan, da zum Entschlüsseln immer noch Dictionaries verwendet werden könnten. Daher muss vor dem Hashen das Klartextpasswort noch mit einem Salt versehen werden. Ein Salt ist eine zufällige Zeichenfolge, die vor das Passwort gehängt wird, bevor es gehasht wird. Es sollte dazu kein systemweiter Salt verwendet werden, der womöglich noch im Sourcecode steht. Stattdessen sollte pro Passwort ein eigener zufälliger Salt verwendet werden. Dieser darf dann im Klartext mit dem Hash zusammen in der Datenbank abgelegt werden.

    Helfen kann einem in PHP dabei die PHPass-Library, die folgendermaßen verwendet wird:

    $hasher=new PasswordHash(8, false);
    $hash=$hasher->HashPassword($plainpassword);
    //$hash kann dann in der Datenbank abgelegt werden
    
    //Zum Prüfen eines eingegebenen Passworts:
    $check=$hasher->CheckPassword($plainpassword, $hash);
    

    PHPass kümmert sich dabei automatisch um die Erstellung von Salts.

    Es nützt übrigens die beste Verschlüsselung nichts, wenn z.B. vergessene Debug-Anweisungen Klartext-Passwörter in Error-Logs schreiben. Es sollte immer bedacht werden, dass Log-Dateien eventuell auch schützenswerte Informationen enthalten können.

  • Zwei-Faktor-Authentifizierung verwenden

    Übliche Faktoren, die zur Authentifikation verwendet werden können, sind Wissen (Passwörter), Besitz (z.B. ein Handy, auf dem eine SMS mit einem Code ankommt) und Biometrie (Fingerabdruck, Iris-Scan). Die meisten Websites setzen also nur auf Wissen. Es ist allerdings ratsam, über die Einführung eines zweiten Faktors nachzudenken. Hierbei bietet sich in erster Linie Besitz an, da mittlerweile jeder ein Handy besitzt. Nun ist das Verschicken von SMS allerdings teuer. Es gibt aber eine andere Methode, die verwendet werden kann.

    Und zwar gibt es mit Google Authenticator einen sogenannten One-Time-Pad-Generator, der als App auf einem Smartphone installiert werden kann. Die App muss einmal mit einem speziellen Code initialisiert werden und generiert dann für eine Website alle 30 Sekunden eine 6-stellige Zahl, die nur innerhalb dieses Zeitfenster gültig ist. Diese Zahl kann dann auf der Website zusätzlich zum Passwort eingegeben werden und wird dort verifiziert. Die Tatsache, dass dieser Code so schnell ungültig wird, macht es einem Angreifer sehr schwierig, ihn zu erraten.

  • Personenbezogene Daten mit Bedacht speichern

    Laut Bundesdatenschutzgesetz gilt der Grundsatz der Datenvermeidung und Datensparsamkeit. Das bedeutet, man sollte nur das Nötigste an personenbezogenen Daten speichern. Dazu gehören auch IP-Adressen von Usern. Da IP-Adressen generell aber in Webserver-Log-Dateien landen, sollte man hier aufpassen. Es wird toleriert, dass sie mitgeloggt werden, aber eigentlich nur aus Sicherheitsgründen und zur Fehlersuche. Es sollten daher die Dateien nach einer angemessenen Zeitspanne gelöscht werden, wenn sie für diesen Zweck nicht mehr benötigt werden.

    Generell gilt: Wenn man erst gar keine personenbezogenen Daten speichert, können sie einem schließlich auch nicht entwendet werden.

  • Applikations-Fehlerberichte kürzen

    Treten auf einer Website Fehler auf, ist z.B. die Datenbank nicht erreichbar, werden dem Besucher allzuoft ausführliche Stack-Traces angezeigt, die viel zu viele Applikationsdetails preisgeben. Dies sollte unbedingt abgestellt werden, da hier für einen Angreifer sehr nützliche Informationen vorliegen, wenn z.B. das verwendete Framework mit Version oder sogar Credentials verraten werden.

  • Keine extern gehosteten Dateien einbinden

    Häufig genutzte Libraries wie jQuery oder auch Google Fonts von externen Hosts nachzuladen ist aus Performance-Gründen eine gute Idee. Allerdings erhalten die verwendeten CDNs durch die Einbindung die Verbindungsdaten aller User auf der entsprechenden Website. Jeder Visit auf der Website wird also auch von den extern hostenden Unternehmen wahrgenommen. Durch clientseitiges Caching kommt zwar nicht jeder Request dort an, aber es reicht, um Datenschützer zu beunruhigen.

    Es sollte also darauf verzichtet werden, solche Dateien extern im Ausland zu hosten.

  • Kein Google Analytics verwenden

    Google Analytics ist ein praktischer, kostenloser Dienst, der sehr einfach eingebunden werden kann und schöne Besucherstatistiken für eine Website anfertigt. Leider schenkt man durch das Einbinden Google mehr Daten über seine User als einem lieb sein kann. IP-Adressen werden zwar innerhalb von Google Analytics (ein bisschen) anonymisiert, aber der komplette Request und noch viel mehr Daten über den User gehen erstmal über den großen Teich zu Google.

    Muss ja nicht sein, dass man unnötig Daten in alle Welt schickt. Daher sollte man tatsächlich für Web Analytics auf ein selbst gehostetes System zurückgreifen wie z.B. Piwik, das ebenfalls kostenlos ist und genauso einfach in der Bedienung.

  • Kein direktes Einbinden von Social Networks

    Bindet man Social-Media-Plugins – wie z.B. den Facebook-Like-Button – so ein, wie sie standardmäßig angepriesen werden, sind sie genauer betrachtet eigentlich ein Datenschutz-Alptraum. Denn bei jedem Seitenaufruf bekommen auch Facebook, Twitter & Co. ebenfalls einen Request zugesandt, auch wenn er nicht auf „Like“ oder ähnliches geklickt hat. Ist der User bei einem der Dienste eingeloggt, kann von ihm ein Bewegungsprofil erstellt werden, da sie mitbekommen, welche Seiten er aufgerufen hat.

    Möchte man trotzdem unbedingt solche Social-Media-Controls anzeigen, sollte man dem User die Wahl lassen, ob sie direkt angezeigt werden sollen oder nicht. Man kann statt des Like-Buttons z.B. zuerst ein Bild eines deaktivierten Buttons anzeigen und erst bei Klick auf denselben den echten Like-Button laden.

    So etwas lässt sich in Javascript folgendermaßen umsetzen:

    <script type="text/javascript">
    	function activatefb(obj) {
    		obj.style.display="none";
    		document.getElementById("fb").innerHTML='<iframe src="//www.facebook.com/plugins/like.php?href=https%3A%2F%2Ftrustedserver.org&amp;send=false&amp;layout=button_count&amp;width=76&amp;show_faces=false&amp;font&amp;colorscheme=light&amp;action=like&amp;height=21" scrolling="no" frameborder="0" style="border:none; overflow:hidden; width:76px; height:21px;" allowTransparency="true"></iframe>';
    	}
    	function activategoogleplus(obj) {
    		obj.style.display="none";
    		document.getElementById("googleplus").innerHTML='<a target="_blank" href="https://plusone.google.com/_/+1/confirm?hl=de&url=https%3A%2F%2Ftrustedserver.org"><img src="/img/googleplus_active.png" /></a>';
    	}
    	function activatetwitter(obj) {
    		obj.style.display="none";
    		document.getElementById("twitter").innerHTML='<iframe allowtransparency="true" frameborder="0" scrolling="no" src="https://platform.twitter.com/widgets/tweet_button.html?url=https%3A%2F%2Ftrustedserver.org&lang=de" style="width: 73px; height: 20px;"></iframe>';
    	}
    </script>
    
    <span id="fb"><img src="/img/facebook_inactive.png" title="Anklicken, um echten Like-Button zu aktivieren" onclick="activatefb(this);" /></span>
    <span id="googleplus"><img src="/img/googleplus_inactive.png" title="Anklicken, um echten Google-Plus-One-Button zu aktivieren" onclick="activategoogleplus(this);" /></span>
    <span id="twitter"><img src="/img/twitter_inactive.png" title="Anklicken, um echten Twitter-Button zu aktivieren" onclick="activatetwitter(this);" /></span>
    

  • Zugänge zu Admin-Oberflächen schützen

    Die meisten größeren Websites haben Administrationsoberflächen, die in derselben Architektur laufen wie der Rest der Site. Diese Bereiche müssen speziell geschützt werden. Das einfachste wäre eine simple HTTP-Authentifizierung (mit .htaccess und .htpasswd), besser wäre eine Applikations-eigene.

    Oft wird vergessen, zusätzlich installierte Tools abzusichern. Gerade populäre Werkzeuge wie phpMyAdmin sind gerne Ziel von Angriffen, da relativ leicht zu prüfen ist, ob sie im Standard-Pfad installiert wurden.

  • Keine Sicherheitslücken in die Applikation einbauen

    Dieser Punkt ist sehr wichtig, denn das größte Einfallstor für Attacken ist mit Sicherheit die Applikation selbst. Hier kann man vorbeugen, indem man zunächst ein populäres Web-Framework wie z.B. Zend als Grundlage nimmt. Das bedeutet natürlich nicht automatisch, dass keine Sicherheitslücken entstehen, wenn unsachgemäß programmiert wird, aber es hilft in vielen Belangen.

    Immer wenn eine Website größere Interaktionsmöglichkeiten für den User bietet, er also z.B. Artikel verfassen darf, die dann in der Datenbank gespeichert werden, öffnen sich mehr Scheunentore für einen Angriff, da hierdurch ein indirekter Zugriff auf die Datenbank besteht. Alleine die Tatsache also, dass eingegebene Daten gespeichert werden, ist als kritisch einzustufen. Die Applikation abzusichern heisst demnach zuallererst, eingegebene Daten auf Plausibilität zu prüfen, bevor sie gespeichert werden.

    Andernfalls ermöglicht dies möglicherweise einem Angreifer, sogenannte Injections (meistens SQL-Injections), Cross-Site-Scriptings oder Cross-Site-Request-Forgeries durchzuführen. Dieses Thema ist sehr komplex, daher bitte ich bei Interesse darum, mich zu kontaktieren. Möglicherweise kann ich bei der Absicherung einer Web-Applikation persönlich helfen.

    Es gibt Tools, die die gängigsten dieser Sicherheitslücken im Rahmen von sogenannten Penetrations-Tests ausprobieren. Es werden also kontrollierte Angriffe auf die Website ausgeübt. Die Bedienung solcher Tools setzt allerdings ein tieferes Verständnis des Themas voraus, da man ansonsten mit den Resultaten wenig anfangen kann.