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 basadas en modelos. 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 aplica a todas las aplicaciones del entorno una vez activada.

Nota

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

Cada componente del valor de encabezado CSP controla los activos que se pueden descargar y se describe con más detalle en Red para desarrolladores de Mozilla (MDN). Los valores predeterminados son los siguientes:

Directiva Valor predeterminado Personalizable
script-src * 'unsafe-inline' 'unsafe-eval' blob: data: No
worker-src 'self' blob: data: 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: data:; worker-src 'self' blob: data:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'self' https://*.powerapps.com;.

Modo estricto

El interruptor Strict CSP crea una política de seguridad de contenido que no incluye principalmente caracteres comodín ni directivas no seguras, como unsafe-inline. Cuando Strict CSP está activado, las directivas detalladas en la tabla anterior se convierten en las directivas detalladas en la tabla siguiente. 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.

Nota

Csp estricto solo está disponible actualmente para aplicaciones controladas por modelos.

Directiva Valor predeterminado (controlado por modelos) Personalizable
script-src 'self' blob: data: <platform>'
worker-src 'self' blob: data: No
style-src 'self' 'unsafe-inline' <platform>
font-src 'self' data: <platform>
frame-ancestors 'self' https://*.powerapps.com
img-src 'self' blob: data: <platform>
connect-src 'self' blob: data: wss: <platform>
frame-src 'self' blob: <platform>
base-uri 'none' No
form-action <platform>
default-src '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. También admitimos un modo de solo informe para permitir un aumento más sencillo en producción.

Para configurar CSP:

  1. Inicie sesión en el Centro de administración de Power Platform.
  2. En el panel de navegación, seleccione Gestionar y, a continuación, en el panel Gestionar, 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 y 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. Es necesario especificar un punto de conexión para habilitarlo. Los informes de infracciones se envían a este punto de conexión independientemente de si CSP se aplica o no (usando el modo de solo informe si CSP no se aplica). 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, el flujo de habilitación sugerido sería:

  1. Aplicar en un entorno de desarrollo/prueba.
  2. Habilite el modo de solo informe en producción.
  3. Hacer cumplir en producción una vez que no se informen infracciones.

Configurar directivas

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

Configure directivas CSP.

Si se deja activada la directiva predeterminada, se usa el valor predeterminado especificado en la tabla. Desactivar la opción de alternancia permite a los administradores especificar valores personalizados para la directiva y anexarlos al valor predeterminado. El siguiente ejemplo establece valores personalizados para frame-ancestors. La directiva se establecería en frame-ancestors: 'self' https://*.powerapps.com https://www.foo.com https://www.bar.com en este ejemplo, lo que significa que la aplicación podría hospedarse en el mismo origen, https://*.powerapps.com, https://www.foo.com y 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

Echemos un vistazo a un par de ejemplos de configuraciones de CSP.

Ejemplo 1: informes desactivados

Ejemplo 1 de CSP.

En el ejemplo:

  • Los informes están desactivados.
  • La aplicación basada en modelos está habilitada.
    • frame-ancestors está personalizado para https://www.foo.com y https://www.bar.com
  • La aplicación de lienzo está deshabilitada.

Los encabezados efectivos serían:

  • 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.foo.com https://www.bar.com;
  • Aplicaciones de lienzo: no se enviaría el encabezado CSP.

Ejemplo 2: informes activados

Ejemplo 2 de CSP.

En el ejemplo:

  • Los informes están activados.
    • El extremo de informes está establecido en https://www.mysite.com/myreportingendpoint
  • 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.baz.com

Los valores CSP efectivos serían:

  • 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 'self' https://*.powerapps.com; report-uri https://www.mysite.com/myreportingendpoint;
  • 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.baz.com; report-uri https://www.mysite.com/myreportingendpoint;

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 arriba, se establece en 'self' si ContentSecurityPolicyConfiguration no está establecido). Esta configuración se define usando un objeto JSON con la siguiente estructura: { "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!')
}