Teilen über


Richtlinie für Inhaltssicherheit

Die Inhaltssicherheitsrichtlinie (Content Security Policy , CSP) wird derzeit in modellgesteuerten Apps und Canvas-Apps unterstützt. Administratoren können steuern, ob der CSP-Header gesendet wird, und in gewissem Umfang, was er enthält. Die Einstellungen befinden sich auf Umgebungsebene, was bedeutet, dass sie auf alle Apps in der Umgebung angewendet werden, sobald sie aktiviert sind.

Notiz

Die Richtlinie für Inhaltssicherheit gilt nur für Umgebungen, die Dataverse verwenden.

Jede Komponente des CSP-Headerwerts steuert die Ressourcen, die heruntergeladen werden können. Das Mozilla Developer Network (MDN) enthält ausführlichere Beschreibungen. Die Standardwerte sind wie folgt:

Richtlinie Standardwert Anpassbar
script-src * 'unsafe-inline' 'unsafe-eval' blob: data: Nein
worker-src 'self' blob: data: Nein
style-src * 'unsafe-inline' Nein
font-src * data: Nein
frame-ancestors 'self' https://*.powerapps.com Ja

Diese Konfiguration resultiert in einem Standard-CSP von script-src * 'unsafe-inline' 'unsafe-eval' blob: data:; worker-src 'self' blob: data:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'self' https://*.powerapps.com;.

Strenger Modus

Der Umschalter "Strict CSP" erstellt einen CSP, der hauptsächlich keine Wildcards oder unsicheren Direktiven enthält, wie z. B. unsafe-inline. Wenn Sie "Strict CSP" aktivieren, werden die vorstehenden Direktiven zu den folgenden Richtlinien, die in diesem Abschnitt beschrieben sind. Die <platform> Notation bedeutet, dass Plattformdomänen gemäß den Anforderungen des Produkts bereitgestellt werden. Die Domänen in diesem Abschnitt können sich im Laufe der Zeit ändern, wenn das Produkt wächst.

Richtlinie Standardwert (modellgesteuert) Standardwert (Canvas) Anpassbar
script-src 'self' blob: data: <platform>' 'self' <platform>' Ja
worker-src 'self' blob: data: 'self' blob: Nein
style-src 'self' 'unsafe-inline' <platform> 'self' 'unsafe-inline' <platform> Ja
font-src 'self' data: <platform> 'self' data: <platform> Ja
frame-ancestors 'self' https://*.powerapps.com 'self' https://*.powerapps.com Ja
img-src 'self' blob: data: <platform> 'self' data: <platform> Ja
connect-src 'self' blob: data: wss: <platform> 'self' blob: <platform> Ja
frame-src 'self' blob: <platform> 'self' <platform> Ja
base-uri 'none' N/A Nein
`Form-Action` <platform> N/A Ja
default-src 'self' 'self' Nein

Voraussetzungen

Für Dynamics 365 Customer Engagement-Apps und andere modellgesteuerte Apps ist CSP nur in Onlineumgebungen und in Organisationen mit Dynamics 365 Customer Engagement (on-premises) ab Version 9.1 verfügbar.

CSP Konfigurieren

Sie können CSP über das Power Platform Admin Center bereitstellen und umschalten. Es ist wichtig, zuerst eine Entwicklungs-/Testumgebung zu aktivieren, da die Aktivierung des CSP Szenarien blockieren könnte, wenn gegen die Richtlinie verstoßen wird. Das Admin Center unterstützt auch einen Modus nur für Berichte , um eine einfachere Einführung in der Produktion zu ermöglichen.

Führen Sie die folgenden Schritte aus, um CSP zu konfigurieren:

  1. Melden Sie sich beim Power Platform Admin Center an.
  2. Wählen Sie im Navigationsbereich die Option Verwalten aus. Wählen Sie im Bereich VerwaltenUmgebungen aus.
  3. Wählen Sie auf der Seite Umgebungen eine Umgebung aus.
  4. Wählen Sie in der Befehlsleiste Einstellungen aus.
  5. Erweitern Sie Produkt und wählen Sie dann Datenschutz und Sicherheit aus.

Das folgende Bild zeigt den Standardstatus der Einstellungen:

