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í.
Poznámka:
Zásady zabezpečení obsahu se vztahují pouze na prostředí používající Dataverse.
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
- Pro aplikace Dynamics 365 Customer Engagement a další modelem řízené aplikace je CSP k dispozici pouze v online prostředích a v organizacích s Dynamics 365 Customer Engagement (on-premises) verze 9.1 nebo novější.
Konfigurace CSP
CSP lze zapínat a konfigurovat v centru pro správu Power Platform. Nejprve je důležité povolit ve vývojářském/testovacím prostředí, protože povolení CSP by mohlo začít blokovat scénářů v případě porušení zásad. 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í.
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í.
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:
- Vynutit ve vývojovém/testovacím prostředí.
- Povolit režim pouze pro sestavy v produkci.
- 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
.
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.
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
V tomto příkladu:
- Hlášení je vypnuto.
- Modelem řízené vynucení je povoleno.
-
frame-ancestors
je přizpůsobeno nahttps://www.foo.com
ahttps://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
V tomto příkladu:
- Hlášení je zapnuté.
- Koncový bod pro vytváření sestav je nastaven na
https://www.mysite.com/myreportingendpoint
- Koncový bod pro vytváření sestav je nastaven na
- 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 nahttps://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 frame-ancestors (jak je vidět výše, je nastavena na
'self'
, pokud není nastavenaContentSecurityPolicyConfiguration
). Toto nastavení je reprezentováno objektem JSON s následující strukturou –{ "Frame-Ancestor": { "sources": [ { "source": "foo" }, { "source": "bar" } ] } }
. To by se převedlo nascript-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>
.
- (Z MDN) Direktiva HTTP Content-Security-Policy (CSP) frame-ancestors určuje platné nadřazené položky, které mohou vložit stránku pomocí
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í dalších zdrojů pro vložení aplikace -
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!')
}