In einem vorherigen Beitrag sprachen wir darüber, dass Sicherheitsmaßnahmen (und Oger), wie Shrek einst sagte, wie Zwiebeln wind: Sie haben Schichten.
Heute gehen wir noch einen Schritt weiter und tauchen in die Software-Seite des Themas ein. Letztes Mal haben wir uns von der Architektur des 10. Jahrhunderts inspirieren lassen, um die mehrschichtige Verteidigung zu erklären, und da wir noch nicht genug Oger-Wortspiele haben, setzen wir diese Analogie fort.
Stellen Sie sich Ihre Webanwendung als eine Burg vor, in der sich Ihr Datenbestand wie ein Schatz befindet. Ihre Software ist das Herzstück der Burg. Es gibt viele Möglichkeiten, Ihr Gold vor Räubern zu schützen, aber nicht alle Verteidigungsmaßnahmen sind gleichwertig, und das Aufschichten von Mauern ist nicht gleichbedeutend mit echter Sicherheit.
Zurück zur Burg: Sobald wir ein verteidigungsfähiges Gelände gefunden haben, müssen wir unsere eigentliche Burg (d. h. das Kerngebäude) errichten. Jede Burg braucht hohe Mauern, Wachen, vielleicht einen Burggraben, eine Zugbrücke usw. Aber das sind nicht die einzigen Schutzschichten, die wir brauchen. Genauso wie hohe Mauern und Wachen, die das Gelände patrouillieren, nicht bedeuten, dass die Burg selbst keine Schlösser an den Türen hat, bedeuten Verteidigungsschichten in unserer Infrastruktur nicht, dass wir die Sicherheitsschichten in unserer Webanwendung ignorieren können.
All diese Ebenen arbeiten zusammen, um unsere Schätze zu schützen, aber bei der Sicherheit geht es nicht darum, einfach nur Schichten aufzustapeln. Man fügt nicht einfach mehr Schichten hinzu, denn es kommt nicht auf die Anzahl der Sicherheitsschichten an, sondern darauf, wie effektiv diese in Kombination sind.
Die Auswahl des richtigen Frameworks kann die Wahl der richtigen Schichten erleichtern. Achten Sie bei der Auswahl eines Frameworks darauf, dass Sie sich für eines entscheiden, bei dem Sicherheit an erster Stelle steht. Django ist ein solches Framework. Ich möchte nicht, dass dieser Artikel zu sehr wie eine Werbung für Django klingt, aber es gibt einen Grund, warum es die Inspiration für unser Unternehmen war.
Es verfügt über integrierte Sicherheitsfunktionen zum Schutz vor gängigen Web-Schwachstellen, was es für uns zur besten Wahl für die Entwicklung sicherer Anwendungen macht. Django fördert durch seine Architektur und Dokumentation auch sichere Praktiken.
Beispielsweise schützt Djangos ORM bei korrekter Nutzung vor SQL-Injection, und Django verfügt außerdem über weitere integrierte Sicherheitsmaßnahmen gegen Cross-Site-Scripting (XSS), Cross-Site-Request-Forgery (CSRF) und mehr. Aber genau wie bei einer Zugbrücke erfordern einige dieser Funktionen Maßnahmen Ihrerseits. Wenn Sie sie zur Vereinfachung der Entwicklung deaktivieren, ist das so, als würden Sie die Zugbrücke unten lassen; Angreifer können dann einfach hereinspazieren.
Wenn Sie sich für ein anderes Framework entscheiden, sollten Sie sich vor Beginn der Entwicklung unbedingt mit dessen Sicherheitsfunktionen vertraut machen.
Beim Erstellen einer Webanwendung verwenden Sie häufig Tools und Pakete anderer Hersteller, um die Entwicklung zu beschleunigen oder Funktionen hinzuzufügen. Dies bietet eine Angriffsfläche für sogenannte Supply-Chain-Angriffe.
Ein Supply-Chain-Angriff findet statt, wenn Hacker Abhängigkeiten von Drittanbietern kompromittieren, auf die Ihre Anwendung angewiesen ist. Stellen Sie sich beispielsweise vor, Sie verwenden ein Paket namens „Foo” und ein Angreifer schafft es, eine Hintertür darin zu installieren. Ohne dass Sie es merken, übernimmt Ihre Anwendung nun diese Schwachstelle, so als hätten Sie versehentlich die Hauptschlüssel Ihrer Burg einem als Händler getarnten Fremden übergeben.
Die wichtigste Erkenntnis? Installieren Sie nur das, was Sie wirklich brauchen, und halten Sie es auf dem neuesten Stand.
In der Softwaresicherheit lautet das Motto: Minimierung der Angriffsfläche. Jede neue Abhängigkeit, die Sie hinzufügen, ist wie eine weitere kleine Tür zu Ihrer Burg, und je mehr Türen Sie haben, desto schwieriger wird es, sie alle zu bewachen.
Das bedeutet nicht, dass Sie alles selbst neu schreiben sollten, aber Sie sollten wählerisch sein: Wählen Sie bewährte, gut gepflegte Pakete und überprüfen Sie zweimal, ob Sie die richtigen verwenden. (Denken Sie daran: Es heißt @fontawesome, nicht @fontsawesome).
Wenn das nach viel Arbeit klingt, habe ich eine gute Nachricht für Sie. Tools wie Dependabot können Ihnen die Arbeit erleichtern, indem sie automatisch Update-Pull-Requests erstellen und bekannte Schwachstellen deutlich hervorheben. Sie müssen lediglich die Änderungen überprüfen, sicherstellen, dass alles weiterhin funktioniert, und sie zusammenführen. Stellen Sie sich das wie einen treuen Verwalter vor, der Ihre Burgtore überprüft und repariert, bevor etwas Unerwünschtes durchschlüpft.
In unserem letzten Beitrag haben wir darüber gesprochen, wie eine CI/CD-Pipeline Geheimnisse offenlegen kann, aber wir wollen anmerken, dass dies auch für die Anwendung selbst gilt. Geheimnisse wie API-Schlüssel sollten niemals fest in die Anwendung einprogrammiert, sondern stattdessen als Umgebungsvariablen konfiguriert werden. Sie möchten nicht, dass sie versehentlich in Ihrem Repository landen, daher sollte dieser Schritt sehr früh im Entwicklungszyklus erfolgen.
Eine Burg kann noch so dicke Mauern und einen noch so tiefen Graben haben – wenn die Wachen jeden ohne Kontrolle hereinlassen, wird sie nicht lange standhalten. Das Gleiche gilt für Webanwendungen: Es spielt keine Rolle, wie sicher alles andere ist, wenn schlechte Benutzerverwaltung und Authentifizierungsverfahren jedem Zugriff auf Daten ermöglichen.
Beginnen wir mit Passwörtern. Wenn Ihre Benutzer weiterhin Passwörter wie „Passwort“ oder „qwertz“ verwenden können, lassen Sie die Zugbrücke offen. Erzwingen Sie starke Passwörter. Ich meine damit nicht übermäßig komplexe Passwörter mit einer Mischung aus Groß- und Kleinbuchstaben, Zahlen und Sonderzeichen, sondern etwas Besseres als „Passwort“. Das mag einige Benutzer verärgern, aber nicht so sehr wie ein Datenleck.
Sie könnten auch eine Authentifizierung durch Dritte verwenden, z. B. die Anmeldung mit Ihrem Google-Konto. Auf diese Weise ist es Googles Problem, wie sicher die Passwörter sind, aber das hat seine eigenen Probleme, z. B. was passiert, wenn Google gehackt wird?
Oder, eine radikale Idee, verzichten Sie ganz auf Passwörter. Die passwortlose Authentifizierung ist eine Methode zur Überprüfung der Identität eines Benutzers, ohne sich auf herkömmliche Passwörter oder andere wissensbasierte Geheimnisse zu verlassen. Stattdessen werden alternative Methoden wie Biometrie (Fingerabdruck, Gesichtserkennung), Einmalpasswörter (OTP) oder physische Sicherheitsschlüssel verwendet.
Mehrfaktor-Authentifizierung (MFA) ist das digitale Äquivalent dazu, Besucher sowohl nach ihrem Ausweis als auch nach einem geheimen Handzeichen zu fragen. Selbst wenn ein Angreifer die erste Ebene überwinden kann, wird er von der zweiten gestoppt.
Wie bei anderen Aspekten der Authentifizierung können Sie Ihre eigene Lösung einführen, Benutzern ein OTP senden, das nach einer bestimmten Zeit abläuft, oder etwas wie Google Authenticator verwenden. Jede Option hat ihre Vor- und Nachteile, daher sollten Sie sorgfältig abwägen.
Korrektes Session-Management und Session-Timeouts stellen sicher, dass niemand anderes die Session eines inaktiven Benutzers kapern und für böswillige Zwecke nutzen kann. Achten Sie daher darauf, dass die Timeouts für Sessions angemessen sind – sie sollten nicht zu kurz sein, damit sie die Benutzer nicht verärgern, aber auch nicht zu lang, damit sie kein Sicherheitsrisiko darstellen. Die Zeitüberschreitungen für Sitzungen sollten lang genug sein, damit ein Benutzer eine Tasse Kaffee trinken gehen kann und trotzdem noch angemeldet bleibt, aber nicht so lang, dass er in den Urlaub fahren und bei seiner Rückkehr feststellen kann, dass er immer noch angemeldet ist.
Orientieren Sie sich am Prinzip der wenigsten notwendingen Berechtigungen, d. h. gewähren Sie Benutzerkonten oder Prozessen nur die Berechtigungen, die für die Ausführung ihrer vorgesehenen Funktionen unbedingt erforderlich sind.
Zu guter Letzt sollten Sie nicht vergessen, die Zugriffsrechte der Benutzer regelmäßig zu überprüfen und zu kontrollieren. Wenn jemand vor sechs Monaten Administratorrechte erhalten hat, um „nur eine Sache zu reparieren“, und diese Rechte immer noch besitzt, oder wenn Benutzer, die das Unternehmen verlassen haben, immer noch Zugriff auf das System haben, stellt dies ein Sicherheitsrisiko dar.
Wenn Ihre Anwendung nutzbringend ist, kommuniziert sie wahrscheinlich mit einer anderen Anwendungen. Diese Kommunikation wird über eine vereinbarte Schnittstelle, auch API genannt, abgewickelt. Dies wirft jedoch die Frage auf, wie Ihre Anwendung weiß, dass sie mit der richtigen Partei kommuniziert und dass diese Partei berechtigt ist, auf die angeforderten Informationen zuzugreifen oder die gewünschten Aktionen auszuführen.
APIs sind in modernen Anwendungen unverzichtbar, aber schlecht implementierte Berechtigungssysteme können sie anfällig für Missbrauch machen. Durch Berechtigungseskalation können Angreifer unbefugten Zugriff auf sensible Daten oder Funktionen erhalten, indem sie unzureichende Sicherheitskontrollen umgehen oder missbrauchen.
Daher lautet der Ratschlag hier, sich die Zeit zu nehmen, um sicherzustellen, dass Ihre API sicher ist. Stellen Sie sicher, dass Sie über eine angemessene Authentifizierung und Autorisierung verfügen und dass alle Anfragen über verschlüsselte Verbindungen gestellt und ausgeführt werden.
Möglicherweise möchten Sie auch eine Ratenbegrenzung für Ihre API in Betracht ziehen, insbesondere wenn diese öffentlich zugänglich ist.
Im Abschnitt „Datenbank“ unseres letzten Beitrags haben wir über den Schutz von Daten in einer Datenbank gesprochen, aber dies ist nicht nur ein Problem der Datenbank. Da Ihre Webanwendung mit der Datenbank kommuniziert, müssen Sie sicherstellen, dass Hacker diese Daten nicht über Ihre Anwendung manipulieren können.
Eine häufige Art von Angriff, auf die ich mich konzentrieren möchte, ist die SQL-Injection. Bei der SQL-Injection werden Schwachstellen in Webanwendungen ausgenutzt, um bösartigen SQL-Code in Datenbankabfragen einzuschleusen. Mir ist keine passende Burg-Metapher eingefallen, daher hier eine aus Star Wars. SQL-Injection ist wie die eine Szene aus dem ersten „Krieg der Sterne“ Film, in der Obi-Wan Kenobi einen Sturmtruppler austrickst, indem er sagt: “Das sind nicht die Droiden die ihr sucht”.
Wenn Sie in einer unsicheren Webanwendung einfach alles, was der Benutzer in ein Eingabefeld eingibt, an die Datenbank senden, laufen Sie Gefahr, dass Hacker etwas wie “‘); DROP TABLE users;” schreiben. Dadurch wird Ihre erste SQL-Abfrage geschlossen und ein Löschbefehl ausgeführt. Plötzlich haben Sie eine Menge verärgerter Benutzer, die alles verloren haben.
Die Erkenntnis? Ihre Benutzereingaben sollten bereinigt werden, um dies zu verhindern. Auch hier kann die Wahl Ihres Frameworks dazu führen, dass dieses Problem leicht zu beheben ist.
Ich habe es bereits gesagt, aber es lohnt sich, es zu wiederholen: Es ist eine klar, dass es nie genug Zeit oder Budget geben wird, um alles zu tun, was Sie tun möchten. Aber Ihre Webanwendung muss dennoch sicher sein, also müssen Sie das Beste aus der Zeit und dem Budget machen, die Ihnen zur Verfügung stehen.
Beginnen Sie damit, das Bestehende zu stärken. Wenn Ihr Framework Opt-in-Funktionen hat, dann aktivieren Sie diese und konfigurieren Sie sie.
Sie können zusätzliche Sicherheitsschichten hinzufügen, aber meiner Erfahrung nach ist das nicht immer der beste Ansatz. Zusätzliche Sicherheitsschichten erhöhen auch die Komplexität Ihres Systems und können zusätzliche Schwachstellen schaffen.
Das Hinzufügen zusätzlicher Schichten hat seinen Preis, entweder in Form von Komplexität oder Kosten. Das Hinzufügen einer externen Firewall von einem namhaften Anbieter kann ein Vermögen kosten, während die Einführung einer kostenlosen Firewall Sie Zeit kostet.
XSS ist ein großes Problem in Webanwendungen, und Content Security Policy (CSP) ist die Lösung dafür. CSP schränkt ein, welche Skripte auf Ihrer Website ausgeführt werden können, d. h. Sie legen fest, welche vertrauenswürdig sind, und stellen sicher, dass Hacker nicht einfach bösartigen Code einschleusen können.
CSP hat vielen Entwicklern Kopfzerbrechen bereitet, aber es lohnt sich, es richtig zu machen. Stellen Sie sich das wie eine „Keine unbefugten Schwerter”-Richtlinie in einer Burg vor. Sie möchten, dass Ihre Wachen bewaffnet sind, aber nicht irgendwelche Leute. Eine CSP-Richtlinie, die jedem erlaubt, oder gar keine CSP-Richtlinie, ist so, als würde man jeden Hinz und Kunz mit einem Wagen voller Schwerter in die Burg lassen.
Es gibt weitere Maßnahmen, die beim Umgang mit XSS helfen können, wie z. B. das Filtern von Eingaben bei der Ankunft, das Enkodieren von Daten bei der Ausgabe und die Verwendung geeigneter Response-Header. Auch hier kann die Wahl Ihres Frameworks, wie z. B. Django, all dies erheblich vereinfachen.
Sobald Ihr System in Betrieb ist, gehen Sie nicht davon aus, dass es sicher ist und greifen Sie es stattdessen an! Äh, ich meine, testen Sie es! Beauftragen Sie Sicherheitsexperten oder verwenden Sie automatisierte Tools, tun Sie alles, um Schwachstellen zu finden, bevor echte Angreifer dies tun.
Überprüfen Sie das System auf häufige Schwachstellen wie SQL-Injection, Brute-Force-Angriffe und Session-Hijacking. Versuchen Sie, sich mit schwachen Anmeldedaten anzumelden, oder versuchen Sie, vergessene Administratorkonten auszunutzen, um zu sehen, ob sensible Daten offengelegt werden. Wenn Sie sich Zugang verschaffen können, kann das auch jemand mit bösen Absichten.
Die wichtigste Erkenntnis ist einfach: Webanwendungen, genau wie Oger, haben verschiedene Schichten. Und jede dieser Schichten kann zu einer Hintertür werden, wenn sie nicht richtig geschützt ist.
Sicherheitslücken treten selten isoliert auf, sondern erstrecken sich oft über mehrere Schichten. Ihr Hauptziel sollte es sein, sicherzustellen, dass bei einem Ausfall einer Schicht eine andere die Bedrohung abfängt. Wenn Ihr Frontend einen Angriff nicht erkennt, sollte Ihr Backend ihn stoppen.
Dadurch wird Ihre Webanwendung von einer Anwendung mit mehreren Schichten von Sicherheitslücken zu einer Anwendung mit mehreren Schichten von Schutzmechanismen.