Udostępnij przez


Zasady zabezpieczeń zawartości

Zasady zabezpieczeń zawartości (CSP) są obecnie obsługiwane w aplikacjach opartych na modelu i kanwie. Administratorzy mogą kontrolować, czy ma być wysyłany nagłówek CSP i, do pewnego stopnia, jego treści. Ustawienia są na poziomie środowiska, co oznacza, że są one stosowane do wszystkich aplikacji w środowisku po włączeniu.

Uwaga

Zasady zabezpieczeń zawartości mają zastosowanie tylko do środowisk korzystających z Dataverse.

Każdy składnik tej wartości nagłówka steruje zasobami, które można pobrać, i jest opisany bardziej szczegółowo w sieci Mozilla Developer Network (MDN). Wartości domyślne ukazano poniżej:

Dyrektywa Domyślna wartość Można dostosowywać
script-src * 'unsafe-inline' 'unsafe-eval' blob: data: Nie
worker-src 'self' blob: data: Nie
style-src * 'unsafe-inline' Nie
font-src * data: Nie
frame-ancestors 'self' https://*.powerapps.com Tak

Ta konfiguracja powoduje domyślną wartość dostawcy CSP wynoszącego 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;.

Tryb ścisły

Przełącznik Strict CSP tworzy zasady zabezpieczeń zawartości, które w większości nie zawierają symboli wieloznacznych ani niebezpiecznych dyrektyw, takich jak unsafe-inline. Gdy program Strict CSP jest włączony, dyrektywy opisane w poprzedniej tabeli zamieniają się w dyrektywy opisane w poniższej tabeli. Notacja <platform> oznacza, że domeny platformy są dostarczane zgodnie z wymaganiami produktu. Domeny w tej sekcji mogą zmieniać się wraz z upływem czasu w miarę rozwoju produktu.

Uwaga

Strict CSP jest obecnie dostępny tylko dla aplikacji opartych na modelu.

Dyrektywa Wartość domyślna (oparta na modelu) Można dostosowywać
script-src 'self' blob: data: <platform>' Tak
worker-src 'self' blob: data: Nie
style-src 'self' 'unsafe-inline' <platform> Tak
font-src 'self' data: <platform> Tak
frame-ancestors 'self' https://*.powerapps.com Tak
img-src 'self' blob: data: <platform> Tak
connect-src 'self' blob: data: wss: <platform> Tak
frame-src 'self' blob: <platform> Tak
base-uri 'none' Nie
form-action <platform> Tak
default-src 'self' Nie

Wymagania wstępne

W przypadku aplikacji platformy Dynamics 365 Customer Engagement i innych aplikacji opartych na modelu dostawca CSP jest dostępny tylko w środowiskach online i w organizacjach z Dynamics 365 Customer Engagement (on-premises) w wersji 9.1 lub nowszej.

Konfiguruj CSP

Dostawcę CSP można przełączać i konfigurować za pomocą centrum administracyjnego Power Platform. Ważne jest, aby najpierw włączyć środowisko deweloperskie/testowe, ponieważ włączenie dostawcy CSP może rozpocząć blokowanie scenariuszy, jeśli zasady zostaną naruszone. Planujemy w przyszłości obsługiwać „tryb tylko raportowania”, aby umożliwić łatwiejszy rozwój produkcji.

Aby skonfigurować wiadomość CSP:

  1. Zaloguj się do centrum administracyjnego Power Platform.
  2. W panelu nawigacyjnym wybierz Zarządzaj, a następnie w panelu Zarządzaj wybierz Środowiska.
  3. Na stronie Środowiska wybierz swoje środowisko.
  4. Wybierz Ustawienia na pasku poleceń.
  5. Rozwiń węzeł Produkt, a następnie wybierz pozycję Prywatność + zabezpieczenia.

Na poniższym obrazie przedstawiono domyślny stan ustawień:

Domyślne ustawienia zasad zabezpieczeń zawartości.

Zgłaszanie