Standardeinstellungen der Richtlinie für Inhaltssicherheit.

Berichterstellung

Der Schalter Berichterstellung aktivieren steuert, ob Modellgesteuerte und Canvas-Apps Verstoßberichte senden. Geben Sie einen Endpunkt an, um ihn zu aktivieren. Die App sendet Verletzungsberichte an diesen Endpunkt, unabhängig davon, ob CSP erzwungen wird oder nicht. Wenn CSP nicht erzwungen wird, verwendet die App den Nur-Bericht-Modus. Weitere Informationen finden Sie in der Dokumentation zur Berichterstellung.

Stellen Sie den Schalter für die Berichterstellung auf „Ein“.

Durchsetzung

Die Durchsetzung von CSP wird für Modellgesteuerte und Canvas-Apps unabhängig gesteuert, um eine granulare Kontrolle über Richtlinien zu ermöglichen. Verwenden Sie die Modellgesteuerte/Canvas-Navigationssteuerung, um den beabsichtigten App-Typ zu ändern.

Die Umschaltfläche " Inhaltssicherheitsrichtlinie erzwingen " aktiviert die Standardrichtlinie für die Erzwingung für den jeweiligen App-Typ. Durch Aktivieren dieses Schalters wird das Verhalten von Apps in dieser Umgebung geändert, um die Richtlinie einzuhalten. Folgen Sie daher diesem vorgeschlagenen Aktivierungsfluss:

  1. Erzwingen Sie die Richtlinie für eine Entwicklungs- oder Testumgebung.
  2. Nur-Bericht-Modus in der Produktion aktivieren.
  3. Erzwingen Sie die Richtlinie in der Produktion, sobald keine Verstöße gemeldet werden.

Richtlinien konfigurieren

Im Abschnitt " Richtlinien konfigurieren" können Sie einzelne Direktiven innerhalb der Richtlinie steuern. Derzeit können Sie die frame-ancestors Direktive nur anpassen.

Konfigurieren Sie die CSP-Richtlinien.

Wenn Sie die Standarddirektive aktiviert lassen, verwenden Sie den in der Tabelle angegebenen Standardwert. Wenn Sie die Umschaltfläche deaktivieren, können Sie benutzerdefinierte Werte für die Direktive angeben und an den Standardwert anfügen. Im folgenden Beispiel werden benutzerdefinierte Werte für frame-ancestors. Die Direktive ist auf frame-ancestors: 'self' https://*.powerapps.com https://www.foo.com https://www.bar.com in diesem Beispiel festgelegt. Diese Einstellung bedeutet, dass die App im selben Ursprung, https://*.powerapps.com, https://www.foo.com und https://www.bar.com gehostet werden kann, aber nicht in anderen Ursprüngen. Verwenden Sie die Schaltfläche Hinzufügen, um Einträge zur Liste hinzuzufügen, und das Symbol Löschen, um sie zu entfernen.

Legen Sie benutzerdefinierte CSP-Richtlinien fest.

Häufige Konfigurationen

Für die Microsoft Teams Integration mit der Dynamics 365-App fügen Sie Folgendes zu frame-ancestors hinzu:

  • https://teams.microsoft.com/
  • https://teams.cloud.microsoft/
  • https://msteamstabintegration.dynamics.com/

Fügen Sie bei Dynamics 365 App for Outlook zu frame-ancestors Folgendes hinzu:

  • Der Ursprung Ihrer Outlook Web App-Startseite
  • https://outlook.office.com
  • https://outlook.office365.com

Um Power Apps in Power BI-Berichte einzubetten, fügen Sie Folgendes zu frame-ancestors hinzu:

  • https://app.powerbi.com
  • https://ms-pbi.pbi.microsoft.com

Wichtige Überlegungen

Deaktivieren der Standarddirektive und Speichern mit einer leeren Liste deaktiviert die Direktive komplett und sendet sie nicht als Teil des CSP-Antwortheaders.

CSPBeispielkonfigurationen

Hier sind ein paar Beispiele für CSP-Konfigurationen.

Beispiel 1 – Berichterstellung deaktiviert

CSP-Beispiel 1

