Partilhar via


Content security policy (Política de segurança de conteúdos)

A Política de Segurança de Conteúdo (CSP) é atualmente suportada em aplicações orientadas por modelos, canvas e código. Este artigo explica como configurar o CSP para aplicações orientadas a modelos e canvas. Para aplicações de código CSP, consulte a documentação das aplicações de código. Os admins podem controlar se o cabeçalho da CSP é enviado e, até certo ponto, o que contém. As definições estão ao nível do ambiente, o que significa que são aplicadas a todas as aplicações do ambiente uma vez ativadas.

Nota

A política de segurança de conteúdo só se aplica a ambientes que usam o Dataverse.

Cada componente do valor do cabeçalho do CSP controla os ativos que podem ser descarregados. A Mozilla Developer Network (MDN) fornece descrições mais detalhadas. Os valores predefinidos são os seguintes:

Diretiva Valor predefinido Personalizável
script-src * 'unsafe-inline' 'unsafe-eval' blob: Não
worker-src 'self' blob: Não
style-src * 'unsafe-inline' Não
font-src * data: Não
frame-ancestors 'self' https://*.powerapps.com Sim

Esta configuração resulta num CSP predefinido 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 restrito

O comutador CSP estrito cria um CSP que, na maioria das vezes, não inclui carateres universais ou diretivas inseguras, como unsafe-inline. Ao ativar a política CSP Estrita, as diretivas anteriores tornam-se as seguintes diretivas detalhadas nesta secção. A <platform> notação significa que os domínios da plataforma são fornecidos conforme exigido pelo produto. Os domínios desta secção podem mudar ao longo do tempo à medida que o produto cresce.

Diretiva Valor padrão (orientado por modelo) Valor padrão (canvas) Personalizável
script-src 'self' blob: <platform>' 'self' <platform>' Sim
worker-src 'self' blob: 'self' blob: Não
style-src 'self' 'unsafe-inline' <platform> 'self' 'unsafe-inline' <platform> Sim
font-src 'self' data: <platform> 'self' data: <platform> Sim
frame-ancestors 'self' https://*.powerapps.com 'self' https://*.powerapps.com Sim
IMG-SRC 'self' blob: data: <platform> 'self' data: <platform> Sim
connect-src 'self' blob: data: wss: <platform> 'self' blob: <platform> Sim
frame-src 'self' blob: <platform> 'self' <platform> Sim
base URI 'none' N/A Não
form-action <platform> N/A Sim
default-src 'self' 'self' Não

Pré-requisitos

Para aplicações Dynamics 365 Customer Engagement e outras aplicações condicionadas por modelo, o CSP só está disponível em ambientes online e em organizações com o Dynamics 365 Customer Engagement (on-premises), versão 9.1 ou posterior.

Configurar CSP

Pode alternar e configurar o CSP através do centro de administração do Power Platform. É importante ativar um ambiente de desenvolvimento/teste primeiro, pois ativar o CSP pode começar a bloquear cenários se a política for violada. O centro de administração também suporta um modo só de relatório para permitir um aumento mais fácil na produção.

Siga estes passos para configurar o CSP:

  1. Inicie sessão no Centro de administração do Power Platform.
  2. No painel de navegação, selecione Gerenciar. No painel Gerir, selecione Ambientes.
  3. Na página Ambientes selecione um ambiente.
  4. Na barra de comando, selecione Definições.
  5. Expanda o Produto e, em seguida, selecione Privacidade + Segurança.

A imagem seguinte mostra o estado predefinido das definições:

Predefinições da política de segurança de conteúdos.

A Denunciar

O comutador Ativar relatórios controla se as aplicações condicionadas por modelo e as aplicações de tela enviam relatórios de violação. Para o ativar, especifique um endpoint. A aplicação envia relatórios de violações para este endpoint, independentemente de o CSP ser aplicado ou não. Se o CSP não for aplicado, a aplicação usa o modo apenas de relatório. Para mais informações, consulte a documentação sobre relatórios.

Ative o comutador de relatórios.

Imposição

A imposição da CSP é controlada de forma independente, para que as aplicações condicionadas por modelo e as aplicações de tela forneçam controlo granular sobre as políticas. Utilize o pivô condicionado por modelo/de tela para modificar o tipo de aplicação pretendido.

A alternância Impor política de segurança de conteúdo ativa a política padrão para imposição para determinado tipo de aplicativo. A ativação deste comutador altera o comportamento das aplicações neste ambiente para que adiram à política. Portanto, siga este fluxo de habilitação sugerido:

  1. Aplicar a política num ambiente de desenvolvimento ou teste.
  2. Ativar o modo só de relatório em produção.
  3. Aplicar a política na produção assim que não forem reportadas infrações.

Configure diretivas

A seção Configurar diretivas permite controlar diretivas individuais dentro da política. Atualmente, só pode personalizar a frame-ancestors diretiva.

Configurar diretivas da CSP.

