Skip to main content

Créer et déployer une API d’analyse de sécurité Node.js sur Platformatic Cloud

Écrit par
Headshot of Matteo Collina

Matteo Collina

feature platformic security

5 janvier 2024

0 minutes de lecture

Dans ce guide, nous allons explorer la puissante combinaison de Platformatic et Fastify, qui permet d’accélérer le développement backend tout en mettant l’accent sur la robustesse et la sécurité.

Que vous soyez un développeur Node.js expérimenté ou que vous débutiez, cet article vous aidera à mieux connaître les environnements PaaS pour Node.js, comme Platformatic. Nous verrons comment intégrer Snyk facilement à votre workflow, pour garantir que votre code ne contient ni vulnérabilités ni fuites de secrets, et comment utiliser l’API Snyk pour créer des applications de sécurité.

Qu’est-ce que Platformatic ?

Platformatic est une plateforme d’hébergement cloud conçue pour simplifier la création et la gestion d’API et de backends avec Node.js. Elle permet aux développeurs de créer facilement des API évolutives et performantes grâce à un ensemble d’outils et de fonctionnalités qui simplifient des tâches telles que le routage, les interactions avec les bases de données et l’authentification. Son intégration à Fastify améliore encore les performances et l’expérience des développeurs.

Qu’est-ce que Fastify ?

Fastify est un framework web moderne et open source pour Node.js, réputé pour ses performances élevées et sa faible empreinte. Si vous connaissez Express, vous apprécierez l’expérience de développement intégrée à Fastify, ainsi que sa légèreté et sa puissance. Axé sur la rapidité et l’efficacité, Fastify propose une API simple et intuitive, une gestion facile des requêtes et des réponses, ainsi qu’une prise en charge intégrée de la validation et de la sérialisation basées sur des schémas.

En proposant une suite complète d’outils réunis dans un ensemble cohérent, Platformatic permet aux développeurs Node.js de se consacrer davantage aux fonctionnalités essentielles de leur application et de moins se préoccuper des complexités de l’infrastructure backend.

Créer une structure de base pour une application Node.js avec Platformatic Service

Commencez par créer un répertoire pour accueillir notre application Node.js :

mkdir pkg-probe

Exécutons ensuite la commande npm suivante pour installer le générateur de projets Platformatic :

npm create platformatic@latest

Cette commande vous demandera de confirmer le téléchargement de la dernière version du package npm platformatic :

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

Répondez ensuite aux questions suivantes pour créer la structure de base d’un nouveau service API 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

Vous obtenez ainsi un projet Platformatic Service dans le répertoire platformatic-service. Il utilise du JavaScript standard et intègre GitHub Actions ainsi que les revues de pull requests connectées à Platformatic, qui fournissent un instantané immuable du service pour chaque PR.

La structure des répertoires et des fichiers devrait ressembler à ceci :

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

5 directories, 5 files

Démarrer le service Platformatic Node.js

Le service Platformatic généré est maintenant prêt à être exécuté. Démarrons l’application, mais commençons par changer de répertoire :

cd platformatic-service

Puis :

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

L’application Node.js générée est maintenant prête et traite les requêtes HTTP sur le port 3042. Par défaut, son point de terminaison GET / affiche le guide de présentation suivant :

Page d’accueil de Platformatic Service affichant des liens vers la documentation, la documentation OpenAPI et GraphiQL.

Notez que cette page d’index est servie spécifiquement par la CLI Platformatic et qu’elle est destinée au développement local. Elle ne fait pas partie du code navigateur côté client déployé avec le service d’application Node.js.

Explorer le service Platformatic 

Pour mieux comprendre le fonctionnement de cette application Node.js, examinons en détail la configuration et la structure des répertoires de Platformatic.

Le fichier platformatic.service.json définit la configuration générale du service Platformatic déployé, notamment le port d’écoute des requêtes HTTP ainsi que les plugins ou routes (également définies comme des plugins) à charger. Voici le fichier de configuration du service généré :

{
  "$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}"
    }
  }
}

Comme le montre la configuration ci-dessus, les plugins comprennent une entrée ./routes qui indique le répertoire dans lequel charger les routes de l’API.

Les routes HTTP se trouvent dans le fichier routes/root.js. L’exemple fourni inclut le point de terminaison GET suivant, au chemin /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 }
  })
}

Vérifions que cela fonctionne en envoyant la requête HTTP suivante à 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"}%   

Ajouter une route pour tester la présence de vulnérabilités dans les packages npm

