CSP: Umwandlung von Inline / Internal CSS, JS und DATA in externe Ressourcen

From
Jump to navigation Jump to search

Dieses Projekt ist eine Aufgabe des Moduls IT-Security-Workshop.

"CSP Extract Inline Resources" ist ein Tool, das den Prozess der Transformation von HTML-Dateien automatisiert, indem es eingebettete Ressourcen wie CSS, JavaScript und Daten in separate externe Dateien auslagert. Dadurch wird die Kompatibilität mit strikten Content Security Policies (CSP) gewährleistet, die „unsafe-inline“-Inhalte verbieten, wodurch die Sicherheit verbessert und das HTML korrekt in Umgebungen gerendert werden kann, in denen eingebettete Ressourcen blockiert sind.

Theorie

Motivation

Dieses Projekt ist eine Aufgabe des IT-Security-Workshop-Moduls.

In einigen Fällen ist es notwendig, Daten im HTML-Format zu generieren, damit sie im Browser angezeigt werden können. Aus Sicherheitsgründen implementieren viele Webserver jedoch eine Content Security Policy (CSP), um Angriffe wie Cross-Site Scripting (XSS) zu verhindern. Eine häufige Einschränkung ist das Verbot von „unsafe-inline“-Inhalten, was dazu führen kann, dass der Browser eingebettetes JavaScript und Styles aufgrund der CSP-Header ignoriert.

Dieses Projekt zielt darauf ab, den Prozess der Auslagerung von eingebetteten Ressourcen in externe Dateien zu automatisieren, damit der HTML-Inhalt weiterhin funktional bleibt und gleichzeitig die CSP-Anforderungen erfüllt.

Funktionen

  • Extrahiert eingebettetes CSS, JavaScript und andere Daten aus einer HTML-Datei
  • Speichert die extrahierten Ressourcen als externe Dateien
  • Aktualisiert die HTML-Datei, um externe Ressourcen zu verlinken

Das Tool

Das gesamte Projekt ist in Github zu finden.

Content Security Policy (CSP)

CSP ist eine Web-Sicherheitsrichtlinie, die dazu dient, potenzielle Angriffe zu verhindern, indem sie dem Browser genaue Anweisungen gibt, welche Inhalte von welchen Quellen geladen werden dürfen. CSP reduziert das Risiko von Angriffen wie Cross-Site-Scripting (XSS), Daten-Injektion und anderen Arten von Code-Injection-Angriffen.
Es wird durch den HTTP-Response-Header eingebunden, der vom Server zum Client (Browser) Informationen sendet. Das ganze ist auch über ein Meta Tag im <Head> der HTML Datei möglich, aber sollte eher als zweite Wahl verwendet werden, falls der HTTP Header nicht gesetzt werden kann. Der Meta Tag Ansatz unterstützt nicht alle Funktionen.

Beispiele:

Erlaube alles, aber nur aus derselben Quelle: Content-Security-Policy: default-src 'self';

Erlaube nur Skripte aus derselben Quelle: Content-Security-Policy: script-src 'self';

Definiert gültige Quellen für Plugins, z.B. <object>, <embed> oder <applet>: Content-Security-Policy: object-src 'self';

Cross-Site Scripting (XSS)

Cross-Site Scripting (XSS)-Angriffe sind eine Art von Injektion, bei der schädliche Skripte in vertrauenswürdige Websites eingeschleust werden. Diese Angriffe nutzen Sicherheitslücken aus, um bösartigen Code einzuschleusen, der dann von anderen Besuchern der Website ausgeführt wird.

Arten von XSS

Reflected XSS (Non-Persistent oder Type I)

Diese Art von XSS tritt auf, wenn der schädliche Code über eine URL oder Formulareingabe an den Server gesendet und direkt in die Antwort eingebettet wird, ohne dass er auf dem Server gespeichert wird.

  • Blind Cross-Site Scripting: Ein Sonderfall von Reflected XSS, bei dem der Angreifer keine direkte Rückmeldung erhält, ob der Angriff erfolgreich war.
Stored XSS (Persistent oder Type II)

Bei Stored XSS wird der schädliche Code dauerhaft auf dem Server gespeichert und an alle Benutzer der Website ausgeliefert, sobald sie die entsprechende Seite besuchen.

DOM-Based XSS (Type-0)

DOM-Based XSS tritt auf, wenn der schädliche Code durch Manipulation des Document Object Models (DOM) der Website im Browser ausgeführt wird, ohne dass eine Server-Kommunikation nötig ist.

Kategorien von XSS

