Споделяне чрез


Политика за защита на съдържание

Правилата за сигурност на съдържанието (CSP) понастоящем се поддържат в управлявани от модели и платна Power Apps. Администраторите могат да контролират дали заглавката на CSP се изпраща и до известна степен какво съдържа. Настройките са на ниво среда, което означава, че ще бъдат приложени към всички приложения в средата, след като бъдат включени.

Всеки компонент от стойността на заглавката на CSP контролира активите, които могат да бъдат изтеглени, и е описан по-подробно в мрежата за разработчици на Mozilla (MDN). Стойностите по подразбиране са, както следва:

Директива Стойност по подразбиране С възможност за персонализиране
script-src * 'unsafe-inline' 'unsafe-eval' No
worker-src 'self' blob: No
style-src * 'unsafe-inline' No
font-src * data: No
frame-ancestors 'self' https://*.powerapps.com Да

Това води до CSP по подразбиране на script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'self' https://*.powerapps.com;. В нашата пътна карта имаме възможност да променяме текущите неадаптивни заглавки.

Предварителни изисквания

  • За приложения на Dynamics 365 Customer Engagement и други приложения, базирани на модели, CSP е наличен само в онлайн среди и в организации с Dynamics 365 Customer Engagement (on-premises) версия 9.1 или по-нова.

Конфигуриране на CSP

CSP може да се превключва и конфигурира чрез Power Platform административния център. Важно е първо да активирате среда за разработка / тестване, тъй като активирането на CSP може да започне да блокира сценарии, ако правилата бъдат нарушени. Ние също така поддържаме „режим само за отчет“, за да позволим по-лесно нарастване на производството.

За да конфигурирате CSP, отидете до Power Platform административния център ->Среди ->Настройки ->Поверителност + Сигурност. Следното изображение показва състоянието по подразбиране на настройките:

Правила за защита на съдържанието настройки по подразбиране

Отчитане

Превключвателят „Разрешаване на отчитане“ контролира дали управляваните от модела и платното приложения изпращат доклади за нарушения. Активирането му изисква да бъде посочена крайна точка. Отчетите за нарушения се изпращат до тази крайна точка, независимо дали CSP се прилага или не (като се използва режим само за отчети, ако CSP не се прилага). За повече информация вижте документацията за отчитане.

Разрешаване на крайна точка за отчитане

Налагане

Прилагането на CSP се контролира независимо за управлявани от модели и платно приложения, за да се осигури детайлен контрол върху политиките. Използвайте управлявания от модела/платното ос, за да промените желания тип приложение.

Превключвателят "Прилагане на правилата за защита на съдържанието" включва правилата по подразбиране за прилагане за дадения тип приложение. Включването на този превключвател променя поведението на приложенията в тази среда, за да се придържат към правилата. Следователно предложеният поток за активиране би бил:

  1. Прилагане в среда за разработка/тест.
  2. Активирайте режима само за отчети в производствения процес.
  3. Прилагане в производството, след като не бъдат докладвани нарушения.

Конфигуриране на директиви

Последният раздел е „Конфигуриране на директиви“. Този раздел ви позволява да контролирате отделни директиви в рамките на правилата. В момента само frame-ancestors могат да бъдат персонализирани.

Конфигуриране на директиви за CSP

Оставянето на директивата по подразбиране превключена използва стойността по подразбиране, зададена в таблицата, показана по-горе в тази статия. Изключването на превключвателя позволява на администраторите да задават стойности по избор за директивата и да ги добавят към стойността по подразбиране. Примерът по-долу задава персонализирани стойности за frame-ancestors. Директивата ще бъде зададена frame-ancestors: 'self' https://*.powerapps.com https://www.foo.com https://www.bar.com в този пример, което означава, че приложението може да бъде хоствано в същия произход https://*.powerapps.comhttps://www.foo.com , но не и https://www.bar.com в друг произход. Използвайте бутона Добавяне, за да добавите записи към списъка, и иконата за изтриване, за да ги премахнете.

Задаване на потребителски CSP директиви

Общи конфигурации

За Microsoft Teams интеграция с помощта на приложението Dynamics 365 добавете следното към frame-ancestors:

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