Im obigen Beispiel:

  • Die Berichterstellung ist deaktiviert.
  • Die Modellgesteuerte Erzwingung ist aktiviert.
    • frame-ancestors ist angepasst an https://www.foo.com und https://www.bar.com.
  • Canvas-Erzwingung ist deaktiviert.

Die effektiven Kopfzeilen sind:

  • Modellgesteuerte Apps: Content-Security-Policy: script-src * 'unsafe-inline' 'unsafe-eval' blob: data:; worker-src 'self' blob: data:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors https://www.foo.com https://www.bar.com;
  • Canvas-Apps: CSP-Header wird nicht gesendet.

Beispiel 2 – Berichterstellung aktiviert

CSP-Beispiel 2

Im obigen Beispiel:

  • Die Berichterstellung ist aktiviert.
    • Berichterstellungsendpunkt ist auf https://www.mysite.com/myreportingendpoint festgelegt
  • Die Modellgesteuerte Erzwingung ist aktiviert.
    • frame-ancestors wird standardmäßig beibehalten
  • Canvas-Erzwingung ist deaktiviert.
    • frame-ancestors ist auf https://www.baz.com angepasst

Die effektiven CSP-Werte sind:

  • Modellgesteuerte Apps: Content-Security-Policy: script-src * 'unsafe-inline' 'unsafe-eval' blob: data:; worker-src 'self' blob: data:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'self' https://*.powerapps.com; report-uri https://www.mysite.com/myreportingendpoint;
  • Canvas-Apps: Content-Security-Policy-Report-Only: script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors https://www.baz.com; report-uri https://www.mysite.com/myreportingendpoint;

Organisationseinstellungen direkt ändern

Sie können CSP konfigurieren, ohne die Benutzeroberfläche zu verwenden, indem Sie die folgenden Organisationseinstellungen direkt ändern:

  • IsContentSecurityPolicyEnabled steuert, ob der Richtlinie für Inhaltssicherheiten-Header in Modellgesteuerten Apps gesendet wird.

  • ContentSecurityPolicyConfiguration steuert den Wert des frame-ancestors-Abschnitts (wie zuvor gesehen, wird auf 'self' gesetzt, wenn ContentSecurityPolicyConfiguration nicht gesetzt ist). Definieren Sie diese Einstellung mithilfe eines JSON-Objekts mit der folgenden Struktur – { "Frame-Ancestor": { "sources": [ { "source": "foo" }, { "source": "bar" } ] } }. Diese Konfiguration wird übersetzt in script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'foo' 'bar';

    • (Von MDN) Die frame-ancestors-Direktive von HTTP Content-Security-Policy (CSP) gibt gültige übergeordnete Elemente an, die eine Seite mit <frame>, <iframe>, <object>, <embed> oder <applet> einbetten können.
  • IsContentSecurityPolicyEnabledForCanvas steuert, ob der Richtlinie für Inhaltssicherheiten-Header in Canvas-Apps gesendet wird.

  • ContentSecurityPolicyConfigurationForCanvas steuert die Richtlinie für Canvas mithilfe des gleichen Prozesses, der in ContentSecurityPolicyConfiguration beschrieben wird.

  • ContentSecurityPolicyReportUri steuert, ob die Berichterstellung verwendet werden soll. Diese Einstellung wird sowohl von Modellgesteuerten Apps als auch von Canvas-Apps verwendet. Eine gültige Zeichenfolge sendet Verstoßberichte an den angegebenen Endpunkt, wobei der Nur-Bericht-Modus verwendet wird, wenn IsContentSecurityPolicyEnabled/IsContentSecurityPolicyEnabledForCanvas deaktiviert ist. Eine leere Zeichenfolge deaktiviert die Berichterstellung. Weitere Informationen finden Sie in der Dokumentation zur Berichterstellung.

Konfigurieren von CSP ohne Benutzeroberfläche

Besonders für Umgebungen, die nicht im Power Platform Admin Center sind, wie lokale Konfigurationen, möchten Administratoren möglicherweise CSP mithilfe von Skripts konfigurieren, um Einstellungen direkt zu ändern.

CSP ohne Benutzeroberfläche aktivieren

