Dieser Inhalt wurde automatisch aus dem Englischen übersetzt, und kann Fehler enthalten. Erfahre mehr über dieses Experiment.

View in English Always switch to English

Sicherheit von Django-Webanwendungen

Der Schutz von Benutzerdaten ist ein wesentlicher Bestandteil jedes Website-Designs. Wir haben zuvor einige der häufigsten Sicherheitsbedrohungen im Artikel Web-Sicherheit erklärt – dieser Artikel liefert eine praktische Demonstration, wie Djangos eingebaute Schutzmechanismen mit solchen Bedrohungen umgehen.

Voraussetzungen: Lesen Sie das Thema "Website-Sicherheit" zur serverseitigen Programmierung. Schließen Sie die Django-Tutorial-Themen bis (und inklusive) mindestens Django Tutorial Teil 9: Arbeiten mit Formularen ab.
Ziel: Ein Verständnis dafür entwickeln, was Sie tun müssen (oder nicht tun sollten), um Ihre Django-Webanwendung zu sichern.

Überblick

Das Thema Website-Sicherheit bietet einen Überblick darüber, was Website-Sicherheit für das serverseitige Design bedeutet und welche häufigen Bedrohungen es abzuwehren gilt. Eine der wichtigsten Botschaften in diesem Artikel ist, dass fast alle Angriffe erfolgreich sind, wenn die Webanwendung den Daten des Browsers vertraut.

Warnung: Die wichtigste Lektion, die Sie bezüglich Website-Sicherheit lernen können, ist, niemals Daten vom Browser zu vertrauen. Dazu gehören GET-Anfragedaten in URL-Parametern, POST-Daten, HTTP-Header und Cookies, vom Benutzer hochgeladene Dateien usw. Überprüfen und bereinigen Sie immer alle eingehenden Daten. Gehen Sie immer vom schlimmsten Fall aus.

Die gute Nachricht für Django-Benutzer ist, dass viele der häufigeren Bedrohungen bereits durch das Framework abgedeckt sind! Der Artikel Sicherheit in Django (Django-Dokumentation) erklärt Djangos Sicherheitsfunktionen und wie man eine von Django betriebene Website sichert.

Häufige Bedrohungen/Schutzmechanismen

Anstatt die Django-Dokumentation hier zu wiederholen, demonstrieren wir in diesem Artikel nur einige der Sicherheitsfunktionen im Kontext unseres Django-Tutorials LokaleBibliothek.

Cross-Site Scripting (XSS)

XSS ist ein Begriff zur Beschreibung einer Klasse von Angriffen, die es einem Angreifer ermöglichen, clientseitige Skripte über die Website in die Browser anderer Benutzer einzuschleusen. Dies wird normalerweise erreicht, indem bösartige Skripte in der Datenbank gespeichert werden, von wo aus sie abgerufen und anderen Benutzern angezeigt werden können, oder indem Benutzer dazu gebracht werden, auf einen Link zu klicken, der das JavaScript des Angreifers im Browser des Benutzers ausführt.

