Delen via


Beleid voor beveiliging van inhoud

Beveiligingsbeleid voor inhoud (CSP) wordt momenteel ondersteund in modelgestuurde en canvas-Power Apps. Beheerders kunnen bepalen of de CSP-header wordt verzonden en, tot op zekere hoogte, wat deze bevat. De instellingen werken op omgevingsniveau, wat betekent dat ze na inschakeling worden toegepast op alle apps in de omgeving.

Elk onderdeel van de CSP-headerwaarde bepaalt welke activa kunnen worden gedownload en wordt in meer detail beschreven in het Mozilla Developer Network (MDN). De standaardwaarden zijn zoals hieronder weergegeven:

Richtlijn Standaardwaarde Aanpasbaar
script-src * 'unsafe-inline' 'unsafe-eval' Nee
worker-src 'self' blob: Nee
style-src * 'unsafe-inline' Nee
font-src * data: Nee
frame-ancestors 'self' https://*.powerapps.com Ja

Dit resulteert in een standaard-CSP van script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'self' https://*.powerapps.com;. In onze roadmap hebben we de mogelijkheid om momenteel niet-aanpasbare headers aan te passen.

Vereisten

  • Voor Dynamics 365 Customer Engagement-apps en andere modelgestuurde apps is CSP alleen beschikbaar in online omgevingen en in organisaties met Dynamics 365 Customer Engagement (on-premises), versie 9.1 of later.

CSP configureren

CSP kan worden in-/uitgeschakeld en geconfigureerd via het Power Platform-beheercentrum. Het is belangrijk om eerst in een ontwikkel-/testomgeving in te schakelen aangezien het inschakelen van CSP ertoe kan leiden dat scenario's worden geblokkeerd als het beleid wordt geschonden. We ondersteunen ook een "modus voor alleen rapporteren", zodat de productie gemakkelijker kan worden opgevoerd.

Om CSP te configureren, navigeert u naar het Power Platform-beheercentrum ->Omgevingen ->Instellingen ->Privacy + beveiliging. De volgende afbeelding toont de standaardstatus van de instellingen:

Standaardinstellingen voor inhoudsbeveiligingsbeleid

Rapportage

De schakelaar 'Rapportage inschakelen' bepaalt of modelgestuurde en canvas-apps overtredingsrapporten verzenden. Om dit te kunnen inschakelen, moet een eindpunt worden opgegeven. Overtredingsrapporten worden naar dit eindpunt gestuurd, ongeacht of CSP wordt afgedwongen of niet (met alleen-rapportmodus als CSP niet wordt afgedwongen). Zie voor meer informatie rapportagedocumentatie.

Rapportage-eindpunt inschakelen

Afdwinging

Afdwinging van CSP wordt onafhankelijk beheerd voor modelgestuurde en canvas-apps om gedetailleerde controle over het beleid te bieden. Gebruik het modelgestuurde/canvas-draaipunt om het beoogde app-type te wijzigen.

Met de schakelaar 'Beveiligingsbeleid voor inhoud afdwingen' wordt het standaardbeleid voor handhaving voor het opgegeven app-type ingeschakeld. Als u deze schakelaar inschakelt, verandert het gedrag van apps in deze omgeving om aan het beleid te voldoen. Daarom is de voorgestelde activeringsstroom:

  1. Afdwingen in een ontwikkel-/testomgeving.
  2. Alleen-rapportmodus in productie inschakelen.
  3. Afdwinging in productie zodra er geen overtredingen worden gemeld.

Richtlijnen configureren

De laatste sectie is "Richtlijnen configureren". Met deze sectie kunt u afzonderlijke richtlijnen binnen het beleid beheren. Momenteel kan alleen frame-ancestors worden aangepast.

CSP-richtlijnen configureren

Als u de standaardinstructie ingeschakeld laat, wordt de standaardwaarde gebruikt die is opgegeven in de tabel die eerder in dit artikel wordt weergegeven. Als u de schakelaar uitschakelt, kunnen beheerders aangepaste waarden voor de richtlijn opgeven en deze aan de standaardwaarde toevoegen. In het onderstaande voorbeeld worden aangepaste waarden ingesteld voor frame-ancestors. In dit voorbeeld zou de richtlijn worden ingesteld op frame-ancestors: 'self' https://*.powerapps.com https://www.foo.com https://www.bar.com, wat betekent dat de app kan worden gehost op dezelfde oorsprong, https://*.powerapps.com, https://www.foo.com en https://www.bar.com, maar niet op een andere oorsprong. Gebruik de knop Toevoegen om items aan de lijst toe te voegen en het verwijderpictogram om ze te verwijderen.

Aangepaste CSP-richtlijnen instellen

Algemene configuraties

Voor Microsoft Teams-integratie met behulp van de Dynamics 365-app voegt u het volgende toe aan frame-ancestors:

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