Se deixares a diretiva padrão ativada, usas o valor padrão especificado na tabela. Se desativares o toggle, podes especificar valores personalizados para a diretiva e adicioná-los ao valor padrão. O exemplo seguinte define valores personalizados para frame-ancestors. A diretiva está definida para frame-ancestors: 'self' https://*.powerapps.com https://www.foo.com https://www.bar.com neste exemplo. Esta configuração significa que a aplicação pode ser alojada na mesma origem, https://*.powerapps.com, https://www.foo.com, e https://www.bar.com, mas não nas outras origens. Utilize o botão Adicionar para adicionar entradas à lista e o ícone Eliminar para as remover.

Definir diretivas da CSP personalizadas.

Configurações comuns

Para a integração do Microsoft Teams utilizando a aplicação Dynamics 365, adicione o seguinte ao frame-ancestors:

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

Para o Dynamics 365 App for Outlook, adicione o seguinte a frame-ancestors:

  • Origem da home page do Outlook Web App
  • https://outlook.office.com
  • https://outlook.office365.com

Para incorporar o Power Apps em relatórios do Power BI, adicione o seguinte a frame-ancestors:

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

Considerações importantes

Desativar a diretiva predefinida e guardar com uma lista vazia, desativa a diretiva por completo e não a envia como parte do cabeçalho de resposta da CSP.

Exemplos de configuração do CSP

Aqui estão alguns exemplos de configurações CSP.

Exemplo 1 - relatórios desativados

Exemplo 1 de CSP, orientado por modelos

Exemplo CSP 1, tela

No exemplo:

  • Os relatórios estão desativados.
  • A imposição condicionada por modelo está ativada.
    • frame-ancestors é personalizada para https://www.contoso.com e https://www.fabrikam.com.
  • A imposição de tela está desativada.

Os cabeçalhos efetivos são:

  • Aplicações condicionadas por modelo: 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;
  • Aplicações Canvas: o cabeçalho CSP não é enviado.

Exemplo 2 - relatórios ativados

Exemplo 2 de CSP, orientado por modelos

Exemplo CSP 2, tela

No exemplo:

  • Os relatórios estão ativados.
    • O ponto final de relatórios está definido como https://contoso.com/reporting-endpoint
  • A imposição condicionada por modelo está ativada.
    • frame-ancestors é mantido como a predefinição
  • A imposição de tela está desativada.
    • frame-ancestors é personalizado para https://www.contoso.com

Os valores efetivos do CSP são:

  • Aplicações condicionadas por modelo: 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;
  • Aplicações de tela: 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 as definições da organização diretamente

Pode configurar o CSP sem usar a interface do utilizador modificando essas definições da organização diretamente:

  • IsContentSecurityPolicyEnabled controla se o cabeçalho Content-Security-Policy é enviado em aplicações condicionadas por modelo.

  • ContentSecurityPolicyConfiguration controla o valor da parte frame-ancestors (como visto anteriormente, define como 'self' se ContentSecurityPolicyConfiguration não estiver definido). Defina este cenário usando um objeto JSON com a seguinte estrutura – { "Frame-Ancestor": { "sources": [ { "source": "foo" }, { "source": "bar" } ] } }. Esta configuração traduz-se em script-src * 'unsafe-inline' 'unsafe-eval'; worker-src 'self' blob:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'foo' 'bar';

    • (Da MDN) A diretiva frame-ancestors da Content-Security-Policy (CSP) HTTP especifica principais válidos que podem incorporar uma página utilizando <frame>, <iframe>, <object>, <embed> ou <applet>.
  • IsContentSecurityPolicyEnabledForCanvas controla se o cabeçalho Content-Security-Policy é enviado em aplicações de tela.

  • ContentSecurityPolicyConfigurationForCanvas controla a política para tela usando o mesmo processo descrito em ContentSecurityPolicyConfiguration.

  • ContentSecurityPolicyReportUri controla se os relatórios devem ser utilizados. Esta definição é utilizada por aplicações condicionadas por modelos e aplicações de tela. Uma cadeia válida envia relatórios de violação para o ponto final especificado, utilizando o modo só de relatório se IsContentSecurityPolicyEnabled/IsContentSecurityPolicyEnabledForCanvas estiver desligado. Uma cadeia vazia desativa os relatórios. Para mais informações, consulte a documentação sobre relatórios.

Configurar a CSP sem IU

Principalmente para ambientes que não estão no centro de administração do Power Platform, tal como configurações no local, os admins poderão pretender configurar a CSP com scripts para modificar diretamente as definições.

Ativar CSP sem interface do utilizador

Siga estes passos para ativar o CSP sem interface do utilizador:

  • Abra ferramentas de programador do browser ao utilizar a aplicação condicionada por modelo como um utilizador com privilégios de atualização de entidades da organização (Administrador de Sistema é uma boa opção).
  • Cole e execute o script que se segue na consola.
  • Para ativar o CSP, passe a configuração predefinida — enableFrameAncestors(["'self'"])
  • Como exemplo de ativar outras origens para incorporar a aplicação — 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!')
}

Desativar CSP sem interface do utilizador

Siga estes passos para desativar o CSP sem interface do utilizador:

  • Abra ferramentas de programador do browser ao utilizar a aplicação condicionada por modelo como um utilizador com privilégios de atualização de entidades da organização (Administrador de Sistema é uma boa opção).
  • Cole e execute o script que se segue na consola.
  • Para desativar o CSP, cole na 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!')
}