Поділитися через


Політика безпеки вмісту

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

Кожний компонент значення заголовка CSP керує активами, які можна завантажувати та описувати більш докладно в мережі Mozilla Developer Network (MDN). Значення за замовчуванням вказані нижче

Директива Стандартне значення Настроювані
script-src * 'unsafe-inline' 'unsafe-eval' No
Робітник-СРС 'self' blob: No
style-src * 'unsafe-inline' No
font-src * data: No
Рамки-предки '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 та інших програм, орієнтованих на модель, CSP доступний лише в онлайнових середовищах і організаціях із Dynamics 365 customer engagement (локальний) версії 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.com https://www.foo.com але https://www.bar.com, але не в іншому джерелі. Натисніть кнопку «Додати», щоб додати записи до списку, а потім піктограму видалення, щоб їх видалити.

Налаштування користувальницьких директив CSP

Поширені конфігурації

Для Microsoft Teams інтеграції за допомогою програми Dynamics 365 додайте такі параметри до frame-ancestors:

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

Для цього Dynamics 365 App for Outlook додайте наступне до frame-ancestors:

  • Походження домашньої сторінки веб-застосунку Веб-застосунок Outlook Web App
  • https://outlook.office.com
  • https://outlook.office365.com

Для вбудовування Power Apps у Power BI звіти додайте до frame-ancestors таких параметрів:

  • https://app.powerbi.com
  • https://ms-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' if ContentSecurityPolicyConfiguration is not set). Цей параметр представлений об’єктом 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-ancestors визначає дійсні батьківські одиниці, що можуть вбудовувати сторінку за допомогою <frame>, <iframe>, <object>, <embed>, або <applet>.
  • IsContentSecurityPolicyEnabledForCanvas визначає, чи надсилається заголовок Content-Security-Policy у програмах canvas.

  • ContentSecurityPolicyConfigurationForCanvas керує політикою для canvas за допомогою того самого процесу, що описано вище 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!')
}