Ajoutons maintenant une nouvelle fonctionnalité à notre API Node.js : elle pourra recevoir les noms et versions des packages saisis par les utilisateurs et vérifier s’ils présentent des vulnérabilités de sécurité connues.

Voici les étapes à suivre dans cette partie du tutoriel :

  • Installer et configurer la CLI Snyk

  • Récupérer le jeton d’API Snyk

  • Envoyer des requêtes HTTP à l’API Snyk avec le jeton d’API

  • Définir un nouveau point de terminaison d’API POST /test/vulnerabilities dans le service Platformatic Node.js

Installer et configurer la CLI Snyk pour récupérer un jeton d’API

Pour démarrer avec la CLI Snyk, il suffit d’installer un package npm :

npm install -g snyk

Installer la dépendance Snyk dans l’espace global des packages npm est pratique : nous pouvons ainsi l’utiliser pour tester différents aspects du code et de la sécurité des projets JavaScript sur lesquels nous travaillons. Snyk peut aussi tester le code et les dépendances en Python, Java, Ruby, PHP et dans d’autres langages !

Nous devons ensuite créer un compte Snyk gratuit pour pouvoir interroger l’API sur les vulnérabilités des packages. Exécutez donc :

snyk auth

Suivez les instructions de la CLI. Une fois la procédure terminée, vous pouvez récupérer votre jeton d’API avec la commande snyk config, qui renvoie une clé de configuration d’API :

snyk config

api: <YOUR_API_TOKEN_HERE>

Enregistrez le jeton d’API dans un endroit facilement accessible : nous allons bientôt l’utiliser. Veillez toutefois à ne pas le laisser fuiter accidentellement sur Internet.

Vous êtes maintenant prêt à tester votre code et vos dépendances pour y détecter des vulnérabilités de sécurité. Profitez-en pour tester notre application de service Platformatic Node.js !

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.

Bravo à l’équipe Platformatic d’avoir livré des outils de projet exempts de vulnérabilités !

Pour en savoir plus sur l’utilisation de la CLI Snyk, consultez la documentation Snyk User Docs et notre aide-mémoire pratique Snyk CLI Cheat Sheet.

Définir le point de terminaison d’API Node.js POST /test/vulnerabilities

Ouvrez le fichier routes/root.js et ajoutez une déclaration de route API Fastify juste après le code fastify.get() existant :

  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 };
  });

Ce code configure un point de terminaison d’API qui vérifie les vulnérabilités des packages npm à l’aide du point de terminaison de l’API Snyk v1. Voyons comment cela fonctionne, étape par étape :

Tout d’abord, la création d’une route Fastify :

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

Cette ligne crée un nouveau point de terminaison POST à l’adresse /test/vulnerabilities. Elle utilise Fastify, un framework web rapide et léger pour Node.js. Le mot-clé async indique que cette fonction peut effectuer des opérations asynchrones.

Ensuite, nous extrayons les paramètres de requête de la requête HTTP :

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

Ces paramètres indiquent le package npm et la version que l’utilisateur souhaite vérifier pour détecter des vulnérabilités.

L’intégration de l’API Snyk commence dans la partie suivante :

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

L’URL du point de terminaison de l’API Snyk est construite à partir du nom du package et d’un numéro de version précis (et non d’un tag : « latest » n’est donc pas pris en charge). Nous effectuons ensuite un appel fetch asynchrone à l’API Snyk et transmettons le jeton d’autorisation dans les en-têtes de la requête. Il s’agit du jeton d’API récupéré avec la commande snyk config.

Enfin, le point de terminaison renvoie les vulnérabilités trouvées dans le package npm spécifié. Il utilise le chaînage optionnel (?.) pour gérer les cas où la réponse ne contient aucun problème.

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

Enfin, vous pouvez améliorer la définition de la route Fastify pour le point de terminaison POST /test/vulnerabilities en définissant un schéma de requête et de réponse. Cela permet d’ajouter la validation des entrées et d’inclure automatiquement la route dans la documentation de l’API OpenAPI. Je vous recommande de suivre le tutoriel Platformatic sur l’application de films et l’article de blog de Simon Plenderleith sur la création d’API REST avec Platformatic DB.

Veillez à ne pas divulguer d’informations sensibles, comme des clés d’API !


Vous avez remarqué que nous venons d’inscrire le jeton d’API en dur dans le code ? À ne surtout pas faire !

Je ne suis pourtant pas passé à côté : j’ai installé l’extension Snyk dans mon IDE VS Code. Elle inclut automatiquement la détection des secrets et signale les problèmes de sécurité dans mon propre code susceptibles d’introduire une vulnérabilité :