Djangos Template-System schützt Sie vor den meisten XSS-Angriffen, indem es bestimmte Zeichen entwertet, die in HTML "gefährlich" sind. Wir können dies demonstrieren, indem wir versuchen, etwas JavaScript in unsere LokaleBibliothek-Website über das erstellte Formular für Autoren einzuschleusen, das wir in Django Tutorial Part 9: Arbeiten mit Formularen eingerichtet haben.

  1. Starten Sie die Website mit dem Entwicklungsserver (python3 manage.py runserver).

  2. Öffnen Sie die Seite in Ihrem lokalen Browser und melden Sie sich bei Ihrem Superuser-Konto an.

  3. Navigieren Sie zur Autor-Erstellungsseite (die sich unter der URL http://127.0.0.1:8000/catalog/author/create/ befinden sollte).

  4. Geben Sie Namen und Datum für einen neuen Benutzer ein und fügen Sie dann dem Feld Nachname den folgenden Text hinzu: <script>alert('Test alert');</script>. Author Form XSS test

    Hinweis: Dies ist ein harmloses Skript, das, wenn es ausgeführt wird, ein Warnfeld in Ihrem Browser anzeigt. Wenn die Warnung beim Absenden des Datensatzes angezeigt wird, ist die Seite anfällig für XSS-Bedrohungen.

  5. Drücken Sie Absenden, um den Datensatz zu speichern.

  6. Wenn Sie den Autor speichern, wird der Datensatz wie unten angezeigt. Aufgrund der XSS-Schutzmechanismen sollte das alert() nicht ausgeführt werden. Stattdessen wird das Skript als einfacher Text angezeigt. Author detail view XSS test

Wenn Sie den Quellcode der Seite anzeigen, können Sie sehen, dass die gefährlichen Zeichen für die Skript-Tags in ihre harmlosen Escape-Code-Äquivalente umgewandelt wurden (zum Beispiel wird aus > nun &gt;).

html
<h1>
  Author: Boon&lt;script&gt;alert(&#39;Test alert&#39;);&lt;/script&gt;, David
  (Boonie)
</h1>

Die Verwendung von Django-Templates schützt Sie vor den meisten XSS-Angriffen. Es ist jedoch möglich, diesen Schutz zu deaktivieren, und der Schutz wird nicht automatisch auf alle Tags angewendet, die normalerweise nicht durch Benutzereingaben gefüllt werden (zum Beispiel wird help_text in einem Formularfeld normalerweise nicht vom Benutzer bereitgestellt, daher entwertet Django diese Werte nicht).

Es ist auch möglich, dass XSS-Angriffe von anderen nicht vertrauenswürdigen Datenquellen ausgehen, wie z.B. Cookies, Webdiensten oder hochgeladenen Dateien (wann immer die Daten nicht ausreichend bereinigt werden, bevor sie in eine Seite eingebunden werden). Wenn Sie Daten aus diesen Quellen anzeigen, müssen Sie möglicherweise ihren eigenen Bereinigungscode hinzufügen.

Schutz vor Cross-Site Request Forgery (CSRF)

CSRF-Angriffe ermöglichen es einem böswilligen Benutzer, Aktionen unter Verwendung der Anmeldeinformationen eines anderen Benutzers ohne dessen Wissen oder Zustimmung auszuführen. Beispielsweise stellen Sie sich den Fall vor, in dem wir einen Hacker haben, der zusätzliche Autoren für unsere LokaleBibliothek erstellen möchte.

Hinweis: Offensichtlich ist unser Hacker nicht im Geldgeschäft! Ein ehrgeizigerer Hacker könnte denselben Ansatz auf anderen Websites verwenden, um wesentlich schädlichere Aufgaben durchzuführen (z. B. Geld auf ihre eigenen Konten überweisen usw.)

Um dies zu tun, könnte er eine HTML-Datei wie die unten stehende erstellen, die ein Autoren-Erstellungsformular enthält (wie das, das wir im vorherigen Abschnitt verwendet haben), das eingereicht wird, sobald die Datei geladen ist. Er könnte die Datei dann an alle Bibliothekare senden und vorschlagen, dass sie die Datei öffnen (sie enthält einige harmlose Informationen, ehrlich!). Wenn die Datei von einem angemeldeten Bibliothekar geöffnet würde, dann würde das Formular mit ihren Anmeldeinformationen eingereicht und ein neuer Autor würde erstellt.

html
<html lang="en">
  <body onload="document.EvilForm.submit()">
    <form
      action="http://127.0.0.1:8000/catalog/author/create/"
      method="post"
      name="EvilForm">
      <label for="id_first_name">First name:</label>
      <input
        id="id_first_name"
        maxlength="100"
        name="first_name"
        type="text"
        value="Mad"
        required />
      <label for="id_last_name">Last name:</label>
      <input
        id="id_last_name"
        maxlength="100"
        name="last_name"
        type="text"
        value="Man"
        required />
      <label for="id_date_of_birth">Date of birth:</label>
      <input id="id_date_of_birth" name="date_of_birth" type="text" />
      <label for="id_date_of_death">Died:</label>
      <input
        id="id_date_of_death"
        name="date_of_death"
        type="text"
        value="12/10/2016" />
      <input type="submit" value="Submit" />
    </form>
  </body>
</html>

Führen Sie den Entwicklungs-Webserver aus und melden Sie sich mit Ihrem Superuser-Konto an. Kopieren Sie den obigen Text in eine Datei und öffnen Sie diese dann im Browser. Sie sollten einen CSRF-Fehler erhalten, da Django einen Schutz gegen diese Art von Angriff bietet!

Der Schutz wird dadurch aktiviert, dass Sie das {% csrf_token %}-Template-Tag in Ihr Formular einfügen. Dieses Token wird dann in Ihrem HTML gerendert, wie unten gezeigt, mit einem Wert, der spezifisch für den Benutzer im aktuellen Browser ist.

html
<input
  type="hidden"
  name="csrfmiddlewaretoken"
  value="0QRWHnYVg776y2l66mcvZqp8alrv4lb8S8lZ4ZJUWGZFA5VHrVfL2mpH29YZ39PW" />

Django generiert einen benutzer-/browserspezifischen Schlüssel und lehnt Formulare ab, die das Feld nicht enthalten oder die ein falsches Feldwert für den Benutzer/Browser enthalten.

Um diese Art von Angriff zu verwenden, muss der Hacker nun den CSRF-Schlüssel für den spezifischen Zielbenutzer herausfinden und einfügen. Sie können auch nicht den "Streuschuss"-Ansatz verwenden, bei dem eine bösartige Datei an alle Bibliothekare gesendet wird und darauf gehofft wird, dass einer von ihnen sie öffnet, da der CSRF-Schlüssel browserspezifisch ist.

Djangos CSRF-Schutz ist standardmäßig aktiviert. Sie sollten immer das {% csrf_token %}-Template-Tag in Ihren Formularen verwenden und POST für Anfragen nutzen, die Daten in der Datenbank ändern oder hinzufügen könnten.

Weitere Schutzmechanismen

Django bietet auch andere Formen des Schutzes an (die meistens schwer oder nicht besonders nützlich zu demonstrieren wären):

Schutz vor SQL-Injection

Schwachstellen bei SQL-Injections ermöglichen es böswilligen Benutzern, beliebigen SQL-Code auf einer Datenbank auszuführen, sodass Daten unabhängig von den Berechtigungen des Nutzers zugegriffen, modifiziert oder gelöscht werden können. In fast allen Fällen greifen Sie mit Djangos Querysets/Models auf die Datenbank zu, sodass der resultierende SQL korrekt durch den zugrunde liegenden Datenbanktreiber entwertet wird. Wenn Sie rohe Abfragen oder benutzerdefinierte SQL schreiben müssen, benötigen Sie ein explizites Vorgehen zur Verhinderung von SQL-Injection.

Schutz vor Clickjacking

Bei diesem Angriff entführt ein böswilliger Benutzer Klicks, die für eine sichtbare oberste Website bestimmt sind, und leitet sie an eine darunter verborgene Seite weiter. Diese Technik könnte zum Beispiel verwendet werden, um eine legitime Bank-Website anzuzeigen, aber die Anmeldeinformationen in einem unsichtbaren <iframe> zu erfassen, das vom Angreifer kontrolliert wird. Django enthält Schutz vor Clickjacking in Form des X-Frame-Options-Middleware, das in einem unterstützenden Browser verhindern kann, dass eine Website innerhalb eines Rahmens gerendert wird.

Erzwingung von TLS/HTTPS

TLS/HTTPS kann auf dem Webserver aktiviert werden, um den gesamten Datenverkehr zwischen der Website und dem Browser zu verschlüsseln, einschließlich Authentifizierungsinformationen, die sonst im Klartext gesendet würden (es wird dringend empfohlen, HTTPS zu aktivieren). Wenn HTTPS aktiviert ist, bietet Django eine Reihe anderer Schutzmaßnahmen, die Sie verwenden können:

  • SECURE_PROXY_SSL_HEADER kann verwendet werden, um zu überprüfen, ob Inhalte sicher sind, selbst wenn sie von einem Nicht-HTTP-Proxy eingehen.
  • SECURE_SSL_REDIRECT wird verwendet, um alle HTTP-Anfragen auf HTTPS umzuleiten.
  • Verwenden Sie HTTP Strict Transport Security (HSTS). Dies ist ein HTTP-Header, der einen Browser darüber informiert, dass alle zukünftigen Verbindungen zu einer bestimmten Website immer HTTPS verwenden sollten. Kombiniert mit der Umleitung von HTTP auf HTTPS stellt diese Einstellung sicher, dass HTTPS immer nach einer erfolgreichen Verbindung verwendet wird. HSTS kann entweder mit SECURE_HSTS_SECONDS und SECURE_HSTS_INCLUDE_SUBDOMAINS oder auf dem Webserver konfiguriert werden.
  • Verwenden Sie ‚sichere‘ Cookies, indem Sie SESSION_COOKIE_SECURE und CSRF_COOKIE_SECURE auf True setzen. Dadurch wird sichergestellt, dass Cookies nur über HTTPS gesendet werden.
Host-Header-Validierung

Verwenden Sie ALLOWED_HOSTS, um nur Anfragen von vertrauenswürdigen Hosts zu akzeptieren.

Es gibt viele weitere Schutzmaßnahmen und Vorbehalte zur Verwendung der oben genannten Mechanismen. Während wir hoffen, dass dieser Artikel Ihnen einen Überblick darüber gegeben hat, was Django bietet, sollten Sie dennoch die Django-Sicherheitsdokumentation lesen.

Zusammenfassung

Django bietet effektive Schutzmaßnahmen gegen eine Reihe von häufigen Bedrohungen, einschließlich XSS- und CSRF-Angriffen. In diesem Artikel haben wir gezeigt, wie Django diese besonderen Bedrohungen in unserer LokaleBibliothek-Website behandelt. Wir haben auch einen kurzen Überblick über einige der anderen Schutzmaßnahmen gegeben.

Dies war ein sehr kurzer Ausflug in die Web-Sicherheit. Wir empfehlen Ihnen dringend, Sicherheit in Django zu lesen, um ein tieferes Verständnis zu erlangen.

Der nächste und letzte Schritt in diesem Modul über Django besteht darin, die Assessment-Aufgabe abzuschließen.

Siehe auch