Melhores práticas de segurança para suas APIs com Node.js

Icaro Caldeira

  • Tech Lead @ RankMyApp

  • 9+ anos de experiência em desenvolvimento

  • Community Lead @ Nerdzão

  • Co-organizer @ NodeBr

  • Speaker

Ferramentas

Nunca confie nos dados vindos do seu client

Valide SEMPRE os dados do seu usuário

> (No)SQL Injection

> ReDoS

> JWT hijack

> Session hijack

> XSS

Como se prevenir

> ODM / ORM

 

 

> Utilize libs que validem seu REGEX (safe-regex)

 

 

> Não use eval!

 

Como se prevenir

> Processe sempre JS e HTML na requisição e na resposta


> Utilize libs de validação de entrada de dados: joi


> Definitivamente utilize o helmet e configure ele de acordo com suas necessidades

Como se prevenir

> No caso de JWT, permita que sua aplicação faça o blacklist dos tokens

 

> SSL sempre!

DoS

> ReDos (REGEX DoS)

 

> BotNet

 

> PoD (Ping of Death)

 

> Teardrop

Tipos

Como se prevenir

>Utilizar serviços de CDN ( Cloudflare, Akamai)

 

> Limitar requests para cada usuário

 

> Não deixe os erros da sua aplicação vazar, trate-os!

 

>Limite o tamanho de cada request que o seu usuário pode enviar

Proteja seus tokens

Fator humano

Um projeto privado pode ser colocado como público, e/ou as chaves podem estar expostas

Como se prevenir

> Criptografe seus tokens (git-crypt)

 

> Utilize o projeto dotenv e suba somente o arquivo .env.example com chaves fake para seu repo

 

> Twelve-Factor App

Proteja as senhas corretamente

Utilize bcrypt para salvar as senhas e não a lib crypto do Node.js

Exiba mensagens de erro amigáveis

Utilize o error handler do framework utilizado

Express

app.use(function(err, req, res, next) {
  console.error(err.stack);
  res.status(500).send('Something broke!');
});
const bodyParser = require('body-parser');
const methodOverride = require('method-override');

app.use(bodyParser());
app.use(methodOverride());
app.use(function(err, req, res, next) {
  // logic
});
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
import { Request, Response } from 'express';

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
    const status = exception.getStatus();

    response
      .status(status)
      .json({
        statusCode: status,
        timestamp: new Date().toISOString(),
        path: request.url,
      });
  }
}

Nest

Responda somente os dados necessários para sua aplicação

{
  "data": [
    {
      "_id": "123456788999999",
      "name": "TDC FLORIPA 2019",
      "email": "TDCFloripa@2019.com",
      "isAdmin": false,
      "cpf": "123144123124123"
  ]
}

Não retorne dados sensíveis se não forem necessários

Utilize transformers

// specify the transform schema option
if (!schema.options.toObject) schema.options.toObject = {};
schema.options.toObject.transform = function (doc, ret, options) {
  // remove the _isAdmin and cpf of every document before returning the result
  delete ret.isAdmin;
  delete ret.cpf;
  return ret;
}

// without the transformation in the schema
doc.toObject();
// { _id: '123456788999999', name: 'TDC FLoripa',  email: 'TDC@2019.floripa', isAdmin: false, cpf: '12312412314123' }

// with the transformation
doc.toObject();
// { _id: '123456788999999', name: 'TDC FLoripa', email: 'TDC@2019.floripa' }

Mantenha suas dependências atualizadas ou tenha uma política de checagem de vulnerabilidades

Não confie 100% nas libs do NPM

Analise a frequência de commits

Analise os mantenedores

Analise as issues

NPM ou Yarn audit

Evite episódios como o roubo de variáveis, event-stream e getcookies

Referências

@icarcal

OBRIGADO

Dúvidas?

TDC Floripa 2019 - Melhores práticas de segurança para suas APIs com Node.js

By Icaro Caldeira

TDC Floripa 2019 - Melhores práticas de segurança para suas APIs com Node.js

  • 625