Sdílet prostřednictvím


Zásady zabezpečení obsahu

Zásady zabezpečení obsahu (CSP) jsou v současné době podporovány v modelem řízených aplikacích a aplikacích plátna Power Apps. Správci mohou řídit, zda se hlavička CSP odesílá a do určité míry i to, co obsahuje. Nastavení je na úrovni prostředí, což znamená, že by se po zapnutí použilo na všechny aplikace v prostředí.

Každá součást této hodnoty hlavičky CSP řídí prostředky, které lze stáhnout, a je podrobněji popsána na Mozilla Developer Network (MDN). Výchozí hodnoty jsou:

Direktiva Výchozí hodnota Přizpůsobitelné
skript-src * 'unsafe-inline' 'unsafe-eval' Ne
worker-src 'self' blob: Ne
style-src * 'unsafe-inline' Ne
font-src * data: Ne
frame-ancestors 'self' https://*.powerapps.com Ano

Výsledkem je výchozí CSP ve tvaru script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'self' https://*.powerapps.com;. V naší cestovní mapě máme možnost upravit aktuálně nepřizpůsobitelná záhlaví.

Předpoklady

  • U aplikací Dynamics 365 pro zapojení zákazníků a dalších aplikací řízených modely je CSP k dispozici pouze v online prostředích a v organizacích se zapojením zákazníků Dynamics 365 (místní), verze 9.1 nebo novější.

Konfigurace CSP

CSP lze zapínat a konfigurovat v centru pro správu Power Platform. Je důležité nejprve povolit ve vývojářském/testovacím prostředí , protože povolení CSP by mohlo začít blokovat scénáře, pokud jsou zásady porušeny. Podporujeme také „režim pouze sestavy“, abychom umožnili snazší náběh produkce.

Chcete-li nakonfigurovat CSP, přejděte na centrum pro správu Power Platform –>Prostředí –>Nastavení –>Soukromí + zabezpečení. Následující obrázek ukazuje výchozí stav nastavení.

Výchozí nastavení zásad zabezpečení obsahu

Nahlašování

Přepínač „Povolit reportování“ určuje, zda aplikace řízené modelem a aplikace plátna odesílají hlášení o porušení. Aktivace vyžaduje zadání koncového bodu. Hlášení o porušení jsou zasílána na tento koncový bod bez ohledu na to, zda je CSP vynucován, nebo ne (použijte režim pouze hlášení, pokud CSP není vynucován). Další informace získáte v dokumentaci k reportování.

Aktivace koncového bodu pro vytváření sestav

Vynucení

Vynucení CSP je řízeno nezávisle pro modelem řízené aplikace a aplikace plátna, aby bylo zajištěno podrobné ovládání zásad. K úpravě zamýšleného typu aplikace použijte pivot řízený modelem / plátna.

Přepínač „Vynutit zásadu zabezpečení obsahu“ zapne výchozí zásady vynucení pro daný typ aplikace. Zapnutím tohoto přepínače změní chování aplikací v tomto prostředí tak, aby dodržovaly zásady. Proto by navrhovaný postup aktivace byl:

  1. Vynutit ve vývojovém/testovacím prostředí.
  2. Povolit režim pouze pro sestavy v produkci.
  3. Vynutit v produkci, jakmile nebudou hlášena žádná porušení.

Konfigurace předpisů

Tato sekce umožňuje ovládat jednotlivé zásady v rámci zásad. V současné době lze přizpůsobit frame-ancestors.

Konfigurace zásad CSP

Pokud ponecháte zapnutou výchozí direktivu, použije se výchozí hodnota zadaná v tabulce uvedené dříve v tomto článku. Vypnutí přepínače umožňuje správcům zadat vlastní hodnoty pro direktivu a připojit je k výchozí hodnotě. Níže uvedený příklad nastavuje vlastní hodnoty pro frame-ancestors. Direktiva by v tomto příkladu byla nastavena na frame-ancestors: 'self' https://*.powerapps.com https://www.foo.com https://www.bar.com, což znamená, že aplikace by mohla být hostována ve stejných původech https://*.powerapps.com, https://www.foo.com a https://www.bar.com, ale ne v jiných. Pomocí tlačítka Přidat přidáte položky do seznamu a pomocí ikony odstranit je odstraníte.

Nastavení vlastních zásad CSP

Běžné konfigurace

Při integraci Microsoft Teams pomocí aplikace Dynamics 365 přidejte následující do frame-ancestors:

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

