Skip to main content

Crie e implante uma API de análise de segurança para Node.js no Platformatic Cloud

Escrito por
Headshot of Matteo Collina

Matteo Collina

feature platformic security

5 de janeiro de 2024

0 minutos de leitura

Neste guia, vamos explorar a poderosa combinação de Platformatic e Fastify, que permite desenvolver backends com rapidez, sem abrir mão da robustez e da segurança.

Seja você um desenvolvedor experiente de Node.js ou esteja começando agora, este artigo é um ótimo ponto de partida para ampliar seus conhecimentos sobre ambientes PaaS para Node.js, como o Platformatic. Vamos explorar como integrar o Snyk ao seu fluxo de trabalho sem complicações, para garantir que seu código não tenha vulnerabilidades nem vazamentos de segredos, e como usar a API do Snyk para criar aplicações de segurança.

O que é a Platformatic?

A Platformatic é uma plataforma de hospedagem em nuvem criada para simplificar o desenvolvimento e o gerenciamento de APIs e backends em Node.js. Com a Platformatic, você pode criar APIs escaláveis e eficientes com facilidade, usando diversas ferramentas e recursos que simplificam tarefas como roteamento, interação com bancos de dados e autenticação. A integração com o Fastify melhora ainda mais o desempenho e a experiência de desenvolvimento.

O que é o Fastify?

Fastify é um framework web moderno e de código aberto para Node.js, conhecido pelo alto desempenho e pela baixa sobrecarga. Se você já trabalha com Express, vai gostar da experiência de desenvolvimento que o Fastify oferece e de como ele é leve sem abrir mão da potência. Com foco em velocidade e eficiência, o Fastify oferece uma API simples e intuitiva, facilita o tratamento de requisições e respostas e inclui suporte integrado à validação e à serialização baseadas em esquemas.

Ao oferecer um conjunto abrangente de ferramentas em um pacote coeso, o Platformatic permite que desenvolvedores de Node.js se concentrem mais na funcionalidade principal de suas aplicações e menos nas complexidades da infraestrutura de backend.

Criar a estrutura inicial de uma aplicação Node.js com o serviço Platformatic

Primeiro, crie um novo diretório para armazenar nossa aplicação Node.js:

mkdir pkg-probe

Em seguida, execute o comando npm abaixo para instalar o gerador de projetos do Platformatic:

npm create platformatic@latest

Este comando solicitará a confirmação do download da versão mais recente do pacote npm platformatic:

Need to install the following packages:
create-platformatic@1.11.0
Ok to proceed? (y) y

Em seguida, responda às perguntas a seguir para criar a estrutura inicial de um novo serviço de API para Node.js:

 Hello Liran Tal, welcome to Platformatic 1.11.0!
 Let's start by creating a new project.
? Which kind of project do you want to create? Service
? Where would you like to create your project? platformatic-service
? Do you want to run npm install? yes
? Do you want to use TypeScript? no
? What port do you want to use? 3042
? Do you want to create the github action to deploy this application to Platformatic Cloud? yes
? Do you want to enable PR Previews in your application? yes
? Do you want to init the git repository? no

Isso cria um projeto de serviço do Platformatic no diretório platformatic-service, que usa JavaScript puro e conta com integração ao GitHub Actions, além de análises de PR conectadas ao Platformatic, que fornecem um snapshot imutável do serviço em cada PR.

A estrutura de diretórios e arquivos deve ficar parecida com esta:

.
└── platformatic-service
    ├── README.md
    ├── global.d.ts
    ├── node_modules
    ├── package-lock.json
    ├── package.json
    ├── platformatic.service.json
    ├── plugins
    ├── routes
    └── test

5 directories, 5 files

Inicie o serviço Platformatic para Node.js

O serviço Platformatic gerado já está pronto para ser executado. Vamos iniciar o app, mas primeiro precisamos mudar de diretório:

cd platformatic-service

E, em seguida:

npm run start

lirantal  …/repos/pkg-probe/platformatic-service   v20.8.0 
♥ npm run start

> start
> platformatic start

