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 baseadas em modelos e aplicações de tela. Os admins podem controlar se o cabeçalho da CSP é enviado e, até certo ponto, o que contém. As configurações estão no nível do ambiente, o que significa que ele é aplicado a todos os aplicativos no ambiente uma vez ativado.

Nota

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

Cada componente do valor de cabeçalho da CSP controla os recursos que podem ser transferidos e é descrito em mais detalhe na Rede de Programadores da Mozilla (MDN). Os valores predefinidos são os seguintes:

Diretiva Valor predefinido Personalizável
script-src * 'unsafe-inline' 'unsafe-eval' blob: data: Não
worker-src 'self' blob: data: 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: data:; worker-src 'self' blob: data:; style-src * 'unsafe-inline'; font-src * data:; frame-ancestors 'self' https://*.powerapps.com;.

Modo restrito

A alternância CSP restrito cria uma política de segurança de conteúdo que, na maioria das vezes, não inclui carateres universais nem diretivas inseguras, como unsafe-inline. Quando o CSP estrito está ativado, as diretivas detalhadas na tabela anterior se transformam nas diretivas detalhadas na tabela a seguir. A <platform> notação significa que os domínios da plataforma são fornecidos conforme exigido pelo produto. Os domínios nesta seção podem mudar ao longo do tempo à medida que o produto cresce.

Nota

Atualmente, o CSP estrito só está disponível para aplicativos controlados por modelo.

Diretiva Valor padrão (orientado por modelo) Personalizável
script-src 'self' blob: data: <platform>' Sim
worker-src 'self' blob: data: Não
style-src 'self' 'unsafe-inline' <platform> Sim
font-src 'self' data: <platform> Sim
frame-ancestors 'self' https://*.powerapps.com Sim
IMG-SRC 'self' blob: data: <platform> Sim
connect-src 'self' blob: data: wss: <platform> Sim
frame-src 'self' blob: <platform> Sim
base URI 'none' Não
form-action <platform> Sim
default-src '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. Também suportamos um modo só de relatório para permitir um aumento mais fácil na produção.

Para configurar CSP:

  1. Inicie sessão no Centro de administração do Power Platform.
  2. No painel de navegação, selecione Gerir e, em seguida, no painel Gerir, selecione Ambientes.
  3. Na página Ambientes selecione um ambiente.
  4. Na barra de comando, selecione Definições.
  5. Expanda 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. É necessário especificar um ponto final para ativá-lo. Os relatórios de violação são enviados para este ponto final, independentemente de a CSP ser ou não imposta (utilizando o modo só de relatório se a CSP não for imposta). 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. Assim, o fluxo de ativação sugerido seria:

  1. Impor num ambiente dev/teste.
  2. Ativar o modo só de relatório em produção.
  3. Impor na produção depois de não ser reportada qualquer violação.

Configure diretivas

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

Configurar diretivas da CSP.

Deixar a diretiva predefinida ativa utiliza o valor predefinido especificado na tabela. Desligar o alternador permite que os administradores especifiquem valores personalizados para a diretiva e os acrescentem ao valor predefinido. O exemplo abaixo define valores personalizados para o frame-ancestors. A diretiva seria definida como frame-ancestors: 'self' https://*.powerapps.com https://www.foo.com https://www.bar.com neste exemplo, o que significa que a aplicação poderia estar alojada na mesma origem, https://*.powerapps.com, https://www.foo.com e https://www.bar.com, mas não no caso de 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

Vejamos alguns exemplos de configurações de CSP.

Exemplo 1 - relatórios desativados

Exemplo de CSP 1.

No exemplo:

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

Os cabeçalhos eficazes seriam:

  • 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.foo.com https://www.bar.com;
  • Aplicações de tela: o cabeçalho da CSP não seria enviado.

Exemplo 2 - relatórios ativados

Exemplo de CSP 2.

No exemplo:

  • Os relatórios estão ativados.
    • O ponto final de relatórios está definido como https://www.mysite.com/myreportingendpoint
  • 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.baz.com

Os valores da CSP eficazes seriam:

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

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 acima, define como 'self' if ContentSecurityPolicyConfiguration não está definido). Esta definição é definida utilizando 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!')
}