Iniciando com Next.js + Strapi: Segurança antes de tudo

Segurança pra quê?

Abaixo vamos discutir, os erros mais comuns de segurança em aplicações web e como mitiga-los ou corrigi-los em nossa aplicação Strapi + Next.js:

XSS/CRSF:

CRSF ou Cross-site request forgery, é quando alguém utiliza de uma técnica maliciosa para conseguir através de um request seja via Postman ou browser conseguir atingir nossa base de dados, apagar dados de usuários por exemplo, roubar dados de sessão ( como cartão de crédito, endereços etc) entre outras coisas.

Click Jacking:

Vulnerabilidades comuns em Rest APIS:

  • DOS & DDOS (Denial of Service) : Quando um hacker quer derrubar uma API , aplicativo ou site , ele pode disparar requisições em massa para aquele API ou endpoint.
  • Exposição de Informações Sensitivas: Quando expomos dados sensitivos do usuário, especialmente sem criptografia em nossa API. Ids, e-mails, endereços, informações de pagamento etc.
  • Ataques MIM (Man in the Middle) : Quando um hacker tenta interceptar a comunicação de client e servidor , com a intenção de roubar dados.
  • SQL Injection: Injeção de código que altere o comportamento esperado da API e do Banco de Dados. Através de uma injection um hacker consegue roubar informações, quebrar a API, alterar seu funcionamento.
  • Insecure Direct Object References: Quando você expõe uma API com endpoints como /user/id/30, e um usuário tenta acessar um ID que não compete a ele, e consegue, você está expondo Referências diretas de objetos inseguros.

Vulnerabilidades comuns em APIS GraphQL:

  • /graphql?query={__schema{types{name,fields{name}}}} :
    Se seu API GraphQL estiver público, apenas com uma query dessa, o usuário que a usa-la, consegue ver todo o esquema da sua API
  • Queries Maliciosas: Hackers podem montar queries maliciosas, sejam para roubar dados, corromper seu banco de dados, ou derrubar sua API/servidor
  • Brute-Force: Para evitar problemas com hackers tentando quebrar os dados da sua API GraphQL , você pode usar plugins como o GraphQL Rate Limit, que vai limitar quantas vezes os campos vulneráveis da sua query podem ser executados em um intervalo de tempo.

Como evitar tudo isso?

  • Entendendo o arquivo de Configuração do Strapi & sua segurança:
    O Strapi possui uma documentação rica que nos mostra como garantir a segurança do CMS :
    Possui configurações para XSS, P3P, Hsts , X-Frame-Options (Clickjacking), CORS (muito útil para setar que domínios podem acessar sua aplicação, que headers podem ser expostos),
    IP (Consegue configurar que IPS enxergam ou não sua aplicação)
  • Injeção de Credenciais: Use um arquivo .env, para não ficar injetando credenciais no meio do seu código
  • Validação: Você pode criar um middleware para validar se os dados da sua aplicação já existem e não vão ser duplicados, ou você também pode usar uma lib como o Joi , para fazer validação dos campos da sua API, mas o Strapi já possui algumas validações nativas que você pode definir nos models da sua API, apenas se você usa MongoDB
  • Roles & Permissions: O ideal é você criar uma documentação pra sua API em quais permissões e quais endpoints você vai habilitar, para não acabar caindo no erro de permitir tudo e oferecendo risco aos dados da sua API
  • Policies: Você pode setar as policies da sua API direto no código do Strapi através do ./config/policies para Policies globais e ./api/**/config/policies para endpoints locais. É uma camada extra de segurança para sua aplicação Strapi. Para setar policies com GraphQL , a documentação do Strapi tem uma página exclusiva a isso.
  • Data-Leak: Você pode passar um paramêtro private:true, dentro do parametro no model da sua API, para tirar o valor de ser acessado por qualquer pessoa. Clique aqui para saber mais
  • JWT: você pode exigir que para o usuário acessar endpoints sensíveis da sua aplicação ele esteja logado e utilize JWT.
  • Exposição de Informações Sensitivas: O Strapi permite com a edição dos controllers, quais informações podem ser acessadas nas chamadas dos endpoints. Você pode apagar certos campos e paramêtros dos resultados.

No GraphQL:

  • DOS (Denial of Service): Você precisa limitar suas queries. Um hacker mal intencionado, se descoberto sua API GraphQL, pode montar uma série de queries que podem sobrecarregar seu servidor. Esse é um ótimo artigo no blog do Apollo que ensina alguns casos de queries maliciosas e como evitá-las.
  • Setando Policies para as Queries: Você tem que customizar o Schema da sua API GraphQL, setando as policies desejadas para ter controle de quem ou como se acessa o quê na sua API
  • Acesso não autorizado: Você precisa desabilitar o GraphQL Playground, que já vem desabilitado na versão produção do Strapi (você pode desabilitar para outros ambientes aqui) , depois seu endpoint GraphQL não é mantido por uma rota mas por um middleware.
    É necessario criar um novo middleware, que vai verificar se o endpoint que queremos é o /graphql e se o usuário autenticado é o que queremos:
