Udostępnij za pośrednictwem


Zasady zabezpieczeń zawartości

zasady zabezpieczeń zawartości (CSP) są obecnie obsługiwane w modelach opartych na modelu i kanwie Power Apps. 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 po włączeniu zostaną zastosowane do wszystkich aplikacji w środowisku.

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ć
skrypt-src * 'unsafe-inline' 'unsafe-eval' Nie
pracownik-src 'self' blob: Nie
styl-src * 'unsafe-inline' Nie
czcionka-src * data: Nie
przodkowie ramki 'self' https://*.powerapps.com Tak

W wyniku tego jest domyślnie domyślny script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'self' https://*.powerapps.com; W naszym harmonogramie jest dostępna możliwość modyfikowania nagłówków, które nie są obecnie dostępne do dostosowania.

Wymagania wstępne

  • W przypadku aplikacji angażujących klientów Dynamics 365 i innych aplikacji opartych na modelu CSP jest dostępny tylko w środowiskach online i w organizacjach z Dynamics 365 customer engagement (lokalnie) w wersji 9.1 lub nowszej.

Konfigurowanie CSP

Dostawcę CSP można przełączać i konfigurować za pośrednictwem centrum administracyjnego Power Platform. Ważne jest, aby najpierw włączyć w środowisku deweloperskim/testowym, 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ć program CSP, przejdź do centrum administracyjnego Power Platform ->Środowiska ->Ustawienia ->Prywatność + Bezpieczeństwo. 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 modelach i kanwie wysyłają raporty o naruszeniech. Włączenie tej funkcji wymaga punkt końcowy danych. 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ę reportowania.

Włączanie punktu końcowego raportowania

Egzekwowanie

Wymuszanie CSP jest kontrolowane niezależnie w przypadku aplikacji opartych na modelach i kanw, aby zapewnić ziarnistą kontrolę nad zasadami. Użyj pivota na podstawie modelu/kanwy, aby zmodyfikować przeznaczony typ aplikacji.

Przełączenie "Wymuszaj stosowanie zasad zabezpieczeń zawartości" powoduje włączenie domyślnej 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

Ta sekcja umożliwia sterowanie poszczególnymi osobami w ramach zasad. Obecnie można dostosowywać frame-ancestors tylko te dostosowania.

Konfiguruj dyrektywy CSP

Pozostawienie domyślnej dyrektywy przełączania używa wartości domyślnej określonej w tabeli pokazanej wcześniej w tym artykule. 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

Zobaczmy kilka przykładów konfiguracji programu CSP:

Przykład 1

Przykład CSP 1

W przykładzie:

  • Raportowanie jest wyłączone.
  • Włączono funkcję wymuszania opartego na modelach.
    • frame-ancestors jest dostosowany do https://www.foo.com i https://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'; worker-src 'self' blob:; 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

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 modelach.
    • frame-ancestors jest zachowywany jako domyślny
  • 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'; worker-src 'self' blob:; 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;

Ustawienia organizacji

Program CSP można skonfigurować bez konieczności używania interfejsu użytkownika, modyfikując bezpośrednio następujące ustawienia organizacji:

  • IsContentSecurityPolicyEnabled kontroluje, czy nagłówek Content-Security-Policy jest wysyłany w aplikacjach opartych na modelu.

  • ContentSecurityPolicyConfiguration kontroluje wartość części frame-ancestors (jak pokazano powyżej, jest ona ustawiona na 'self' if ContentSecurityPolicyConfiguration nie jest ustawiona). To ustawienie jest reprezentowane przez obiekt JSON o następującej strukturze — { "Frame-Ancestor": { "sources": [ { "source": "foo" }, { "source": "bar" } ] } }. To miałoby przetłumaczyć 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 kontroluje, czy nagłówek Content-Security-Policy jest wysyłany w aplikacjach kanwy.

  • ContentSecurityPolicyConfigurationForCanvas kontroluje zasady dla kanwy przy użyciu tego samego procesu opisanego powyżej ContentSecurityPolicyConfiguration .

  • ContentSecurityPolicyReportUri określa, czy należy używać raportowania. To ustawienie jest używane zarówno przez aplikacje korzystające z modelu, jak i aplikacje z kanwą. 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ę reportowania.

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 programu CSP bez interfejsu użytkownika

Kroki:

  • Otwórz narzędzia do tworzenia przeglądarek, używając aplikacji korzystającej z modelu jako użytkownika z uprawnieniami do aktualizowania encji organizacji (rozwiązanie System Administrator jest dobrym rozwiązaniem).
  • Wklej i wykonaj poniższy skrypt do konsoli.
  • Aby włączyć dostawcę CSP, przekaż domyślną konfigurację — enableFrameAncestors(["'self'"])
  • Jako przykład umożliwienia innym źródłom osadzania 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łączanie programu CSP bez interfejsu użytkownika

Kroki:

  • Otwórz narzędzia do tworzenia przeglądarek, używając aplikacji korzystającej z modelu jako użytkownika z uprawnieniami do aktualizowania encji organizacji (rozwiązanie System Administrator jest dobrym rozwiązaniem).
  • Wklej i wykonaj następujący skrypt w 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!')
}