Como sanitizar(limpar) os erros no Express para evitar vazamento de informações importantes
Tags: security, node, javascript, errors
Published: 2022-10-14 14:14:16

Fala povo bonito, como estão? Espero que estejam bem 😀

Hoje estou passando aqui para dar uma dica a respeito de como tratar erros inesperados no Express, ajudando a mitigar uma falha grave que ocorre em várias api’s hoje em dia, essa brecha é a ***Sensitive Data Exposure***, ou exposição de dados sensíveis. Então bora conferir essa dica? 🙂

## Sensitive Data Exposure

Essa brecha é muito conhecida no mundo de cybersecurity e existe a bastante tempo.
A exposição de dados sensíveis ocorre quando um ataque, ou até mesmo uma falha de um usuário legítimo, acaba tendo expondo informações que não deveriam ser acessadas. Essas informações podem ser dados de outros usuários, dados de outros serviços que conversem com a api com a qual o usuário está interagindo ou até mesmo a própria api que está sendo acessada.
Considere, por exemplo, que ao trocar o id do usuário em uma requisição GET um usuário consegue acessar as informações de perfil de outro usuário. Outra situação ruim que pode acontecer é quando a sua api acaba gerando algum erro e então ao retornar o erro para o usuário sua api envia junto informações confidenciais, como por exemplo tokens de outras apis, informações do .env da api ou outro tipo de informação que não deveria estar sendo enviada.
Esses são apenas alguns exemplos. Resumindo, ***Sensitive Data Exposure*** ocorre sempre que um usuário acaba tendo acesso a informações que não deveria devido a alguma falha na lógica de implementação da api que está sendo acessada.
Sugiro fortemente uma leitura muito mais profunda no site da [OWASP (Web Application Security Project)](https://owasp.org/www-project-top-ten/2017/A3_2017-Sensitive_Data_Exposure) e também no site do [Mitre](https://cwe.mitre.org/data/definitions/200.html), que é outra fonte muito boa para obter informações a respeito dessa e de outras vulnerabilidades.
É muito difícil tratar todos os pontos onde é possível haver vazamento de informações, pois ela pode ocorrer em vários estágios durante o caminho da informação, pode ser durante um erro, pode ser durante uma autenticação, enfim são vários pontos, e cada um desses precisa ser devidamente tratado.
Com isso em mente vamos focar em tratar os erros não previstos que ocorrerem em nossa api. 
Causar erros não esperados é uma das formas que os atacantes possuem para tentar fazer “vazar” informações confidenciais. Por isso é importante tentar tratar todos os erros em nível de função, o que é muito difícil, por isso uma das formas de tentar tratar essas situações não previstas é capturando o erro e tratando-o antes de que ele seja enviado para o usuário. E é isso que faremos!!!

## error-sanitizer

***error-sanitizar*** é um middleware para o framework Express que criei para ajudar a sanitizar os erros que não foram capturados pelos desenvolvedores na hora de codificar as apis. Ele funciona limpando informações sensíveis das mensagens de erro antes de enviá-los para os usuários.
Ele também é capaz de remover a stack do erro, para que o usuário que está chamando não tenha conhecimento de como é a estrutura interna de arquivos e chamadas de procedimentos da api.
Além disso, ele também faz a remoção de variáveis de .env que possivelmente poderiam acabar vazando na mensagem de erro. 
Por fim, ele também permite que você adicione novas variáveis à blacklist que ele utiliza para fazer a remoção desses valores das mensagens, lhe dando a opção ainda de poder remover alguma variável da blacklist bastando apenas passar seu valor para a função de remoção de variáveis da lista de bloqueio.
É muito importante que você tenha em mente que ele não é uma bala de prata, ou seja, este middleware sozinho não vai resolver todos os problemas, como foi dito antes, ***sensitive data exposure*** é um problema que, para ser mitigado, precisa de ações em várias frentes no que diz respeito à construção da sua api. Porém ele pode ser de grande ajuda para começar a fazer o tratamento dessa questão 🙂

## Como instalar?

Instalar o package é muito simples, basta executar:

``` npm i --save error-sanitizer```

Esta é a página dele no npm: [https://www.npmjs.com/package/error-sanitizer](https://www.npmjs.com/package/error-sanitizer)

## Como usar?

Usar o ***error-sanitizer*** é muito fácil segue um exemplo que como ele pode ser utilizado.

````
const Express = require("express");

const { init, addVariableToBlackList, sanitizeErrors, removeFromBlacklist } = require("error-sanitizer");

function simpleErrorCallback(error) {
  console.log(`Essa callback será chamada sempre que um erro não tratado for capturado pelo middlware. Importante notar que ela será chamada ANTES do objeto de ***error*** ser modificado, para o caso em que você quer enviar os erros para alguma api de log de erros por exemplo, ou fazer validações extras`);
}

init({ calbackOnError: simpleErrorCallback });
 removeFromBlacklist(String(process.env.API_NAME)) // A propriedade API_NAME é algo que eu quero exibir para os usuários em uma possível mensagem de erro, então removo ela da lista de exceções

const app = Express();

app.get("/", (request, response) => {

  const tokenFromSomeApi = "123456";

  addVariableToBlackList(tokenFromSomeApi); //Você pode adicionar //mais variáveis à lista de exceções, para que elas sejam //ofuscadas em um possível erro não tratado ser exibido para o //usuário.

  throw new Error(
    `generic error with sensitive data:
      ${String(process.env.DB_HOST)}:${String(process.env.DB_PORT)}
      api token: ${tokenFromSomeApi}
      Error on api: ${String(process.env.API_NAME)}
      `);

  // As variáveis ***process.env.DB_HOST*** e ***process.env.DB_PORT*** são variáveis que estão no .env da aplicação
});

app.use(sanitizeErrors); // O middleware deve ser utilizado, preferencialmente, depois de todas as suas 

app.listen(3000);

}
```

Vamos analisar o trecho de código:

````
throw new Error(
    `generic error with sensitive data:
      ${String(process.env.DB_HOST)}:${String(process.env.DB_PORT)}
      api token: ${tokenFromSomeApi}
      Error on api: ${String(process.env.API_NAME)}
      `);
```

Como você pode ver as variáveis ***tokenFromSomeApi***, ***String(process.env.DB_PORT)***,
***String(process.env.DB_HOST)*** iriam ser vazadas quando esse erro fosse enviado para o usuário. Essas são informações que não podem chegar nas mãos de um usuário comum.
Porém a informação ***process.env.API_NAME*** é algo que você quer que seja passado a frente, por isso é possível retirar essa informação da blacklist através do método ***removeFromBlacklist ***

Com o uso do middleware a mensagem de erro resultante será assim:

`Error: generic error with sensitive data: ***:"*** api token: *** Error on api: API-1`


Para aplicar o middleware a toda a aplicação (que é o mais aconselhável) você simplesmente usa o método ***use()*** da aplicação criada pelo Express.

O middleware possui 4 métodos expostos para uso, são eles:    ***init***,  ***addVariableToBlackList***, ***sanitizeErrors***, ***removeFromBlacklist***,


***init***: é chamado antes de todas as rotas. Receba até 4 argumentos, desta forma:

***hidenMessage***: Mensagem alfandegária para substituir dados confidenciais, o padrão é "***"

***removeStackTrace***: Booleano que indica se o rastreamento de pilha será removido do erro antes que ele seja repassado. É verdadeiro por padrão.

***calbackOnError***: Este é uma callback que será chamada `ANTES` da sanitização. Isso é útil para caso você queira realizar qualquer validação extra e/ou enviar dados de erro para alguma API de log.

***removeEnv***: Booleano que indica se a lib deve remover todas as variáveis ​​que estão em .env da mensagem de erro. É verdadeiro por padrão.

O método ***addVariableToBlackList *** recebe como argumento uma propriedade que será removida das próximas mensagens de erro.

O método ***removeFromBlacklist*** recebe como argumento uma propriedade que será removida da blacklist. Em outras palavras, será exibido nas próximas mensagens de erro.

O método ***sanitizeErrors*** é o próprio middleware, e deve ser usado (preferencialmente, mas não somente) após todas as rotas da sua api.

## Algumas dicas para evitar a exposição de dados sensíveis

- Higienize todos os erros quando possível
- Valide toda e qualquer entrada de usuário que sua API recebe
- Sempre verifique se o usuário tem permissão para fazer o que está tentando fazer
- Controle e minimize os retornos em suas respostas de API


Bom, essa foi a dica de hoje e espero que tenham gostado.
Fiquem bem e até a próxima 🙂