Boas práticas de segurança em sites React
Tags: javascript, react, security, webdev
Published: 2022-03-14 21:13:32

## Proteção XSS com data binding

Use o data binding com chaves {} e o React escapará automaticamente dos valores para proteger contra ataques XSS. Observe que essa proteção ocorre apenas ao renderizar textContent e não ao renderizar atributos HTML.

- Use a sintaxe JSX `{}` para colocar dados em seus elementos. Ex. `<div>{data}</div>`.
- Evite valores de atributos dinâmicos sem validação. Não use `...`

---

## URLs perigosas

As URLs podem conter conteúdo de script dinâmico via javascript. Valide suas URLs antes de usar.

- Use a validação para garantir que seus links sejam http ou https e evitar injeção de script baseada em URL. Valide a URL usando uma função de análise nativa.

```
function validateURL(url) {
	const parsed = new URL(url)
	return ['https:', 'http:'].includes(parsed.protocol)
}
<a href={validateURL(url) ? url : ''}>This is a link!</a>
```

---

## Renderizando HTML

É possível inserir HTML diretamente nos nós do DOM, usando o `dangerouslySetInnerHTML`. Qualquer conteúdo inserido desta forma deve ser previamente sanitizado.

- Use alguma lib de sanitize como a **DOMPurify** em quaisquer valores antes de colocá-los no `dangerouslySetInnerHTML`.

```
import purify from "dompurify";

<div dangerouslySetInnerHTML={{__html:purify.sanitize(data)}} />
```

---

## Acesso direto ao DOM

O acesso ao DOM para injetar conteúdo diretamente nos nós deve ser evitado. Use `dangerouslySetInnerHTML` se você precisar injetar HTML, mas primeiro deve sanitiza-lo antes, usando por exemplo o **DOMPurify.**

- Evite usar refs e `findDomNode()` para acessar elementos do **DOM**, injetar conteúdo diretamente via `innerHTML`, propriedades e métodos semelhantes.

---

## Server-side Rendering

O data binding fornecerá escape automático de conteúdo ao usar funções de renderização do lado do servidor, como `ReactDOMServer.renderToString()` e `ReactDOMServer.renderToStaticMarkup()`.

- Evite concatenar strings na saída de `renderToString()` e `renderToStaticMarkup()` antes de enviar as strings ao cliente para renderização.

---

## Vulnerabilidades em dependências

Algumas versões de componentes de terceiros podem conter problemas de segurança. Verifique suas dependências e atualize quando as versões mais novas estiverem disponíveis.

- Use uma ferramenta gratuita como o **Snyk** para verificar vulnerabilidades.
- Corrija vulnerabilidades **automaticamente com o Snyk** integrado ao seu **CI/CD** para receber correções automatizadas.

`$ npx snyk test`

---

## Estado JSON

É comum enviar **JSON** em páginas React renderizadas no lado do servidor. Sempre valide caracteres inválidos para **evitar ataques de injeção**.

- Evite valores de **HTML** sem escape em objetos **JSON**.

```
<script>
//[https://redux.js.org/recipes/server-rendering/#security-considerations](https://redux.js.org/recipes/server-rendering/#security-considerations)
  window.PRELOADED_STATE = ${JSON.stringify(preloadedState).replace(/</g,'\\u003c')}
</script>
```

---

## Versões Vulneráveis do React

O React teve algumas vulnerabilidades de **alta gravidade** no passado, entao, é uma boa ideia manter-se atualizado com a versão mais recente.

- Evite versões vulneráveis do **react** e **react-dom,** verificando se você está na versão mais recente usando o **npm upgrade**.
- Use o **Snyk** para **atualizar automaticamente** para novas versões quando existirem vulnerabilidades nas versões que você está usando.

---

## Linters

Instale configurações e plug-ins de linters que **detectarão automaticamente problemas** de segurança em seu código e oferecerão **dicas de correção**.

- Use a **configuração de segurança** para detectar problemas em nossa base de código (Instalar o plugin do **Snyk** no **VSCode**).
- Configure um **hook** de **pre-commit** que falha quando problemas de linter relacionados à segurança são detectados, usando uma biblioteca como **husky**.

---

## Dependências de código sujo

Códigos de libs sao frequentemente usados para **realizar operações**, como **inserir diretamente o HTML no DOM**. Revise o código da lib **manualmente** ou com linters para detectar o uso inseguro dos mecanismos de segurança do **React**.

- Evite bibliotecas que usam `dangerouslySetInnerHTML`, `innerHTML`, **URLs inválidas** ou outros **padrões inseguros**.
- Use **linters** em sua pasta **node_modules** para detectar **padrões inseguros** em suas libs.