Pro Dynamics 365 App for Outlook přidejte následující do frame-ancestors:

  • Původ úvodní stránky webové aplikace Outlook
  • https://outlook.office.com
  • https://outlook.office365.com

Pro vložení Power Apps do sestav Power BI přidejte následující k frame-ancestors:

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

Důležitá poznámka

Vypnutí výchozí zásady a uložení s prázdným seznamem úplně vypne zásadu a neodesílá ji jako součást hlavičky odpovědi CSP.

Příklady

Podívejme se na několik příkladů konfigurace CSP:

Příklad 1

Příklad CSP 1

V příkladu:

  • Hlášení je vypnuto.
  • Modelem řízené vynucení je povoleno.
    • frame-ancestors je přizpůsobeno na https://www.foo.com a https://www.bar.com
  • Vynucení plátna je deaktivováno.

Efektivní hlavičky budou:

  • Modelem řízené aplikace: 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;
  • Aplikace plátna: Záhlaví CSP nebude odesláno.

Příklad 2

Příklad CSP 2

V příkladu:

  • Hlášení je zapnuté.
    • Koncový bod pro vytváření sestav je nastaven na https://www.mysite.com/myreportingendpoint
  • Modelem řízené vynucení je povoleno.
    • frame-ancestors je zachováno jako výchozí
  • Vynucení plátna je deaktivováno.
    • frame-ancestors je přizpůsobeno na https://www.baz.com

Efektivní hodnoty CSP budou:

  • Modelem řízené aplikace: 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;
  • Aplikace plátna: 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;

Nastavení organizace

CSP lze konfigurovat bez použití uživatelského rozhraní přímou úpravou následujících nastavení organizace:

  • IsContentSecurityPolicyEnabled řídí, zda se záhlaví Content-Security-Policy odesílá v modelem řízených aplikacích.

  • ContentSecurityPolicyConfiguration řídí hodnotu části rámců-předků (jak je vidět výše, je nastavena na 'self' pokud ContentSecurityPolicyConfiguration není nastaveno). Toto nastavení je reprezentováno objektem JSON s následující strukturou –{ "Frame-Ancestor": { "sources": [ { "source": "foo" }, { "source": "bar" } ] } }. To by se převedlo na script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'foo' 'bar';

    • (Z MDN) Direktiva HTTP Content-Security-Policy (CSP) frame-ancestors určuje platné nadřazené položky, které mohou vložit stránku pomocí <frame>, <iframe>, <object>, <embed>, nebo <applet>.
  • IsContentSecurityPolicyEnabledForCanvas řídí, zda se záhlaví Content-Security-Policy odesílá v aplikacích plátna.

  • ContentSecurityPolicyConfigurationForCanvas řídí zásady pro plátno pomocí stejného procesu popsaného v ContentSecurityPolicyConfiguration výše.

  • ContentSecurityPolicyReportUri řídí, zda by se mělo používat hlášení. Toto nastavení používají aplikace řízené modelem i aplikace plátna. Platný řetězec odesílá hlášení o porušení na zadaný koncový bod pomocí režimu pouze sestavy, pokud je IsContentSecurityPolicyEnabled/IsContentSecurityPolicyEnabledForCanvas vypnuté. Prázdný řetězec deaktivuje hlášení. Další informace získáte v dokumentaci k reportování.

Konfigurace CSP bez uživatelského rozhraní

Zejména pro prostředí, která nejsou v centru pro správu Power Platform, jako jsou místní konfigurace, mohou správci chtít nakonfigurovat CSP pomocí skriptů pro přímou úpravu nastavení.

Aktivace CSP bez uživatelského rozhraní

Kroky:

  • Otevřete vývojářské nástroje prohlížeče při používání modelem řízené aplikace jako uživatel s oprávněními pro aktualizaci organizační entity (Dobrou možností je správce systému).
  • Vložte a spusťte níže uvedený skript do konzoly.
  • Chcete-li povolit CSP, předejte výchozí konfiguraci - enableFrameAncestors(["'self'"])
  • Jako příklad povolení k vložení aplikace jiným původům - 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!')
}

Deaktivace CSP bez uživatelského rozhraní

Kroky:

  • Otevřete vývojářské nástroje prohlížeče při používání modelem řízené aplikace jako uživatel s oprávněními pro aktualizaci organizační entity (Dobrou možností je správce systému).
  • Vložte a spusťte následující skript do konzoly.
  • Chcete-li CSP zakázat, vložte do konzoly: 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!')
}