Przełączając funkcję "Włączanie raportowania", można określić, czy aplikacje oparte na modelu i aplikacje kanwy wysyłają raporty o naruszeniach. Aby go włączyć, musisz określić punkt końcowy. Do niniejszego raportu będą wysyłane raporty o naruszenie punkt końcowy niezależnie od tego, czy CSP jest wymuszany czy nie (jeśli nie jest wymuszany za pomocą trybu tylko do raportu). Aby uzyskać więcej informacji, zobacz dokumentację dotyczącą raportowania.

Włącz przełącznik raportowania.

Egzekwowanie

Wymuszanie CSP jest kontrolowane niezależnie w przypadku aplikacji opartych na modelu i aplikacji kanwy, aby zapewnić szczegółową kontrolę nad zasadami. Użyj elementu pivot „oparta na modelu/kanwy”, aby zmodyfikować zamierzony typ aplikacji.

Przełącznik Wymuszaj zasady zabezpieczeń zawartości włącza domyślne zasady wymuszania dla danego typu aplikacji. Włączenie tego przełączania spowoduje zmianę zachowania aplikacji w tym środowisku w celu przestrzegania zasad. Dlatego sugerowany przepływ włączania powinien mieć:

  1. Wymuszanie w środowisku dewelopera/testowego.
  2. Włącz tryb tylko do raportu w środowisku produkcyjnym.
  3. Wymuszanie w środowisku produkcyjnym po tym, jak nie zgłaszane są żadne naruszenie.

Konfiguruj dyrektywy

Sekcja Konfigurowanie dyrektyw umożliwia kontrolowanie poszczególnych dyrektyw w ramach zasad. Obecnie można dostosowywać frame-ancestors tylko te dostosowania.

Konfiguruj dyrektywy CSP.

Pozostawienie włączonej domyślnej dyrektywy powoduje użycie wartości domyślnej określonej w tabeli. Wyłączenie tego przełączania umożliwia administratorom określenie niestandardowych wartości dyrektywy i dołączenie ich do wartości domyślnej. W poniższym przykładzie przedstawiono niestandardowe wartości opcji frame-ancestors. W tym przykładzie ta dyrektywa powinna być ustawiona na wartość frame-ancestors: 'self' https://*.powerapps.com https://www.foo.com https://www.bar.com, czyli aplikacja może być hostowana w tym samym źródle, https://*.powerapps.com, https://www.foo.com i https://www.bar.com, ale nie w innych źródłach. Aby dodać pozycje do listy i usunąć ikony usuwania, użyj przycisku Dodaj.

Ustawianie niestandardowych dyrektyw CSP.

Typowe konfiguracje

Dla integracji Microsoft Teams korzystającej z aplikacji Dynamics 365 dodaj następujące elementy do frame-ancestors:

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

Dla Dynamics 365 App for Outlook, dodaj następujące elementy do frame-ancestors:

  • Pochodzenie strony głównej aplikacji Outlook Web App
  • https://outlook.office.com
  • https://outlook.office365.com

Aby osadzić Power Apps w raportach Power BI, dodaj następujące elementy do frame-ancestors:

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

Ważne uwagi

Wyłączenie dyrektywy domyślnej i zapisanie pustej listy powoduje całkowite wyłączenie dyrektywy i nie jest wysyłana jako część nagłówka odpowiedzi CSP.

Przykłady konfiguracji CSP

Rzućmy okiem na kilka przykładów konfiguracji CSP.

Przykład 1 – raportowanie wyłączone

Przykład CSP 1.

W przykładzie:

  • Raportowanie jest wyłączone.
  • Włączono funkcję wymuszania opartego na modelu.
    • frame-ancestors jest dostosowany do https://www.foo.com orazhttps://www.bar.com
  • Wykonanie kanw jest wyłączone.

Skuteczne nagłówki to:

  • Aplikacje oparte na modelu: 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;
  • Aplikacje kanw: nagłówek CSP nie jest wysyłany.

Przykład 2 – raportowanie włączone

Przykład CSP 2.

