Compartir a través de


Directiva de seguridad de contenido

La directiva de seguridad de contenido (CSP) se admite actualmente en aplicaciones de lienzo y código basadas en modelos. En este artículo se explica cómo configurar CSP para aplicaciones de lienzo y controladas por modelos. Para las aplicaciones de código CSP, consulte la documentación de aplicaciones de código. Los administradores pueden controlar si se envía el encabezado CSP y, hasta cierto punto, qué contiene. La configuración está en el nivel de entorno, lo que significa que se aplican a todas las aplicaciones del entorno una vez activadas.

Nota

La directiva de seguridad de contenido solo se aplica a los entornos que usan Dataverse.

Cada componente del valor del encabezado CSP controla los recursos que se pueden descargar. Mozilla Developer Network (MDN) proporciona descripciones más detalladas. Los valores predeterminados son los siguientes:

Directiva Valor predeterminado Personalizable
script-src * 'unsafe-inline' 'unsafe-eval' blob: No
worker-src 'self' blob: No
style-src * 'unsafe-inline' No
font-src * data: No
frame-ancestors 'self' https://*.powerapps.com

Esta configuración da como resultado un CSP predeterminado de script-src * 'unsafe-inline' 'unsafe-eval' blob: ; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'self' https://*.powerapps.com;.

Modo estricto

La alternancia CSP estricto crea un CSP que en su mayoría no incluye comodines ni directivas inseguras, como unsafe-inline. Al activar Strict CSP, las directivas anteriores se convierten en las siguientes directivas detalladas en esta sección. La <platform> notación significa que el producto proporciona los dominios de plataforma según sea necesario. Los dominios de esta sección pueden cambiar con el tiempo a medida que crece el producto.

Directiva Valor predeterminado (controlado por modelos) Valor predeterminado (lienzo) Personalizable
script-src 'self' blob: <platform>' 'self' <platform>'
worker-src 'self' blob: 'self' blob: No
style-src 'self' 'unsafe-inline' <platform> 'self' 'unsafe-inline' <platform>
font-src 'self' data: <platform> 'self' data: <platform>
frame-ancestors 'self' https://*.powerapps.com 'self' https://*.powerapps.com
img-src 'self' blob: data: <platform> 'self' data: <platform>
connect-src 'self' blob: data: wss: <platform> 'self' blob: <platform>
frame-src 'self' blob: <platform> 'self' <platform>
base-uri 'none' N/A No
form-action <platform> N/A
default-src 'self' 'self' No

Requisitos previos

Para las aplicaciones de involucración del cliente Dynamics 365 y otras aplicaciones basadas en modelos, CSP solo está disponible en entornos en línea y en organizaciones con Dynamics 365 Customer Engagement (on-premises), versión 9.1 o una versión posterior.

Configurar CSP

Puede alternar y configurar CSP a través del Centro de administración de Power Platform. Es importante habilitar primero un entorno de desarrollo y prueba, ya que habilitar CSP podría comenzar a bloquear escenarios si se infringe la directiva. El centro de administración también admite un modo de solo informe para permitir un aumento más sencillo en producción.

Siga estos pasos para configurar CSP:

  1. Inicie sesión en el Centro de administración de Power Platform.
  2. En el panel de navegación, seleccione Administrar. En el panel Administrar, seleccione Entornos.
  3. Seleccione un entorno en la página Entornos.
  4. Seleccione Configuración en la barra de comandos.
  5. Expanda Producto y luego seleccione Privacidad + Seguridad.

La siguiente imagen muestra el estado predeterminado de la configuración:

Configuración predeterminada de la directiva de seguridad de contenido.

Denunciando

La alternancia Habilitar informes controla si las aplicaciones basadas en modelos y de lienzo envían informes de infracciones. Para habilitarlo, especifique un punto de conexión. La aplicación envía informes de infracciones a este punto de conexión, independientemente de si csp se aplica o no. Si no se aplica CSP, la aplicación usa el modo de solo informe. Para obtener más información, consulte la documentación de informes.

Habilite la opción de informes.

Aplicación

La aplicación de CSP se controla de forma independiente para aplicaciones de lienzo y basadas en modelos para proporcionar un control granular sobre las políticas. Use el pivote basado en modelo/lienzo para modificar el tipo de aplicación previsto.

La opción de alternancia Habilitar directiva de seguridad de contenido activa la directiva predeterminada de aplicación para el tipo de aplicación determinado. Activar esta opción cambia el comportamiento de las aplicaciones en este entorno para cumplir con la política. Por lo tanto, siga este flujo de habilitación sugerido:

  1. Aplique la directiva en un entorno de desarrollo o prueba.
  2. Habilite el modo de solo informe en producción.
  3. Aplique la directiva en producción una vez que no se notifique ninguna infracción.

Configurar directivas

La sección Configurar directivas permite controlar directivas individuales dentro de la directiva. Actualmente, solo puede personalizar la frame-ancestors directiva.

Configure directivas CSP.

Si deja activada la directiva predeterminada, usa el valor predeterminado especificado en la tabla. Si desactiva el interruptor, puede especificar valores personalizados para la directiva y agregarlos al valor predeterminado. En el ejemplo siguiente se establecen valores personalizados para frame-ancestors. La directiva se establece en frame-ancestors: 'self' https://*.powerapps.com https://www.foo.com https://www.bar.com en este ejemplo. Esta configuración significa que la aplicación se puede hospedar en el mismo origen, https://*.powerapps.com, https://www.foo.comy https://www.bar.com, pero no en otros orígenes. Utilice el botón Agregar para agregar entradas a la lista y el icono Eliminar para eliminarlas.