Führen Sie die folgenden Schritte aus, um CSP ohne Benutzeroberfläche zu aktivieren:

  • Öffnen Sie Browser-Entwicklertools, während Sie die Modellgesteuerte App als Benutzer mit Aktualisierungsberechtigungen für Organisationsentitäten verwenden (Systemadministrator ist eine gute Option).
  • Fügen Sie das folgende Skript in die Konsole ein, und führen Sie es aus.
  • Um CSP zu aktivieren, übergeben Sie die Standardkonfiguration – enableFrameAncestors(["'self'"])
  • Als Beispiel für die Aktivierung anderer Ursprünge zum Einbetten der App – enableFrameAncestors(["*.powerapps.com", "'self'", "abcxyz"])
async function enableFrameAncestors(sources) {
    const baseUrl = Xrm.Utility.getGlobalContext().getClientUrl();

    if (!Array.isArray(sources) || sources.some(s => typeof s !== 'string')) {
        throw new Error('sources must be a string array');
    }

    const orgResponse = await fetch(`${baseUrl}/api/data/v9.1/organizations`);
    if (!orgResponse.ok) throw new Error('Failed to retrieve org info');
    const orgs = await orgResponse.json();
    const { organizationid, contentsecuritypolicyconfiguration, iscontentsecuritypolicyenabled } = orgs.value[0];

    console.log(`Organization Id: ${organizationid}`);
    console.log(`CSP Enabled?: ${iscontentsecuritypolicyenabled}`);
    console.log(`CSP Config: ${contentsecuritypolicyconfiguration}`);

    const orgProperty = prop => `${baseUrl}/api/data/v9.1/organizations(${organizationid})/${prop}`;

    console.log('Updating CSP configuration...')
    const config = {
        'Frame-Ancestor': {
            sources: sources.map(source => ({ source })),
        },
    };
    const cspConfigResponse = await fetch(orgProperty('contentsecuritypolicyconfiguration'), {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            value: JSON.stringify(config),
        }),
    });

    if (!cspConfigResponse.ok) {
        throw new Error('Failed to update csp configuration');
    }
    console.log('Successfully updated CSP configuration!')

    if (iscontentsecuritypolicyenabled) {
        console.log('CSP is already enabled! Skipping update.')
        return;
    }

    console.log('Enabling CSP...')
    const cspEnableResponse = await fetch(orgProperty('iscontentsecuritypolicyenabled'), {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            value: true,
        }),
    });

    if (!cspEnableResponse.ok) {
        throw new Error('Failed to enable csp');
    }
    console.log('Successfully enabled CSP!')
}

CSP ohne Benutzeroberfläche deaktivieren

Führen Sie die folgenden Schritte aus, um CSP ohne Benutzeroberfläche zu deaktivieren:

  • Öffnen Sie Browser-Entwicklertools, während Sie die Modellgesteuerte App als Benutzer mit Aktualisierungsberechtigungen für Organisationsentitäten verwenden (Systemadministrator ist eine gute Option).
  • Fügen Sie das folgende Skript in die Konsole ein, und führen Sie es aus.
  • Um CSP zu deaktivieren, fügen Sie in die Konsole ein: disableCSP()
async function disableCSP() {
    const baseUrl = Xrm.Utility.getGlobalContext().getClientUrl();

    const orgResponse = await fetch(`${baseUrl}/api/data/v9.1/organizations`);
    if (!orgResponse.ok) throw new Error('Failed to retrieve org info');
    const orgs = await orgResponse.json();
    const { organizationid, iscontentsecuritypolicyenabled } = orgs.value[0];

    console.log(`Organization Id: ${organizationid}`);
    console.log(`CSP Enabled?: ${iscontentsecuritypolicyenabled}`);

    const orgProperty = prop => `${baseUrl}/api/data/v9.1/organizations(${organizationid})/${prop}`;

    if (!iscontentsecuritypolicyenabled) {
        console.log('CSP is already disabled! Skipping update.')
        return;
    }

    console.log('Disabling CSP...')
    const cspEnableResponse = await fetch(orgProperty('iscontentsecuritypolicyenabled'), {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            value: false,
        }),
    });

    if (!cspEnableResponse.ok) {
        throw new Error('Failed to disable csp');
    }
    console.log('Successfully disabled CSP!')
}