Partager via


Stratégie de sécurité du contenu

La stratégie de sécurité de contenu (CSP) est actuellement prise en charge dans les applications de canevas et pilotées par modèle. Les administrateurs peuvent contrôler si l’en-tête CSP est envoyé et, dans une certaine mesure, ce qu’il contient. Les paramètres sont au niveau de l’environnement, ce qui signifie qu’ils sont appliqués à toutes les applications de l’environnement une fois activés.

Note

La stratégie de sécurité du contenu s’applique uniquement aux environnements qui utilisent Dataverse.

Chaque composant de la valeur d’en-tête CSP contrôle les actifs pouvant être téléchargés et est décrit plus en détail sur le Mozilla Developer Network (MDN). Les valeurs par défaut sont les suivantes :

Instructions Valeur par défaut Personnalisable
script-src * 'unsafe-inline' 'unsafe-eval' blob: data: Non
worker-src 'self' blob: data: Non
style-src * 'unsafe-inline' Non
font-src * data: Non
frame-ancestors 'self' https://*.powerapps.com Oui

Cette configuration se traduit par une stratégie CSP par défaut de 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;.

Mode strict

L'interrupteur CSP strict crée une stratégie de sécurité de contenu qui ne comprend généralement pas de caractères génériques ou de directives non sécurisées, telles que unsafe-inline. Lorsque strict CSP est activé, les directives détaillées dans le tableau précédent se transforment en directives détaillées dans le tableau suivant. La <platform> notation signifie que les domaines de plateforme sont fournis comme requis par le produit. Les domaines de cette section peuvent changer au fil du temps à mesure que le produit augmente.

Note

La fonctionnalité Fournisseur de solutions Cloud strict n’est actuellement disponible que pour les applications pilotées par modèle.

Instructions Valeur par défaut (pilotée par le modèle) Personnalisable
script-src 'self' blob: data: <platform>' Oui
worker-src 'self' blob: data: Non
style-src 'self' 'unsafe-inline' <platform> Oui
font-src 'self' data: <platform> Oui
frame-ancestors 'self' https://*.powerapps.com Oui
img-src 'self' blob: data: <platform> Oui
connect-src 'self' blob: data: wss: <platform> Oui
frame-src 'self' blob: <platform> Oui
base-uri 'none' Non
form-action <platform> Oui
default-src 'self' Non

Configuration requise

Pour les applications Dynamics 365 Customer Engagement et d’autres applications pilotées par modèle, CSP n’est disponible que dans les environnements en ligne et dans les organisations avec Dynamics 365 Customer Engagement (on-premises), version 9.1 ou une version ultérieure.

Configurer la CSP

Vous pouvez activer et configurer la stratégie Fournisseur de solutions Cloud via le centre d’administration Power Platform. Il est important d’activer d’abord un environnement de développeur/test car activer une stratégie CSP pourrait commencer à bloquer des scénarios si la stratégie est violée. Nous prenons également en charge un mode rapport uniquement pour faciliter la montée en production.

Pour configurer les CSP :

  1. Connectez-vous au Centre d’administration Power Platform.
  2. Dans le volet de navigation, sélectionnez Gérer, puis dans le volet Gérer, sélectionnez Environnements.
  3. Sur la page Environnements, sélectionnez un environnement.
  4. Dans la barre de commandes, sélectionnez Paramètres.
  5. Développez Produit,puis sélectionnez Confidentialité + Sécurité.

L’image suivante montre l’état par défaut des paramètres :

Paramètres par défaut de la stratégie de sécurité du contenu.

Signalement

Le bouton bascule Activer les rapports contrôle si les applications pilotées par modèle et canevas envoient des rapports de violation. Vous devez spécifier un point de terminaison pour l’activer. Les rapports de violation sont envoyés à ce point de terminaison, que la CSP soit appliquée ou non (en utilisant le mode rapport uniquement si la CSP n’est pas appliquée). Pour plus d’informations, consultez la documentation sur la génération de rapports.

Activez le bouton bascule Rapports.

Mise en application

L’application de la CSP est contrôlée indépendamment pour les applications pilotées par modèle et canevas afin de fournir un contrôle granulaire sur les stratégies. Utilisez le tableau croisé piloté par modèle/canevas pour modifier le type d’application souhaité.

Le bouton Appliquer la stratégie de sécurité du contenu active la stratégie d’application par défaut pour le type d’application donné. L’activation de ce bouton bascule modifie le comportement des applications dans cet environnement pour respecter la stratégie. Par conséquent, le flux d’activation suggéré serait :

  1. Appliquer dans un environnement de développeur/test.
  2. Activer le mode rapport uniquement en production.
  3. Appliquer en production une fois qu’aucune violation n’est signalée.

Configurer les instructions

La section Configurer les directives vous permet de contrôler des directives individuelles au sein de la stratégie. Actuellement, seul frame-ancestors peut être personnalisé.

Configurer les directives CSP.

En laissant la directive par défaut activée, vous utiliserez la valeur par défaut spécifiée dans la table. La désactivation du bouton bascule permet aux administrateurs de spécifier des valeurs personnalisées pour la directive et de les ajouter à la valeur par défaut. L’exemple ci-dessous définit des valeurs personnalisées pour frame-ancestors. La directive serait définie sur frame-ancestors: 'self' https://*.powerapps.com https://www.foo.com https://www.bar.com dans cet exemple, ce qui signifie que l’application pourrait être hébergée dans la même origine, https://*.powerapps.com, https://www.foo.com et https://www.bar.com, mais pas dans d’autres origines. Utilisez le bouton Ajouter pour ajouter des entrées à la liste et l’icône Supprimer pour en supprimer.