[12:56:12.555] INFO (main/75676): Server listening at http://127.0.0.1:3042

A aplicação Node.js gerada está pronta e recebendo solicitações HTTP na porta 3042. Por padrão, a aplicação exibe o guia introdutório a seguir no endpoint GET /:

Página de boas-vindas do Platformatic Service exibindo links para a documentação, a documentação do OpenAPI e o GraphiQL.

É importante observar que esta página inicial é exibida especificamente pela CLI do Platformatic e destina-se ao desenvolvimento local. Ela não faz parte do código de navegador do lado do cliente implantado com o serviço da aplicação Node.js.

Conheça o serviço Platformatic 

Para entender melhor como esta aplicação Node.js funciona, precisamos analisar em detalhes a configuração e a estrutura de diretórios do Platformatic.

O arquivo platformatic.service.json define a configuração geral do serviço Platformatic implantado, como a porta que receberá solicitações HTTP e os plugins ou rotas (também definidas como plugins) que devem ser carregados. Veja o arquivo de configuração do serviço gerado:

{
  "$schema": "https://platformatic.dev/schemas/v1.11.0/service",
  "service": {
    "openapi": true
  },
  "watch": true,
  "plugins": {
    "paths": [
      {
        "path": "./plugins",
        "encapsulate": false
      },
      "./routes"
    ]
  },
  "server": {
    "hostname": "{PLT_SERVER_HOSTNAME}",
    "port": "{PORT}",
    "logger": {
      "level": "{PLT_SERVER_LOGGER_LEVEL}"
    }
  }
}

De acordo com a configuração acima, os plugins incluem uma entrada ./routes, que define o diretório de onde as rotas da API serão carregadas.

As rotas HTTP estão disponíveis no arquivo routes/root.js, e o exemplo pronto para uso fornece o seguinte endpoint GET no parâmetro de caminho /example:

/// <reference path="../global.d.ts" />
'use strict'

/** @param {import('fastify').FastifyInstance} fastify */
module.exports = async function (fastify, opts) {
  fastify.get('/example', async (request, reply) => {
    return { hello: fastify.example }
  })
}

Vamos confirmar se funciona enviando a seguinte solicitação HTTP para GET /example:

 curl http://localhost:3042/example -vvv  