W przykładzie:

  • Raportowanie jest włączone.
    • Punkt końcowy raportowania ustawiony na https://www.mysite.com/myreportingendpoint
  • Włączono funkcję wymuszania opartego na modelu.
    • frame-ancestors jest zachowywana jako domyślna
  • Wykonanie kanw jest wyłączone.
    • frame-ancestors jest dostosowany do https://www.baz.com

Efektywne wartości CSP byłyby następujące:

  • Aplikacje oparte na modelu: 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;
  • Aplikacje kanwy: 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;

Bezpośrednie modyfikowanie ustawień organizacji

Dostawcę CSP można skonfigurować bez korzystania z interfejsu użytkownika, modyfikując bezpośrednio następujące ustawienia organizacji:

  • IsContentSecurityPolicyEnabled określa, czy nagłówek zasad zabezpieczeń zawartości jest wysyłany na stronie aplikacji opartych na modelu.

  • ContentSecurityPolicyConfiguration kontroluje wartość części frame-ancestors (jak pokazano powyżej, jest ustawiona na 'self' if ContentSecurityPolicyConfiguration nie jest ustawiona). To ustawienie jest określone przez obiekt JSON o następującej strukturze — { "Frame-Ancestor": { "sources": [ { "source": "foo" }, { "source": "bar" } ] } }. Taka konfiguracja przekłada się na script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'foo' 'bar';

    • (Z MDN) Dyrektywa HTTP Content-Security-Policy (CSP) frame-ancestors określa prawidłowych rodziców, którzy mogą osadzić stronę za pomocą <frame>, <iframe>, <object>, <embed>, lub <applet>.
  • IsContentSecurityPolicyEnabledForCanvas określa, czy nagłówek zasad zabezpieczeń zawartości jest wysyłany na stronie aplikacji kanwy.

  • ContentSecurityPolicyConfigurationForCanvas kontroluje zasady dla kanwy przy użyciu tego samego procesu, który opisano w temacie ContentSecurityPolicyConfiguration.

  • Formant ContentSecurityPolicyReportUri określa, czy raportowanie ma być używane. To ustawienie jest używane zarówno przez aplikacje oparte na modelu, jak i aplikacje kanwy. Prawidłowy ciąg wyśle raporty naruszeń do określonego punktu końcowego przy użyciu trybu tylko raportów, jeśli opcja IsContentSecurityPolicyEnabled/IsContentSecurityPolicyEnabledForCanvas jest wyłączona. Pusty ciąg powoduje wyłączenie raportowania. Aby uzyskać więcej informacji, zobacz dokumentację dotyczącą raportowania.

Konfiguracja CSP bez interfejsu użytkownika

W szczególności w środowiskach Power Platform, które nie są dostępne w centrum administracyjnym, lokalny konfiguracji, administratorzy mogą chcieć skonfigurować program CSP za pomocą skryptów w celu bezpośredniej modyfikacji ustawień.

Włączanie dostawcy CSP bez interfejsu użytkownika

Wykonaj następujące kroki, aby włączyć dostawcę CSP bez interfejsu użytkownika:

  • Otwórz narzędzia deweloperskie dla przeglądarek, używając aplikacji opartej na modelu jako użytkownika z uprawnieniami do aktualizowania encji organizacji (Administrator systemu jest dobrym rozwiązaniem).
  • Wklej i wykonaj poniższy skrypt do konsoli.
  • Aby włączyć CSP, należy przekazać konfigurację domyślną — enableFrameAncestors(["'self'"])
  • Przykład włączania innych źródeł pochodzenia w celu osadzenia aplikacji — 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!')
}

Wyłącz dostawcę CSP bez interfejsu użytkownika

Wykonaj następujące kroki, aby wyłączyć dostawcę CSP bez interfejsu użytkownika:

  • Otwórz narzędzia deweloperskie dla przeglądarek, używając aplikacji opartej na modelu jako użytkownika z uprawnieniami do aktualizowania encji organizacji (Administrator systemu jest dobrym rozwiązaniem).
  • Wklej i wykonaj poniższy skrypt do konsoli.
  • Aby wyłączyć CSP, wklej go do konsoli: 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!')
}