Es ist nicht ganz richtig, dass es sich bei diesen (Stored, Reflected, DOM) um drei strikt getrennte Arten von XSS handelt, da sie in der Praxis oft ineinander übergehen. So gibt es sowohl gespeicherte als auch reflektierte DOM-basierte XSS. Auch nicht-DOM-basierte Varianten von gespeicherten und reflektierten XSS sind möglich, was die Unterscheidung erschwert. Um diese Unklarheiten zu beseitigen, führte die Forschungsgemeinschaft ab Mitte 2012 zwei neue Begriffe ein, um die verschiedenen XSS-Typen besser zu strukturieren.

Server XSS

Bei Server XSS wird der schädliche Code durch die Kommunikation mit dem Server injiziert und an die Endnutzer zurückgesendet.

Client XSS

Client XSS findet ausschließlich im Browser des Nutzers statt, indem das DOM der Website verändert wird, ohne dass der Server involviert ist.

Quellen

Praxis

Voraussetzungen

Stellen Sie sicher, dass die folgenden Programme auf Ihrem System installiert sind, bevor Sie beginnen:

  1. Python (neueste Version): Dieses Projekt erfordert die neueste Version von Python 3.x. Sie können Python von der offiziellen Website herunterladen und installieren: https://www.python.org/downloads/.
    1. Um zu überprüfen, ob Python installiert ist und die Version anzuzeigen, können Sie den folgenden Befehl im Terminal oder in der Eingabeaufforderung ausführen:
      python --version
  2. pip: pip ist der Python-Paketinstaller und wird normalerweise standardmäßig mit Python geliefert.
    1. Um zu überprüfen, ob pip installiert ist, führen Sie aus:
      pip --version
    2. Falls pip nicht installiert ist, können Sie es gemäß den Anweisungen hier installieren: https://pip.pypa.io/en/stable/installation/
  3. venv-Modul: Stellen Sie sicher, dass das venv-Modul installiert ist. Dieses Modul ist standardmäßig in Python 3.x enthalten.
    1. Sie können die Verfügbarkeit durch Ausführen des folgenden Befehls überprüfen:
      python -m venv --help
  4. Erstellen und Aktivieren einer virtuellen Umgebung: Sobald Python und venv verfügbar sind, sollten Sie eine virtuelle Umgebung für das Projekt erstellen und aktivieren. Dies stellt sicher, dass alle Abhängigkeiten in einer isolierten Umgebung installiert werden.
    1. Um die virtuelle Umgebung zu erstellen und zu aktivieren:
      Unter Unix/macOS:
      python -m venv .venv
      source .venv/bin/activate
      Unter Windows:
      python -m venv .venv
      .venv\Scripts\activate

Nach der Aktivierung der virtuellen Umgebung ändert sich Ihr Terminal-Prompt, was anzeigt, dass die virtuelle Umgebung aktiv ist. Von hier aus können Sie mit der Installation der Projektabhängigkeiten fortfahren.

Installation

Nachdem die Voraussetzungen erfüllt sind, können Sie die Projektabhängigkeiten mit dem folgenden Befehl installieren:
pip install -r requirements.txt

Verwendung

Programm ausführen

Um das Programm mit einer bestimmten HTML-Datei auszuführen, verwenden Sie den folgenden Befehl:
python csp_extractor/main.py index.html

Binary erstellen

Sie können auch ein eigenständiges Binary für Ihr System mit PyInstaller erstellen.

Um das Binary zu erstellen, führen Sie aus:
pyinstaller --onefile csp_extractor/main.py

Das generierte Binary befindet sich im Verzeichnis dist/.

Projektstruktur

   .dockerignore
│   .gitignore
│   LICENSE
│   main.spec
│   README.md
│   requirements.txt
│   tree.txt
│   
├───.docker
│      Dockerfile
│         ├───apache
│          Dockerfile
│             └───bin
│           Dockerfile
├───apache
│       apache-config.conf
│       
├───bin
│       csp_extractor_linux_x64
│       csp_extractor_win_x64.exe
│       
├───csp_extractor
│       css_extractor.py
│       data_extractor.py
│       extractor.py
│       js_extractor.py
│       main.py
│       __init__.py
│           
├───doc
│       Specificity.md
│       
├───tests
│       Das sollte jetzt rot sein!.htm
│       index.html
│       InternalInline.html
│       test_main.py
│       
└───www_dist
       index.html
       index.js
       main.css
       
    └───img
            wolf-emblem.svg