*   Trying 127.0.0.1:3042...
* Connected to localhost (127.0.0.1) port 3042 (#0)
> GET /example HTTP/1.1
> Host: localhost:3042
> User-Agent: curl/8.1.2
> Accept: */*
> 

< HTTP/1.1 200 OK
< content-type: application/json; charset=utf-8
< content-length: 18
< Date: Thu, 16 Nov 2023 11:24:41 GMT
< Connection: keep-alive
< Keep-Alive: timeout=5
< 
* Connection #0 to host localhost left intact
{"hello":"foobar"}%   

Adicione uma nova rota para testar se os pacotes npm têm vulnerabilidades de segurança

Agora, vamos adicionar um novo recurso à nossa API Node.js para receber nomes e versões de pacotes informados pelos usuários e verificar se há vulnerabilidades de segurança conhecidas.

Veja as tarefas que precisaremos concluir nesta seção do tutorial:

  • Instalar e configurar a CLI do Snyk

  • Obter o token da API do Snyk

  • Fazer solicitações HTTP à API do Snyk usando o token da API

  • Definir um novo endpoint de API POST /test/vulnerabilities no serviço Platformatic para Node.js

Instale e configure a CLI do Snyk para obter um token da API

Começar a usar a CLI do Snyk é simples: basta instalar um pacote npm:

npm install -g snyk

Instalar a dependência do Snyk no escopo global de pacotes npm é útil porque podemos usá-la para testar vários aspectos de código e segurança dos projetos JavaScript em que trabalhamos. Na verdade, o Snyk também pode testar código e dependências de Python, Java, Ruby, PHP e outras linguagens!

Em seguida, precisamos criar uma conta gratuita no Snyk para consultar a API em busca de vulnerabilidades em pacotes. Execute:

snyk auth

Siga as instruções da CLI. Depois de concluir, você poderá obter seu token da API usando o comando snyk config, que retorna uma chave de configuração da API:

snyk config

api: <YOUR_API_TOKEN_HERE>

Guarde o token da API em um local de fácil acesso, pois vamos usá-lo em breve. Mas tenha cuidado para não deixá-lo vazar acidentalmente para a internet pública.

Agora você já pode testar seu código e suas dependências em busca de vulnerabilidades de segurança. Que tal aproveitar para testar nossa aplicação Node.js Platformatic Service?

lirantal  …/pkg-probe/platformatic-service   main !   v20.8.0 
♥  snyk test   

Testing ~/repos/pkg-probe/platformatic-service...

Organization:      snyk-demo-567
Package manager:   npm
Target file:       package-lock.json
Project name:      package.json
Open source:       no
Project path:      ~/repos/pkg-probe/platformatic-service
Licenses:          enabled

✔ Tested 500 dependencies for known issues, no vulnerable paths found.

Next steps:
- Run `snyk monitor` to be notified about new related vulnerabilities.
- Run `snyk test` as part of your CI/test.

Parabéns à equipe do Platformatic por lançar ferramentas de projeto sem nenhuma vulnerabilidade!

Para saber mais sobre como usar a CLI do Snyk, consulte a Snyk User Docs e nosso prático guia de referência da CLI do Snyk.

Defina o endpoint de API POST /test/vulnerabilities para Node.js

Abra o arquivo routes/root.js e adicione uma nova declaração de rota da API do Fastify logo após o código fastify.get() existente:

  fastify.post("/test/vulnerabilities", async (request, reply) => {
    const packageName = request.query.packageName;
    const packageVersion = request.query.packageVersion;

    const snykApiToken = "12345”
    const url = `https://snyk.io/api/v1/test/npm/${packageName}/${packageVersion}`;

    const response = await fetch(url, {
      headers: {
        Authorization: `token ${snykApiToken}`,
      },
    });

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }

    const data = await response.json();
    return { vulnerabilities: data.issues?.vulnerabilities };
  });

Este código configura um endpoint de API para verificar vulnerabilidades em pacotes npm usando o endpoint da API v1 do Snyk. Vamos analisar cada parte:

Primeiro, a criação da rota do Fastify:

fastify.post("/test/vulnerabilities", async (request, reply) => {...});

Esta linha cria um novo endpoint POST em /test/vulnerabilities. Aqui usamos o Fastify, um framework web rápido e de baixo overhead para Node.js. A palavra-chave async indica que esta função pode executar operações assíncronas.

Em seguida, extraímos os parâmetros de consulta da solicitação HTTP:

const packageName = request.query.packageName;
const packageVersion = request.query.packageVersion;

Esses parâmetros especificam o pacote npm e a versão que o usuário quer verificar em busca de vulnerabilidades.

A integração com a API do Snyk começa na próxima parte:

const snykApiToken = "12345";
const url = `https://snyk.io/api/v1/test/npm/${packageName}/${packageVersion}`;
const response = await fetch(url, { headers: { Authorization: `token ${snykApiToken}` } });

A URL do endpoint da API do Snyk é montada usando o nome do pacote e o número explícito da versão (não uma tag, portanto “latest” não é compatível). Em seguida, fazemos uma chamada fetch assíncrona à API do Snyk, passando o token de autorização nos cabeçalhos da solicitação. Esse é o token da API obtido com o comando snyk config.

Por fim, o endpoint retorna as vulnerabilidades encontradas no pacote npm especificado. Ele usa encadeamento opcional (?.) para lidar com casos em que a resposta não contém problemas.

return { vulnerabilities: data.issues?.vulnerabilities };

Por fim, você pode aprimorar a definição da rota do Fastify para o endpoint POST /test/vulnerabilities definindo um esquema de solicitação e resposta. Isso ajuda a validar as entradas e permite que a rota seja incluída automaticamente na documentação da API OpenAPI. Recomendo seguir o tutorial do app de filmes do Platformatic e a publicação de Simon Plenderleith sobre como criar APIs REST com o Platformatic DB.

Tenha cuidado para não expor informações confidenciais, como chaves de API!


Você percebeu que acabamos de inserir o token da API diretamente no código? Isso não pode!

Eu não deixei passar: tenho a extensão do Snyk instalada no VS Code, que inclui detecção automática de segredos e sinaliza problemas de código inseguro que podem introduzir vulnerabilidades:

Editor de código exibindo uma rota Node.js com um token de API do Snyk embutido no código e destacado.

Instale a extensão do Snyk diretamente pelo VS Code ou encontre as extensões do Snyk no Marketplace do VS Code para saber mais.

Vamos corrigir esse vazamento de credenciais com a ajuda do alerta de detecção de segredos. Primeiro, defina uma nova variável de ambiente no arquivo .env e substitua “1234” pelo seu próprio token da API do Snyk:

PLT_SNYK_API_TOKEN=1234

Em seguida, podemos adicioná-la ao arquivo de configuração platformatic.service.json, atualizando a chave de string ./routes existente no array para um objeto que recebe uma chave options:

{
  …
  "plugins": {
    "paths": [
      {
        "path": "./plugins",
        "encapsulate": false
      },
     {
        "path": "./routes",
        "options": {
           "snykApiToken": "{PLT_SNYK_API_TOKEN}"
       }
     }
    ]
  },
  …
}
module.exports = async function (fastify, opts) {

    const snykApiToken = opts.snykApiToken;
    const url = `https://snyk.io/api/v1/test/npm/${packageName}/${packageVersion}`;

Observe que, se você usar npm run start para executar o Node.js Platformatic Service, não precisará executar este comando novamente, pois ele oferece recarga automática e atualiza o código do servidor sempre que você salva arquivos de rotas ou plugins.

Teste um pacote npm em busca de vulnerabilidades de segurança usando nosso novo serviço de API para Node.js 

Agora que conectamos o Snyk e o serviço de API Node.js Platformatic, vamos confirmar se tudo funciona em conjunto.

Vamos verificar se a versão mais recente do pacote npm vm2, que alguns desenvolvedores podem usar como sandbox de segurança para executar código não confiável, é segura.

A solicitação HTTP a seguir especifica o nome do pacote e o número da versão mais recente no registro npmjs, e envia o resultado para a ferramenta jq, que formata a resposta JSON para facilitar a leitura:

curl -X POST "http://localhost:3042/test/vulnerabilities?packageName=vm2&packageVersion=3.9.19" | jq 

{
  "vulnerabilities": [
    {
      "id": "SNYK-JS-VM2-5772823",
      "url": "https://snyk.io/vuln/SNYK-JS-VM2-5772823",
      "title": "Remote Code Execution (RCE)",
      "type": "vuln",
      "description": "## Overview\n[vm2](https://github.com/patriksimek/vm2#readme) is a sandbox that can run untrusted code with whitelisted Node's built-in modules.\n\nAffected versions of this package are vulnerable to Remote Code Execution (RCE) due to insufficient checks which allow an attacker to escape the sandbox.\r\n\r\n**Note:**\r\n\r\nAccording to the maintainer, the security issue cannot be properly addressed and the library will be discontinued.\n## Remediation\nThere is no fixed version for `vm2`.\n## References\n- [GitHub Issue](https://github.com/patriksimek/vm2/issues/533)\n",
      "from": [
        "vm2@3.9.19"
      ],
      "package": "vm2",
      "version": "3.9.19",
      "severity": "critical",
      "exploitMaturity": "proof-of-concept",
      "language": "js",
      "packageManager": "npm",
      "semver": {
        "vulnerable": [
          "*"
        ]
      },
      "publicationTime": "2023-07-12T14:50:43.988574Z",
      "disclosureTime": "2023-07-12T14:10:56Z",
      "isUpgradable": false,
      "isPatchable": false,
      "isPinnable": false,
      "identifiers": {
        "CVE": [
          "CVE-2023-37903"
        ],

Funcionou! Parabéns por criar sua primeira ferramenta de segurança com Snyk e Platformatic!

Vamos continuar criando um frontend para esta aplicação web e, em seguida, implantar a API Node.js no Platformatic Cloud.

Uma aplicação frontend em Vue para analisar vulnerabilidades de segurança

Nesta parte, vamos conhecer os componentes básicos da aplicação web frontend que se comunica com a API backend Node.js que criamos com o serviço Platformatic.

Scanner de segurança de pacotes npm exibindo a versão 3.9.19 do vm2 e dois relatórios de vulnerabilidades de execução remota de código

A aplicação web frontend é composta por:

  • Um frontend do lado do cliente com Vue.js 3 + Vite

  • Tailwind CSS

A parte de frontend é um formulário simples, com campos de texto para o nome e a versão do pacote, enviados à API Node.js Platformatic.

Veja a seguir um formulário Vue.js simples que se comunica com o serviço Node.js em execução local em localhost:3042:

<script setup>
import { ref } from "vue";

const processing = ref(false);
const packageName = ref("vm2");
const packageVersion = ref("3.9.19");
const vulnerabilities = ref([]);

async function scanPackage() {
  processing.value = true;

  const BASE_URL = "http://localhost:3042";
  const httpResponseRaw = await fetch(
    `${BASE_URL}/test/vulnerabilities?packageName=${packageName.value}&packageVersion=${packageVersion.value}`,
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify({}),
    }
  );

  const httpResponse = await httpResponseRaw.json();
  vulnerabilities.value = httpResponse.vulnerabilities;

  processing.value = false;
}
</script>

Você pode consultar o código completo da aplicação web frontend neste repositório do GitHub: https://github.com/lirantal/pkg-probe.

Implante a API backend Node.js no Platformatic Cloud

O Platformatic Cloud é uma PaaS (plataforma como serviço) especializada, ideal para hospedar aplicações Node.js. Além das excelentes ferramentas do Platformatic, agora podemos usar o ambiente de nuvem da plataforma para hospedar nossa aplicação web de análise de segurança e disponibilizá-la na internet.

Comece fazendo login na página inicial com o botão Conectar ao GitHub, autorize a integração com o app do GitHub, aceite os termos de serviço e a política de privacidade e, em seguida, clique em Criar um app no painel:

Tela de importação do Platformatic exibindo a etapa Repositório do GitHub, com menus suspensos de organização e repositório e um botão Avançar

Este fluxo de trabalho padrão cria uma nova aplicação de exemplo do Platformatic para você. No entanto, já temos uma aplicação em execução, então clique no link Fazer manualmente na parte inferior da tela de instruções.

Em seguida, dê um nome à aplicação e ao workspace. Mantenha a opção Dynamic Workspace desativada, pois, por enquanto, não precisamos de análises automatizadas de PR para implantar a aplicação Node.js pela CLI.

Você verá uma tela de resumo do Platformatic, como esta:

Tela de configuração do espaço de trabalho confirmando que “pkg-probe” foi criado com sucesso, com os campos de ID do espaço de trabalho e chave de API ocultos.

Agora que temos o ID do workspace e a chave da API, podemos usá-los para implantar nossa aplicação backend Node.js no ambiente de hospedagem do Platformatic Cloud.

Com o ID do workspace e a chave da API em mãos, acesse o diretório platformatic-service do nosso projeto para executar um comando de ciclo de vida npm no código-fonte da API Node.js. Execute o comando npm run deploy e informe os dados do workspace do Platformatic Cloud, como mostrado a seguir:

$  npm run deploy

This application will be deployed to Platformatic Cloud. To change the target use the --deploy-service-host flag
? Select workspace type: static
? Enter workspace id: 09d9a354-b755-40da-b4ab-841a43d8c074
? Enter workspace key: ********************************
[13:41:52] INFO: Found Platformatic config file: platformatic.service.json
[13:41:54] INFO: Project has been successfully archived
[13:41:55] INFO: Uploading bundle (95.9 MB) to the cloud…
…
[13:42:52] INFO: Application has been successfully started

Ao concluir, o comando também exibirá a URL em que a API Node.js foi implantada e está disponível, como: https://something-something-funny.deploy.space

Se voltarmos ao painel do Platformatic Cloud em https://platformatic.cloud, veremos a nova aplicação de análise de segurança que criamos:

Painel de aplicativo azul-escuro com um bloco “Create an App” e um bloco do aplicativo “pkg-probe”.

Ao abrir nossa aplicação, podemos ver informações em tempo real, como métricas de desempenho e o endereço público para acessá-la:

Painel do espaço de trabalho da Platform mostrando uma implantação ativa de pkg-probe, detalhes do pacote mais recente e métricas de solicitações, latência, clientes conectados e taxa de falhas.

Falta apenas mais um item de configuração na API Node.js com Platformatic: habilitar o CORS.

O que é CORS?

O compartilhamento de recursos entre origens (CORS) é um recurso de segurança implementado nos navegadores para controlar como os recursos são compartilhados entre diferentes origens, que geralmente correspondem a domínios, protocolos ou portas distintos. Em uma aplicação de back-end, o CORS é essencial porque controla se e como os dados de um servidor podem ser compartilhados com páginas da web de outra origem. Sem o CORS, as aplicações web modernas que dependem de APIs e de outros recursos de origens diferentes enfrentariam sérias limitações.

Por que o CORS é importante?

Essa política impede que uma página da Web faça solicitações a um domínio diferente daquele que a serviu, ajudando a proteger contra certos tipos de ameaças à segurança cibernética, como ataques de Cross-Site Scripting (XSS). Ao mesmo tempo, o CORS permite acesso seguro e controlado ao especificar quais domínios podem acessar os recursos do seu servidor. Assim, é possível desenvolver aplicações Web ricas e interativas que interagem com segurança com recursos de várias origens.

Vamos adicionar uma configuração de CORS à API Node.js. Abra o arquivo .env e adicione a seguinte configuração de CORS do Platformatic:

PLT_SERVER_CORS_ORIGIN=http://localhost:5173

Como você pode ver neste exemplo de configuração, a origem está definida como a porta do servidor de desenvolvimento local do Vue.js, em localhost. Se você implantar o frontend em outro lugar, como em um ambiente de hospedagem na nuvem do Netlify ou Vercel, precisará ajustar esse valor.

Em seguida, vamos atualizar a diretiva de configuração do servidor em platformatic.service.json para incluir também o seguinte:

  "server": {
    "hostname": "{PLT_SERVER_HOSTNAME}",
     // other configuration options…
     // add CORS too:
    "cors": {
      "origin": "{PLT_SERVER_CORS_ORIGIN}"
    }
 }

Sucesso

Pronto!

Você criou com sucesso um aplicativo web em Node.js que verifica vulnerabilidades de segurança usando a API da Snyk e o implantou no ambiente de hospedagem da Platformatic Cloud para uso público.

Comece a proteger seus aplicativos JavaScript

Encontre e corrija vulnerabilidades em JavaScript gratuitamente com o Snyk.

Não é necessário informar um cartão de crédito.

Ou cadastre-se com o Azure AD Docker ID Bitbucket

Ao usar o Snyk, você concorda em cumprir nossas políticas, incluindo os Termos de Serviço e a Política de Privacidade.

Leia mais

Blog

Modelos de ponta encontraram as vulnerabilidades. Só o atacante encontrou as cadeias.

A análise estática encontrou as falhas, mas só os testes de ataque em aplicações ativas provaram como elas poderiam ser encadeadas para causar invasões. Uma comparação entre Evo COS, Claude Security e Claude Code Security.

feature insights context
Blog

Os ataques autônomos já chegaram. A defesa precisa acompanhar o ritmo.

Os atacantes autônomos estão reduzindo o tempo disponível para a defesa. Saiba como a descoberta, a correção, a validação e a prevenção contínuas ajudam as equipes de segurança a acompanhar esse ritmo.

Blog

Por que agentes de programação com IA continuam criando falhas de controle de acesso

Agentes de programação com IA podem gerar uma lógica de autorização que compila e passa pela revisão, mas permite que um tenant acesse os dados de outro. Saiba por que é difícil detectar falhas de controle de acesso e como evitá-las.