Éditeur de code affichant une route Node.js avec un jeton d’API Snyk codé en dur et mis en évidence.

Installez l’extension Snyk directement depuis l’IDE VS Code ou consultez les extensions Snyk sur la marketplace VS Code pour en savoir plus.

Corrigeons donc cette fuite d’identifiants grâce à l’alerte de détection des secrets. Pour commencer, définissez une nouvelle variable d’environnement dans le fichier .env et remplacez « 1234 » par votre propre jeton d’API Snyk :

PLT_SNYK_API_TOKEN=1234

Ajoutons-la ensuite au fichier de configuration platformatic.service.json en remplaçant la chaîne ./routes existante dans le tableau par un objet qui reçoit une clé 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}`;

Notez que si vous utilisez npm run start pour exécuter le service Platformatic Node.js, vous n’avez pas besoin de relancer cette commande : le rechargement automatique actualise le code du serveur chaque fois que vous enregistrez des fichiers de routes ou de plugins.

Tester la présence de vulnérabilités dans un package npm à l’aide de notre nouveau service API Node.js 

Maintenant que Snyk et le service API Platformatic Node.js sont connectés, vérifions que tout fonctionne bien ensemble.

Vérifions si la dernière version du package npm vm2, que certains développeurs utilisent comme bac à sable de sécurité pour exécuter du code non fiable, peut être utilisée sans risque.

La requête HTTP suivante précise le nom du package et le numéro de sa dernière version dans le registre npmjs, puis transmet le résultat à l’outil jq pour afficher la réponse JSON dans un format plus lisible :

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"
        ],

Et voilà, ça fonctionne ! Félicitations, vous venez de créer votre premier outil de sécurité avec Snyk et Platformatic !

Continuons en créant une interface frontend pour cette application web, puis déployons l’API Node.js sur Platformatic Cloud.

Une application frontend Vue pour détecter les vulnérabilités de sécurité

Dans cette partie, nous allons passer en revue les composants de base de l’application web frontend qui communique avec l’API backend Node.js créée avec Platformatic Service.

Scanner de sécurité des packages npm indiquant la version 3.9.19 de vm2 et deux rapports de vulnérabilité d’exécution de code à distance

L’application web frontend comprend :

  • Un frontend côté client avec Vue.js 3 et Vite

  • Tailwind CSS

La partie frontend consiste en un formulaire simple avec des champs de texte pour le nom et la version du package, qui sont envoyés à l’API Platformatic Node.js.

Voici un formulaire Vue.js tout simple qui communique avec le service Node.js exécuté localement sur 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>

Vous trouverez le code complet de l’application web frontend dans ce dépôt GitHub : https://github.com/lirantal/pkg-probe.

Déployer l’API backend Node.js sur Platformatic Cloud

Platformatic Cloud est une plateforme PaaS (Platform as a Service) spécialisée, idéale pour héberger des applications Node.js. En plus des excellents outils proposés par Platformatic, nous pouvons désormais utiliser son environnement cloud pour héberger notre application web d’analyse de sécurité et la rendre accessible sur Internet.

Commencez par vous connecter sur la page d’accueil à l’aide du bouton Connect with GitHub, autorisez l’intégration de l’application GitHub, acceptez les conditions d’utilisation et la politique de confidentialité, puis cliquez sur Create an app dans le tableau de bord :

Écran d’importation Platformatic affichant l’étape du dépôt GitHub, avec des menus déroulants pour l’organisation et le dépôt, ainsi qu’un bouton Suivant

Ce workflow par défaut crée pour vous un nouvel exemple d’application Platformatic. Comme nous en avons déjà une, cliquez sur le lien Do it manually en bas de l’écran d’instructions.

Nommez ensuite l’application et l’espace de travail. Laissez Dynamic Workspace désactivé : nous n’avons pas besoin de revues automatisées des PR pour déployer l’application Node.js depuis la CLI pour le moment.

Un écran récapitulatif Platformatic s’affichera alors :

Écran de configuration de l’espace de travail confirmant la création de « pkg-probe », avec l’ID de l’espace de travail et la clé API masqués.

Maintenant que nous avons l’ID de l’espace de travail et la clé d’API, nous pouvons les utiliser pour déployer notre application backend Node.js sur l’environnement d’hébergement Platformatic Cloud.

Une fois l’ID de l’espace de travail et la clé d’API prêts, accédez au répertoire platformatic-service de nos projets pour exécuter une commande de cycle de vie npm dans le code source de l’API Node.js. Exécutez la commande npm run deploy suivante et fournissez les informations de l’espace de travail Platformatic Cloud :

$  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

À la fin de la commande, l’URL à laquelle l’API Node.js a été déployée et est accessible sera également indiquée. Elle ressemblera à ceci : https://something-something-funny.deploy.space

Si nous retournons au tableau de bord Platformatic Cloud à l’adresse https://platformatic.cloud, nous verrons notre nouvelle application d’analyse de sécurité :

Tableau de bord d’application bleu foncé affichant une tuile « Créer une application » et une tuile pour l’application existante « pkg-probe ».

En ouvrant notre application, nous pouvons consulter son état en temps réel, notamment les indicateurs de performance et l’adresse URL publique permettant d’y accéder :

Tableau de bord de l’espace de travail Platformatic affichant un déploiement pkg-probe actif, les détails du dernier bundle et les métriques des requêtes, de la latence, des clients connectés et du taux d’échec.

Il reste un dernier élément à configurer : activer CORS dans l’API Node.js propulsée par Platformatic.

Qu’est-ce que le partage des ressources entre origines (CORS) ?

Le partage des ressources entre origines (CORS) est une fonctionnalité de sécurité intégrée aux navigateurs web. Elle permet de gérer le partage des ressources entre différentes origines, généralement des domaines, protocoles ou ports distincts. Dans le contexte d’une application backend, CORS est essentiel, car il détermine si et comment les données d’un serveur peuvent être partagées avec des pages web provenant d’une autre origine. Sans CORS, les applications web modernes qui s’appuient sur des API et d’autres ressources inter-origines seraient fortement limitées.

Pourquoi le CORS est-il important ?

Cette politique empêche une page Web d’envoyer des requêtes à un domaine différent de celui qui l’a servie, protégeant ainsi contre certaines cybermenaces, comme les attaques par cross-site scripting (XSS). Toutefois, le CORS permet un accès sécurisé et contrôlé en précisant quels domaines peuvent accéder aux ressources de votre serveur. Vous pouvez ainsi créer des applications Web riches et interactives qui interagissent en toute sécurité avec des ressources provenant de plusieurs origines.

Ajoutons une configuration CORS à l’API Node.js. Ouvrez le fichier .env et ajoutez la configuration CORS Platformatic suivante :

PLT_SERVER_CORS_ORIGIN=http://localhost:5173

Comme vous pouvez le voir dans cet exemple, la configuration pointe vers le port du serveur de développement local de Vue.js sur localhost. Si vous déployez votre frontend ailleurs, par exemple sur un hébergement cloud Netlify ou Vercel, vous devrez adapter cette valeur.

Ensuite, modifions la directive de configuration server dans platformatic.service.json pour y ajouter également les éléments suivants :

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

Réussite

Et voilà !

Vous avez créé avec succès une application web Node.js qui recherche les vulnérabilités de sécurité à l’aide de l’API Snyk, puis l’avez déployée sur l’environnement d’hébergement Platformatic Cloud pour la rendre accessible au public.

Sécurisez vos applications JavaScript dès maintenant

Détectez et corrigez gratuitement les vulnérabilités JavaScript avec Snyk. 

Aucune carte de crédit requise.

Ou inscrivez-vous avec Azure AD Docker ID Bitbucket

En utilisant Snyk, vous acceptez de respecter nos politiques, notamment nos Conditions d’utilisation et notre Politique de confidentialité.

Lire la suite

Blog

Les modèles de pointe ont trouvé les vulnérabilités. Seul l’attaquant a trouvé les chaînes d’exploitation.

L’analyse statique a détecté les failles, mais seuls des tests d’attaque en conditions réelles ont prouvé comment elles pouvaient être enchaînées pour provoquer des compromissions. Comparaison d’Evo COS, de Claude Security et de Claude Code Security.

feature insights context
Blog

Les attaques autonomes sont déjà là. La défense doit suivre leur rythme.

Les attaquants autonomes réduisent la fenêtre de défense. Découvrez comment la découverte, la correction, la validation et la prévention continues peuvent aider les équipes de sécurité à suivre le rythme.

Blog

Pourquoi les agents de codage IA créent-ils sans cesse des failles de contrôle d’accès ?

Les agents de codage IA peuvent générer une logique d’autorisation qui compile et passe la revue, tout en exposant les données d’un tenant à un autre. Découvrez pourquoi les failles de contrôle d’accès sont difficiles à détecter et comment les prévenir.