Définition de directives CSP personnalisées.

Configurations courantes

Pour l’intégration de Microsoft Teams à l’aide de l’application Dynamics 365, ajoutez ce qui suit à frame-ancestors :

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

Pour Dynamics 365 App for Outlook, ajoutez ce qui suit à frame-ancestors :

  • Origine de la page d’accueil de votre application web Outlook
  • https://outlook.office.com
  • https://outlook.office365.com

Pour l’intégration de Power Apps dans les rapports Power BI, ajoutez ce qui suit à frame-ancestors :

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

Remarques importantes

La désactivation de la directive par défaut et son enregistrement avec une liste vide désactive complètement la directive et ne l’envoie pas dans le cadre de l’en-tête de réponse CSP.

Exemple de configuration CSP

Jetons un coup d’œil à quelques exemples de configurations Fournisseur de solutions Cloud.

Exemple 1 : rapport désactivé

Exemple CSP 1 :

Dans l’exemple :

  • La génération de rapports est désactivée.
  • L’application pilotée par modèle est activée.
    • frame-ancestors est personnalisé pour https://www.foo.com et https://www.bar.com
  • L’application canevas est désactivée.

Les en-têtes effectifs seraient :

  • Applications pilotées par modèle : 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;
  • Applications canevas : l’en-tête CSP ne serait pas envoyé.

Exemple 2 : rapports activés

Exemple CSP 2 :

Dans l’exemple :

  • La génération de rapports est activée.
    • Le point de terminaison de génération de rapports est défini sur https://www.mysite.com/myreportingendpoint
  • L’application pilotée par modèle est activée.
    • frame-ancestors est conservé par défaut
  • L’application canevas est désactivée.
    • frame-ancestors est personnalisé pour https://www.baz.com

Les valeurs CSP effectives seraient :

  • Applications pilotées par modèle : 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;
  • Applications canevas : 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;

Modifier directement les paramètres de l’organisation

Vous pouvez configurer Fournisseur de solutions Cloud sans utiliser l’interface utilisateur en modifiant directement ces paramètres d’organisation :

  • IsContentSecurityPolicyEnabled contrôle si l’en-tête Content-Security-Policy est envoyée dans les applications pilotées par modèle.

  • ContentSecurityPolicyConfiguration contrôle la valeur de la partie frame-ancestors (comme vu ci-dessus, elle est définie sur 'self' si ContentSecurityPolicyConfiguration n’est pas défini). Ce paramètre est défini à l’aide d’un objet JSON avec la structure suivante : { "Frame-Ancestor": { "sources": [ { "source": "foo" }, { "source": "bar" } ] } }. Cette configuration se traduit par script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'foo' 'bar';

    • (À partir de MDN) La directive HTTP Content-Security-Policy (CSP) frame-ancestors spécifie des parents valides qui peuvent intégrer une page à l’aide de <frame>, <iframe>, <object>, <embed> ou <applet>.
  • IsContentSecurityPolicyEnabledForCanvas contrôle si l’en-tête Content-Security-Policy est envoyée dans les applications canevas.

  • ContentSecurityPolicyConfigurationForCanvas contrôle la stratégie pour canevas en utilisant le même processus décrit dans ContentSecurityPolicyConfiguration.

  • ContentSecurityPolicyReportUri contrôle si la génération de rapports doit être utilisée. Ce paramètre est pris en charge à la fois dans les applications pilotées par modèle et les applications canevas. Une chaîne valide envoie les rapports de violation au point de terminaison spécifié, en utilisant le mode rapport uniquement si IsContentSecurityPolicyEnabled/IsContentSecurityPolicyEnabledForCanvas est désactivé. Une chaîne vide désactive la création de rapports. Pour plus d’informations, consultez la documentation sur la génération de rapports.

Configurer la CSP sans interface utilisateur

En particulier pour les environnements qui ne se trouvent pas dans le Centre d’administration de Power Platform, tels que les configurations locales, les administrateurs peuvent souhaiter configurer le Fournisseur de solutions Cloud à l’aide de scripts pour modifier directement les paramètres.

Activer le Fournisseur de solutions Cloud sans interface utilisateur

Procédez comme suit pour activer le Fournisseur de solutions Cloud sans interface utilisateur :

  • Ouvrez les outils de développement du navigateur tout en utilisant l’application pilotée par modèle en tant qu’utilisateur disposant des privilèges de mise à jour de l’entité de l’organisation (Administrateur système est une bonne option).
  • Collez et exécutez le script suivant dans la console.
  • Pour activer la stratégie CSP, transmettez la configuration par défaut - enableFrameAncestors(["'self'"])
  • À titre d’exemple d’activation d’autres origines pour intégrer l’application - 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!')
}

Désactiver le Fournisseur de solutions Cloud sans interface utilisateur

Procédez comme suit pour désactiver le Fournisseur de solutions Cloud sans interface utilisateur :

  • Ouvrez les outils de développement du navigateur tout en utilisant l’application pilotée par modèle en tant qu’utilisateur disposant des privilèges de mise à jour de l’entité de l’organisation (Administrateur système est une bonne option).
  • Collez et exécutez le script suivant dans la console.
  • Pour désactiver le fournisseur de solutions Cloud, collez dans la 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!')
}