За Dynamics 365 App for Outlook трябва да добавите произхода на началната страница на frame-ancestors Outlook Web App.

За вграждане Power Apps в Power BI отчети добавете следното към frame-ancestors:

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

Важни съображения

Изключването на директивата по подразбиране и запазването с празен списък изключва директивата напълно и не я изпраща като част от заглавката на отговора на CSP.

Примери

Нека да разгледаме няколко примера за CSP конфигурация:

Пример 1

CSP пример 1

В горния пример:

  • Отчитането е изключено.
  • Налагането, управлявано от модел, е активирано.
    • frame-ancestors е персонализиран за https://www.foo.com и https://www.bar.com
  • Налагането на платно е деактивирано.

Ефективните заглавки биха били:

  • Приложения, управлявани от модел: 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;
  • Приложения за платно: CSP заглавката няма да бъде изпратена.

Пример 2

CSP пример 2

В горния пример:

  • Отчитането е включено.
    • Отчетна крайна точка е зададена на https://www.mysite.com/myreportingendpoint
  • Налагането, управлявано от модел, е активирано.
    • frame-ancestors се запазва по подразбиране
  • Налагането на платно е деактивирано.
    • frame-ancestors се персонализира за https://www.baz.com

Ефективните стойности на CSP ще бъдат:

  • Приложения, задвижвани от модела: 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;
  • Приложения за платно: 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;

Настройки на организация

CSP може да се конфигурира без използване на потребителския интерфейс, като се променят директно следните настройки на организацията:

  • IsContentSecurityPolicyEnabled контролира дали заглавката Content-Security-Policy се изпраща в управлявани от модел приложения.

  • ContentSecurityPolicyConfiguration контролира стойността на частта frame-ancestors (както се вижда по-горе, тя е зададена на 'self' ако ContentSecurityPolicyConfiguration не е зададен). Тази настройка е представена от JSON обект със следната структура – { "Frame-Ancestor": { "sources": [ { "source": "foo" }, { "source": "bar" } ] } }. Това ще се преведе в script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'foo' 'bar';

    • (От MDN) HTTP Content-Security-Policy (CSP) директивата за рамки-предци определя валидни родители, които могат да вграждат страница, използвайки <frame>, <iframe>, <object>, <embed> или <applet>.
  • IsContentSecurityPolicyEnabledForCanvas контролира дали заглавието Content-Security-Policy се изпраща в приложенията за платно.

  • ContentSecurityPolicyConfigurationForCanvas контролира политиката за платно, като използва същия процес, описан в ContentSecurityPolicyConfiguration по-горе.

  • ContentSecurityPolicyReportUri контролира дали трябва да се използва отчитане. Тази настройка се използва както от приложения, управлявани от модел, така и от платно. Валиден низ изпраща отчети за нарушения до указаната крайна точка, като използва режим само за отчети, ако IsContentSecurityPolicyEnabled/IsContentSecurityPolicyEnabledForCanvas е изключен. Празен низ деактивира отчитането. За повече информация вижте документацията за отчитане.

Конфигуриране на CSP без потребителски интерфейс

Особено за среди извън Power Platform административния център, като локален конфигурации, администраторите може да искат да конфигурират CSP с помощта на скриптове за директно модифициране на настройките.

Активиране на CSP без потребителски интерфейс

Стъпки:

  • Отворете инструментите за разработка на браузъра, докато използвате управляваното от модела приложение като потребител с привилегии за актуализиране на организационен обект (системният администратор е добра опция).
  • Поставете и изпълнете скрипта по-долу в конзолата.
  • За да активирате просто CSP, подайте конфигурацията по подразбиране - enableFrameAncestors(["'self'"])
  • Като пример за активиране на допълнителни източници за вграждане на приложението - 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 без потребителски интерфейс

Стъпки:

  • Отворете инструментите за разработка на браузъра, докато използвате управляваното от модела приложение като потребител с привилегии за актуализиране на организационен обект (системният администратор е добра опция).
  • Поставете и изпълнете скрипта по-долу в конзолата.
  • За да деактивирате CSP, поставете в конзолата: 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!')
}