Voeg voor Dynamics 365 App for Outlook het volgende toe aan frame-ancestors:

  • De oorsprong van uw Outlook Web App-startpagina
  • https://outlook.office.com

Voor het insluiten van Power Apps in Power BI-rapporten, voegt u het volgende toe aan frame-ancestors:

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

Belangrijke aandachtspunten

Als de standaardrichtlijn wordt uitgeschakeld en wordt opgeslagen met een lege lijst wordt de richtlijn volledig uitgeschakeld en wordt deze niet als onderdeel van de CSP-responsheader verzonden.

Voorbeelden

Laten we een paar voorbeelden van CSP-configuratie bekijken:

Voorbeeld 1

CSP-voorbeeld 1

In het bovenstaande voorbeeld:

  • Rapportage wordt uitgeschakeld.
  • Modelgestuurde handhaving wordt ingeschakeld.
    • frame-ancestors wordt aangepast aan https://www.foo.com en https://www.bar.com
  • Canvas-handhaving wordt uitgeschakeld.

De effectieve headers zijn:

  • Modelgestuurde apps: 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;
  • Canvas-apps: CSP-header wordt niet verzonden.

Voorbeeld 2

CSP-voorbeeld 2

In het bovenstaande voorbeeld:

  • Rapportage wordt ingeschakeld.
    • Rapportage-eindpunt wordt ingesteld op https://www.mysite.com/myreportingendpoint
  • Modelgestuurde handhaving wordt ingeschakeld.
    • frame-ancestors wordt standaard behouden
  • Canvas-handhaving wordt uitgeschakeld.
    • frame-ancestors wordt aangepast aan https://www.baz.com

De effectieve CSP-waarden zijn:

  • Modelgestuurde apps: 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;
  • Canvas-apps: 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;

Organisatie-instellingen

CSP kan worden geconfigureerd zonder de gebruikersinterface te gebruiken door de volgende organisatie-instellingen rechtstreeks te wijzigen:

  • IsContentSecurityPolicyEnabled bepaalt of de Content-Security-Policy-header wordt verzonden in modelgestuurde apps.

  • ContentSecurityPolicyConfiguration bepaalt de waarde van het gedeelte frame-ancestor (zoals hierboven te zien is, wordt het ingesteld op 'self' als ContentSecurityPolicyConfiguration niet is ingesteld). Deze instelling wordt weergegeven door een JSON-object met de volgende structuur: { "Frame-Ancestor": { "sources": [ { "source": "foo" }, { "source": "bar" } ] } }. Dit zou zich vertalen in script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'foo' 'bar';

    • (Van MDN) De HTTP Content-Security-Policy (CSP) frame-ancestor-richtlijn specificeert geldige ouders die een pagina mogen insluiten met <frame>, <iframe>, <object>, <embed> of <applet>.
  • IsContentSecurityPolicyEnabledForCanvas bepaalt of de Content-Security-Policy-header wordt verzonden in canvas-apps.

  • ContentSecurityPolicyConfigurationForCanvas beheert het beleid voor canvas met hetzelfde proces dat is beschreven in ContentSecurityPolicyConfiguration hierboven.

  • ContentSecurityPolicyReportUri bepaalt of rapportage moet worden gebruikt. Deze instelling wordt gebruikt door zowel modelgestuurde als canvas-apps. Een geldige tekenreeks stuurt overtredingsrapporten naar het opgegeven eindpunt, in de alleen-rapportmodus als IsContentSecurityPolicyEnabled/IsContentSecurityPolicyEnabledForCanvas is uitgeschakeld. Een lege tekenreeks schakelt rapportage uit. Zie voor meer informatie rapportagedocumentatie.

CSP configureren zonder gebruikersinterface

Vooral voor omgevingen niet in het Power Platform-beheercentrum zoals on-premises configuraties, willen beheerders CSP mogelijk configureren met behulp van scripts om instellingen direct te wijzigen.

CSP inschakelen zonder gebruikersinterface

Stappen:

  • Open browserontwikkeltools terwijl u de modelgestuurde app gebruikt als een gebruiker met bevoegdheden voor het bijwerken van organisatie-entiteiten (Systeembeheerder is een goede optie).
  • Plak en voer het onderstaande script uit in de console.
  • Als u simpelweg CSP wilt inschakelen, geeft u de standaardconfiguratie door - enableFrameAncestors(["'self'"])
  • Als voorbeeld van het inschakelen van extra herkomsten voor het insluiten van de 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!')
}

CSP uitschakelen zonder gebruikersinterface

Stappen:

  • Open browserontwikkeltools terwijl u de modelgestuurde app gebruikt als een gebruiker met bevoegdheden voor het bijwerken van organisatie-entiteiten (Systeembeheerder is een goede optie).
  • Plak en voer het onderstaande script uit in de console.
  • U kunt CSP uitschakelen door het volgende te plakken in de 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!')
}