Configuración de directivas CSP personalizadas.

Opciones de configuración comunes

Para la integración de Microsoft Teams mediante la aplicación Dynamics 365, agregue lo siguiente a frame-ancestors:

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

Para Dynamics 365 App for Outlook, agregue lo siguiente a frame-ancestors:

  • El origen de la página de inicio de Outlook Web App
  • https://outlook.office.com
  • https://outlook.office365.com

Para insertar Power Apps en informes de Power BI, agregue lo siguiente a frame-ancestors:

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

Consideraciones importantes

Desactivar la directiva predeterminada y guardar con una lista vacía apaga la directiva por completo y no lo envía como parte del encabezado de respuesta de CSP.

Ejemplos de configuración de CSP

Estos son un par de ejemplos de configuraciones de CSP.

Ejemplo 1: informes desactivados

Ejemplo 1 de CSP, controlado por modelos

Ejemplo 1 de CSP, lienzo

En el ejemplo:

  • Los informes están desactivados.
  • La aplicación basada en modelos está habilitada.
    • frame-ancestors se personaliza en https://www.contoso.com y https://www.fabrikam.com.
  • La aplicación de lienzo está deshabilitada.

Los encabezados efectivos son:

  • Aplicaciones basadas en modelos: 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.contoso.com https://www.fabrikam.com;
  • Aplicaciones de lienzo: no se envía el encabezado CSP.

Ejemplo 2: informes activados

Ejemplo 2 de CSP, controlado por modelos

Ejemplo 2 de CSP, lienzo

En el ejemplo:

  • Los informes están activados.
    • El extremo de informes está establecido en https://contoso.com/reporting-endpoint
  • La aplicación basada en modelos está habilitada.
    • frame-ancestors se mantiene de manera predeterminada
  • La aplicación de lienzo está deshabilitada.
    • frame-ancestors está personalizado a https://www.contoso.com

Los valores de CSP efectivos son:

  • Aplicaciones basadas en modelos: Content-Security-Policy: script-src * 'unsafe-inline' 'unsafe-eval' blob:; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'self' https://*.powerapps.com; report-uri https://contoso.com/reporting-endpoint;
  • Aplicaciones de lienzo: 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.contoso.com; report-uri https://contoso.com/reporting-endpoint;

Modificar la configuración de la organización directamente

Puede configurar CSP sin usar la interfaz de usuario modificando directamente estas configuraciones de la organización:

  • IsContentSecurityPolicyEnabled controla si el encabezado Content-Security-Policy se envía en aplicaciones basadas en modelo.

  • ContentSecurityPolicyConfiguration controla el valor de la parte de los ancestros del marco (como se vio anteriormente, se establece en 'self' si no se establece ContentSecurityPolicyConfiguration). Defina esta configuración mediante un objeto JSON con la estructura siguiente: { "Frame-Ancestor": { "sources": [ { "source": "foo" }, { "source": "bar" } ] } }. Esta configuración se traduce en script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'foo' 'bar';

    • (De MDN) La directiva HTTP Content-Security-Policy (CSP) frame-ancestors (CSP) especifica elementos primarios válidos que pueden incrustarse en una página usando <frame>, <iframe>, <object>, <embed> o <applet>.
  • IsContentSecurityPolicyEnabledForCanvas controla si el encabezado Content-Security-Policy se envía en aplicaciones de lienzo.

  • ContentSecurityPolicyConfigurationForCanvas controla la directiva para el lienzo utilizando el mismo proceso descrito en ContentSecurityPolicyConfiguration.

  • ContentSecurityPolicyReportUri controla si se deben utilizar los informes. Esta configuración se usa tanto en las aplicaciones basadas en modelos como en las aplicaciones de lienzo. Una cadena válida envía informes de infracción al punto de conexión especificado, utilizando el modo de solo informe si IsContentSecurityPolicyEnabled/IsContentSecurityPolicyEnabledForCanvas esta desactivado. Una cadena vacía deshabilita los informes. Para obtener más información, consulte la documentación de informes.

Configurar CSP sin IU

Especialmente para entornos que no están en el Centro de administración de Power Platform, como configuraciones locales, es posible que los administradores deseen configurar CSP mediante scripts para modificar directamente la configuración.

Habilitar CSP sin UI

Siga estos pasos para habilitar CSP sin UI:

  • Abra las herramientas de desarrollo del navegador mientras usa la aplicación basada en modelos como un usuario con privilegios de actualización de entidades de la organización (administrador del sistema es una buena opción).
  • Pegue y ejecute el siguiente script en la consola.
  • Para habilitar simplemente CSP, pase la configuración predeterminada: enableFrameAncestors(["'self'"])
  • Un ejemplo de habilitar otros orígenes para incrustar en la aplicación: 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!')
}

Deshabilitar CSP sin UI

Siga estos pasos para deshabilitar CSP sin UI:

  • Abra las herramientas de desarrollo del navegador mientras usa la aplicación basada en modelos como un usuario con privilegios de actualización de entidades de la organización (administrador del sistema es una buena opción).
  • Pegue y ejecute el siguiente script en la consola.
  • Para deshabilitar CSP, pegue en la consola: 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!')
}