module.exports = strapi => {
return {
initialize() {
strapi.app.use(async (ctx, next) => {
const handleErrors = (ctx, err = undefined, type) => {
if (ctx.request.graphql === null) {
return (ctx.request.graphql = strapi.errors[type](err));
}

return ctx[type](err);
};

// check if it's a graphql request
if (ctx.request.url === '/graphql' && ctx.request.method === 'POST') {
if (ctx.request && ctx.request.header && ctx.request.header.authorization) {
try {
// get token data
const { id } = await strapi.plugins[
'users-permissions'
].services.jwt.getToken(ctx);

if (id === undefined) {
throw new Error('Invalid token: Token did not contain required fields');
}

// check if the id match to the user you want
if (id !== 'my-user-id') {
return handleErrors(ctx, 'You are not authorized to access to the GraphQL API', 'unauthorized');
}
} catch (err) {
return handleErrors(ctx, err, 'unauthorized');
}
} else {
// if no authenticated, return an error
return handleErrors(ctx, 'You need to be authenticated to request GraphQL API', 'unauthorized');
}
}

await next();
});
}
};
};

Para ser autenticado você precisa mandar um JWT no header. Veja aqui na documentação de autenticação do Strapi como fazer.

No Next.js:

  • Validando os campos: A validação de campos de forms, não serve apenas para guiar seu usuários, mas também garantir a integridade das informações transmitidas do client para o server. Isso evita uma série de códigos maliciosos serem inputados em nossos Serviços. O usuário pode ainda tentar manipular os dados, editando o HTML no DevTools, mas isso é outro problema..
  • CRSF: Passando o paramêtro Content-Type: application/JSON, nas nossas requisições, força nossa aplicação a não usar requisições simples, e protege contra ataques
  • XSS: Esse guia é muito útil e mostra algumas regras que é bom seguir ao desenvolver nossa aplicação front-end para não ter dor de cabeça depois em questões de segurança e XSS. Esse plugin pro Next.js também ajuda a implementar XSS Protection, ajudando o browser a sanitizar áreas vulneraveis da sua aplicação.
  • Security Headers & ClickJacking: Utilizando X-Frame-Options:DENY ou SAMEORIGIN, você evita que terceiros consigam rodar sua aplicação Next.js dentro de um frame.
    O plugin next-secure-headers, te ajuda com isso. Além de implementar o FrameGuard, ele também implementa XSS Protection, contentSecurityPolicy,nosniff,noopen,forceHTTPSRedirect, referrerPolicy, expectCT.
  • JWT & Tokens Rolantes: Você pode implementar JWT, para a autenticação do seu App para garantir a integridade da sua API e ao acesso a ela, esse é um bom tutorial que ensina isso
  • Mais:
    NextAuth.js : Um plugin para te ajudar com a segurança na autenticação do seu app Next.js

SSL:

Cacheamento de APIS:

Roadmap de Segurança do Strapi:

Esse é o link do Product Board. Nele vemos que o time do Strapi planeja features como: 2FA( Autenticação de dois fatores) , Token Rolante ( JWT), SSO ( Google, Twitter, Facebook, GitHub), dentre outros que já estão sendo testados: como Permissões e Regras por usuário e Permissões a níveis de campo.

Ferramentas de checagem:

Sentry: Sentry é uma ferramenta para monitoramento de erros de webapps. Tem suporte a diversas tecnologias e plataformas. É facilmente integrável com GraphQL, Strapi ou Next.js. Possui uma versão free para desenvolvedores.

Sqreen: Sqreen é uma plataforma de monitoramento de segurança de webapps. Pode trazer dados em tempo real de exploits em potencial, te proteger de ataques e atividades maliciosas.

O Strapi tem suporte ao Sqreen.

No Next.js você também pode usar o Sqreen, mas a configuração é um pouco mais complicada

LGTM: LGTM é uma ferramenta open-source utilizada por grandes players do mercado, como Google, Microsoft, Nasa e Dell, que verifica vulnerabilidades no seu código através de um repositório no Github ou BitBucket.
Tem uma ferramenta de code review automático e é bastante poderoso, possui alertas para te avisar sobre problemas no código e também comparativos e histórico.

SonarCloud: SonarQube é uma feramenta muito poderosa, que não só verifica Bugs e Vulnerabilidades no seu código, como alguns parâmetros como Mantenabilidade de código, Coverage de Testes, Codesmells, Duplicações de código, ele analisa seu código e pode barrar um P/R ou M/R no Github, GitLab, Azure DevOps ou BitBucket caso não atinja a qualidade de código esperada. O SonarCloud possui também um plugin para IDES que verifica em real time

Mozilla Observatory: Ferramenta da Mozilla que vai ajudar a trazer Insights sobre a segurança do seu website.

DigiCert SSL Tools: Vai checar dados do seu certificado SSL, mostrar possíveis vulnerabilidades, o Certificate Chain e a Configuração de servidor.

Qualys SSL Labs: Ferramenta um pouco mais completa que a da DigiCert.

Pen-test Tool: Website Vulnerability: Site que possui verificação de SQL Injection, XSS, Inclusão de arquivos, Execução de comandos remotos , porém é pago.

Sucuri SiteChecker: Sucuri é bem conhecido no mundo de segurança web. Detecta se seu site está blacklisted no Google, se tem links não seguros, entre outros parametros de segurança

Bom pessoal, obrigado se você chegou aqui e teve paciência, a intenção era ter dado uma idéia geral de como mitigar e solucionar diversos problemas de segurança e vulnerabilidade em aplicações web com Next.js e Strapi, antes de começarmos a usar a Stack, sendo que os conceitos aqui apontados podem ser utilizados e verificados em qualquer aplicação web não só com Node.js e JavaScript/TypeScript mas com outras linguagens e que utilizem Rest APis ou GraphQL Apis. Esse é um assunto muito extenso que poderia render vários artigos,mas tentei resumir nesse aqui.

Referências:

--

--

Senior Software Engineer @ Mintbase (https://rubenmarcus.dev)

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store