Verzeichnisübersicht

  • .docker/: Enthält Docker-Konfigurationen und Skripte für das Apache-Setup und den Build-Prozess.
    • apache/: Konfigurationen für den Apache-Webserver.
    • bin/: Skripte und Konfigurationen für das Erstellen des Binaries.
  • apache/: Stellt alle notwendigen Konfigurationen und Dateien für den Apache-Webserver bereit.
  • bin/: Enthält das erstellte Binary nach dem Build-Prozess.
  • csp_extractor/: Der Hauptcode des Projekts, der für die Extraktion von Inline-Ressourcen verantwortlich ist.
  • doc/: Dokumentationsdateien des Projekts.
  • tests/: Enthält die Testfälle und HTML-Dateien, die zur Validierung der Extraktionslogik verwendet werden.
  • www_dist/: In diesem Ordner werden die extrahierten Dateien abgelegt, nachdem sie aus den HTML-Dateien entfernt wurden.

Wichtige Dateien:

  • requirements.txt: Liste der benötigten Python-Abhängigkeiten.
  • README.md: Detaillierte Projektbeschreibung und Installationsanweisungen.

Dateien im Verzeichnis csp_extractor

  • css_extractor.py: Diese Datei enthält die Logik zur Extraktion von Inline-CSS aus HTML-Dateien. Sie identifiziert alle eingebetteten <style>-Tags und Inline-CSS-Regeln und extrahiert sie in externe .css-Dateien.
  • data_extractor.py: Diese Datei ist für die Extraktion von Daten (z.B. Inline-Bilder wie <img> oder andere eingebettete Datenstrukturen) aus HTML-Dateien verantwortlich. Es speichert die extrahierten Daten in separaten Dateien unter www_dist/img/.
  • extractor.py: Der Haupt-Extraktor, der die Prozesse der verschiedenen spezialisierten Extraktoren (CSS, JS, Daten) koordiniert. Diese Datei orchestriert die Extraktion und Verarbeitung aller Ressourcen in einer HTML-Datei.
  • js_extractor.py: Diese Datei enthält die Logik zur Extraktion von Inline-JavaScript. Sie identifiziert alle <script>-Tags, die Inline-JavaScript enthalten, und verschiebt deren Inhalte in externe .js-Dateien.
  • main.py: Das Hauptprogramm, das die Anwendung startet. Es verarbeitet die Eingabe-HTML-Datei, führt die Extraktionsprozesse durch und speichert die resultierenden HTML- und Ressourcen-Dateien im angegebenen Verzeichnis.
  • __init__.py: Diese Datei macht das Verzeichnis csp_extractor zu einem Python-Paket. Sie ermöglicht es, dass andere Teile des Programms dieses Verzeichnis als Modul importieren können.

Code Notes


In diesem Projekt haben wir das Pyton Package Beautiful Soup (BS) verwendet. BS ist eine Python-Bibliothek zur Analyse von HTML- und XML-Dokumenten. Sie erleichtert das Extrahieren von Daten aus Webseiten und ermöglicht es, die Struktur des Dokuments effizient zu durchsuchen und zu modifizieren. BS arbeitet oft in Kombination mit Bibliotheken wie requests, um HTML-Seiten herunterzuladen und dann weiterzuverarbeiten.

Die Bibliothek wandelt das HTML-Dokument in einen Baum von Python-Objekten um, der leicht zu navigieren ist. Sie bietet Methoden zum Suchen von Tags, zum Durchlaufen des DOM-Baums und zum Ändern der Inhalte. So können zum Beispiel Elemente anhand ihrer Tags, Klassen oder IDs gefunden und gezielt Daten extrahieren werden.

Beispiele:

from bs4 import BeautifulSoup
import requests

# HTML-Seite herunterladen
url = 'https://example.com'
response = requests.get(url)
soup = BeautifulSoup(response.content, 'html.parser')

# Finden aller Links auf der Seite
for link in soup.find_all('a'):
    print(link.get('href'))
from bs4 import BeautifulSoup

# Lokale HTML-Datei öffnen
with open("beispiel.html", "r", encoding="utf-8") as file:
    content = file.read()

# Beautiful Soup verwenden, um den HTML-Inhalt zu parsen
soup = BeautifulSoup(content, 'html.parser')

# Finden und Ausgeben aller Style-Tags
for tag in soup.find_all('style'):
    print(tag.string)

# Den Titel der Seite ausgeben
title = soup.title.string
print("Seitentitel:", title)

Weitere Info

Das README.md im Projektverzeichnis enthält eine Anleitung zum Starten des Projekts mit Docker sowie eine Beschreibung weiterer hilfreicher Befehle, die die Entwicklung effizienter machen. Für eine detaillierte Erklärung lesen Sie bitte das README.md im Projektordner.