Criteri di sicurezza dei contenuti
criteri di sicurezza contenuto (CSP) è attualmente supportato in model-driven e canvas Power Apps. Gli amministratori possono controllare se l'intestazione CSP viene inviata e, in una certa misura, cosa contiene. Le impostazioni sono a livello ambiente, il che significa che una volta attivate, verranno applicate a tutte le app presenti in ambiente.
Ciascun componente di questo valore di intestazione CSP controlla le risorse che possono essere scaricate ed è descritto in modo più dettagliato su Mozilla Developer Network (MDN). I valori predefiniti sono i seguenti:
Direttiva | Valore predefinito | Personalizzabile |
---|---|---|
script-src | * 'unsafe-inline' 'unsafe-eval' |
No |
lavoratore-src | 'self' blob: |
No |
stile-src | * 'unsafe-inline' |
No |
fonte-font | * data: |
No |
antenati del frame | 'self' https://*.powerapps.com |
Sì |
Ciò si traduce in un CSP predefinito di script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'self' https://*.powerapps.com;
. Nella nostra tabella di marcia, abbiamo la possibilità di modificare le intestazioni attualmente non personalizzabili.
Prerequisiti
- Per le app di coinvolgimento dei clienti Dynamics 365 e altre app basate su modello, CSP è disponibile solo negli ambienti online e nelle organizzazioni con Dynamics 365 Customer Engagement (locale), versione 9.1 o successiva.
Configurazione di CSP
CSP può essere attivato configurato tramite l'interfaccia di amministrazione di Power Platform. È importante abilitare prima ambiente su uno sviluppatore/test poiché l'abilitazione di CSP potrebbe avviare scenari di blocco in caso di violazione della policy. Supportiamo anche una "modalità solo report" per consentire un più facile avvio in produzione.
Per configurare CSP, accedi all'interfaccia di amministrazione di Power Platform ->Ambienti - >Impostazioni>Privacy + Sicurezza. L'immagine seguente mostra lo stato predefinito delle impostazioni:
Report
L'interruttore "Abilita creazione report" controlla se le app basate su modello e canvas inviano segnalazioni di violazione. Per abilitarlo è necessario specificare un endpoint. Le segnalazioni di violazione vengono inviate a questo endpoint indipendentemente dal fatto che CSP sia applicato o meno (utilizzando la modalità di solo segnalazione se CSP non è applicato). Per altre informazioni, vedi la documentazione sulla creazione di report.
Applicazione
L'applicazione del CSP è controllata in modo indipendente per le app basate su modello e canvas per fornire un controllo granulare sui criteri. Usa il pivot basato su modello/canvas per modificare il tipo di app previsto.
L'interruttore "Abilita criteri di sicurezza contenuto" attiva i criteri predefiniti per l'applicazione per il tipo di app specificato. L'attivazione di questo interruttore cambia il comportamento delle app in questo ambiente per aderire alle norme. Pertanto, il flusso di abilitazione suggerito sarebbe:
- Applica su un ambiente di sviluppo/test.
- Abilita la modalità solo report in produzione.
- Applica in produzione una volta che non vengono segnalate violazioni.
Configura direttive
Questa sezione consente di controllare le singole direttive all'interno dei criteri. Attualmente, solo frame-ancestors
può essere personalizzato.
Lasciando attivata la direttiva predefinita viene utilizzato il valore predefinito specificato nella tabella mostrata in precedenza in questo articolo. La disattivazione dell'interruttore consente agli amministratori di specificare valori personalizzati per la direttiva e di aggiungerli al valore predefinito. L'esempio seguente imposta valori personalizzati per frame-ancestors
. La direttiva verrebbe impostata su frame-ancestors: 'self' https://*.powerapps.com https://www.foo.com https://www.bar.com
in questo esempio, il che significa che l'app potrebbe essere ospitata nella stessa origine, https://*.powerapps.com
, https://www.foo.com
e https://www.bar.com
, ma non in altre origini. Utilizza il pulsante Aggiungi per aggiungere voci all'elenco e l'icona Elimina per rimuoverle.
Configurazioni comuni
Per l'integrazione di Microsoft Teams tramite l' app Dynamics 365, aggiungi quanto segue a frame-ancestors
:
https://teams.microsoft.com/
https://teams.cloud.microsoft/
https://msteamstabintegration.dynamics.com/
Per Dynamics 365 App for Outlook, aggiungi quanto segue a frame-ancestors
:
- Origine della home page di Outlook Web App
https://outlook.office.com
https://outlook.office365.com
Per l'integrazione di Power Apps nei report Power BI, aggiungi quanto segue a frame-ancestors
:
https://app.powerbi.com
https://ms-pbi.pbi.microsoft.com
Considerazioni importanti
La disattivazione della direttiva predefinita e il salvataggio con un elenco vuoto disattiva completamente la direttiva e non la invia come parte dell'intestazione della risposta CSP.
Esempi
Diamo un'occhiata a un paio di esempi di configurazione CSP:
Esempio 1
Nell'esempio:
- La creazione di report è disattivata.
- L'applicazione basata su modello è abilitata.
frame-ancestors
è personalizzato perhttps://www.foo.com
ehttps://www.bar.com
- L'applicazione canvas è disabilitata.
Le intestazioni effettive sarebbero:
- App basate su modello:
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;
- App canvas: l'intestazione CSP non verrebbe inviata.
Esempio 2
Nell'esempio:
- La creazione di report è attivata.
- L'endpoint di creazione di report è impostato su
https://www.mysite.com/myreportingendpoint
- L'endpoint di creazione di report è impostato su
- L'applicazione basata su modello è abilitata.
frame-ancestors
è mantenuto come predefinito
- L'applicazione canvas è disabilitata.
frame-ancestors
è personalizzato perhttps://www.baz.com
I valori CSP effettivi sarebbero:
- App basate su modello:
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;
- App canvas:
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;
Impostazioni dell'organizzazione
È possibile configurare CSP senza utilizzare l'interfaccia utente modificando direttamente le seguenti impostazioni dell'organizzazione:
IsContentSecurityPolicyEnabled controlla se l'intestazione Content-Security-Policy viene inviata nelle app basate su modello.
ContentSecurityPolicyConfiguration controlla il valore della porzione frame-ancestors (come visto sopra, è impostato su
'self'
seContentSecurityPolicyConfiguration
non è impostato). Questa impostazione è rappresentata da un oggetto JSON con la struttura seguente:{ "Frame-Ancestor": { "sources": [ { "source": "foo" }, { "source": "bar" } ] } }
. Questo si tradurrebbe inscript-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'foo' 'bar';
- (Da MDN) La direttiva frame-ancestors HTTP Content-Security-Policy (CSP) specifica i genitori validi che possono incorporare una pagina utilizzando
<frame>
,<iframe>
,<object>
,<embed>
, o<applet>
.
- (Da MDN) La direttiva frame-ancestors HTTP Content-Security-Policy (CSP) specifica i genitori validi che possono incorporare una pagina utilizzando
IsContentSecurityPolicyEnabledForCanvas controlla se l'intestazione Content-Security-Policy viene inviata nelle app canvas.
ContentSecurityPolicyConfigurationForCanvas controlla la policy per canvas utilizzando lo stesso processo descritto sopra.
ContentSecurityPolicyConfiguration
ContentSecurityPolicyReportUri controlla se utilizzare la segnalazione. Questa impostazione viene utilizzata sia dalle app basate su modello che da quelle canvas. Una stringa valida invia i report di violazione al endpoint specificato, utilizzando la modalità solo report se
IsContentSecurityPolicyEnabled
/IsContentSecurityPolicyEnabledForCanvas
è disattivato. Una stringa vuota disabilita la creazione di report. Per altre informazioni, vedi la documentazione sulla creazione di report.
Configurazione di CSP senza interfaccia utente
Soprattutto per ambienti fuori dall'interfaccia utente di Power Platform come le configurazioni locali, gli amministratori potrebbero voler configurare CSP utilizzando gli script per modificare direttamente le impostazioni.
Abilitazione di CSP senza interfaccia utente
Passaggi:
- Apri gli strumenti di sviluppo del browser mentre utilizzi l'app basata su modello come utente con privilegi di aggiornamento dell'entità dell'organizzazione (Amministratore di sistema è una buona opzione).
- Incolla ed esegui lo script seguente nella console.
- Per abilitare CSP, passare la configurazione predefinita -
enableFrameAncestors(["'self'"])
- Come esempio di come abilitare altre origini a incorporare l'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!')
}
Disabilitazione di CSP senza interfaccia utente
Passaggi:
- Apri gli strumenti di sviluppo del browser mentre utilizzi l'app basata su modello come utente con privilegi di aggiornamento dell'entità dell'organizzazione (Amministratore di sistema è una buona opzione).
- Incolla ed esegui lo script seguente nella console.
- Per disabilitare CSP, incolla nella console:
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!')
}