In this article
Décryptage des CVE : guide pratique pour évaluer et atténuer les risques de sécurité
Résumé
Explorons l’univers des vulnérabilités et expositions courantes (CVE) à l’aide d’exemples détaillés, étape par étape, pour déterminer si une CVE affecte votre projet, ainsi que de stratégies pragmatiques pour l’atténuer efficacement. Ce guide vous aidera à faire face aux vulnérabilités de sécurité. Ne laissez pas les alertes CVE passer inaperçues : découvrez comment y répondre avec assurance et efficacité.
Contenu
En tant que développeurs, nous devons constamment jongler entre plusieurs projets et prioriser les corrections de bugs et les améliorations de fonctionnalités. Pourtant, dans ce rythme effréné, nous sommes souvent confrontés à une réalité inquiétante : nos projets peuvent être vulnérables aux vulnérabilités et expositions courantes (CVE). Chaque jour, le nombre de CVE signalées augmente, ce qui complique considérablement la sécurisation de nos projets. Mais pas d’inquiétude : je vais vous présenter des stratégies pratiques pour faire face à ce problème. Dans cet article, je décrirai plusieurs façons d’intégrer facilement l’examen des CVE à votre workflow de développement, afin de vous aider à protéger vos projets en toute confiance.
Sans stratégie claire pour atténuer les CVE, leur nombre, qui augmente chaque jour, peut rapidement nous submerger. C’est particulièrement vrai dans l’écosystème Node.js, où les applications comportent souvent de nombreuses dépendances. Ulises Gascón. Node.js pour les débutants (chapitre 15 : sécuriser les applications Web)
Comment examiner une CVE ?
Prenons CVE-2020-8203 comme exemple. Cette vulnérabilité de pollution de prototype affecte la bibliothèque populaire Lodash.
Selon les outils que nous utilisons pour être informés des vulnérabilités de notre projet, nous pouvons consulter différents rapports qui présentent plus ou moins les mêmes informations :
Comme vous pouvez le constater, les deux images présentent des informations similaires (principalement des métadonnées) sur la vulnérabilité. Toutefois, chaque description apporte des informations différentes qui peuvent enrichir notre analyse.

Évaluer la gravité
Pour commencer, nous pouvons utiliser le niveau de gravité pour prioriser le travail. Celui-ci est déterminé sur une échelle de un à dix à l’aide du système commun de notation des vulnérabilités (CVSS). Ce score est également détaillé et peut nous apporter beaucoup de contexte. L’objectif est de prioriser les correctifs en fonction de la criticité, lorsque plusieurs vulnérabilités doivent être examinées.
Les résultats peuvent varier selon la source d’information. Dans l’image ci-dessous, Snyk attribue un score de 8,2, tandis que Red Hat et le NVD attribuent un score de 7,4.

Le système de notation que vous choisissez importe peu, à condition de toujours utiliser le même. En général, les CVE critiques ou élevées doivent être examinées en priorité, tandis que les CVE moins graves peuvent attendre un peu.
Il faut bien comprendre qu’une fois une CVE rendue publique, tout le monde en est informé. Les acteurs malveillants peuvent donc facilement intégrer ces CVE critiques à leur arsenal et commencer à les exploiter pour s’attaquer aux systèmes, s’ils en trouvent le moyen.
Si vous ne connaissez pas la rapidité avec laquelle les acteurs malveillants peuvent agir, consultez ce rapport sur un honeypot.
Obtenir plus d’informations
L’étape suivante consiste à obtenir le plus d’informations possible sur cette vulnérabilité et son exploitation potentielle. Vous pouvez parfois trouver de nombreux renseignements en consultant les liens de la section des références sur la page officielle du rapport CVE.

Dans ce cas, nous pouvons même lire le rapport d’origine sur HackerOne et les échanges entre la personne qui a signalé la vulnérabilité et les responsables de la maintenance. Cela peut nous apporter beaucoup d’informations. Ici, nous pouvons trouver des renseignements utiles dans les rapports de Snyk et de GitHub.
Déterminer la surface d’attaque
À l’issue de l’étape précédente, nous devrions savoir quelles versions de la bibliothèque sont affectées (>=4.1.0 <4.17.20) et quelles méthodes sont concernées par cette vulnérabilité (pick, set, setWith, update, updateWith et zipObjectDeep), en gardant à l’esprit qu’il s’agit d’une vulnérabilité de pollution de prototype.
Nous pouvons rapidement vérifier le dépôt et déterminer si nous sommes exposés. Si nous n’utilisons pas ces méthodes avec ces versions précises, nous pouvons confirmer que notre code n’est pas affecté et qu’il s’agit d’un faux positif dans notre cas.
Cette évaluation peut être plus complexe que prévu. Dans l’écosystème JavaScript, il est courant d’avoir des devDependencies dans des outils de développement qui n’ont pas d’impact réel en production : linters, frameworks de test, certaines bibliothèques utilitaires, etc. Tout dépend de la nature du projet. Nous pouvons utiliser PM2 en local pour simuler un environnement de production, mais déployer nos projets en production à l’aide de conteneurs et de Kubernetes. Cela limite considérablement les vecteurs d’attaque liés aux CVE concernant PM2, car, dans la plupart des cas, nous l’exécutons dans un « environnement sécurisé » que nous contrôlons entièrement. N’oublions toutefois pas que même si le package n’est pas utilisé en production, sa compromission peut avoir des effets négatifs sur notre environnement de développement. Par exemple, eslint a été compromis en 2018.
Si nous ne pouvons pas démontrer clairement que cette vulnérabilité ne concerne pas notre projet, mieux vaut considérer que nous sommes potentiellement affectés et qu’une mesure d’atténuation valable est nécessaire.
En plus des informations fournies dans la description, consulter les Common Weakness Enumerations (CWE) mentionnées dans la CVE est un bon moyen de mieux comprendre la technique d’attaque.

Dans ce cas, la CWE mentionnée est CWE-1321 : modification mal contrôlée des attributs du prototype d’objet (« pollution de prototype »). Cela nous aide à trouver des CVE similaires et à mieux comprendre comment cette vulnérabilité peut être exploitée.
En termes simples, la CWE est une liste de faiblesses potentielles, tandis que la CVE répertorie les vulnérabilités découvertes dans la nature. Ulises Gascón. Node.js pour les débutants
Existe-t-il un POC exploitable ?
Toutes les CVE ne fournissent pas de preuve de concept (POC) de la vulnérabilité signalée qui puisse être facilement exploitée. Mais dans ce cas, nous en avons une très claire :
const _ = require('lodash');
_.zipObjectDeep(['__proto__.z'],[123]);
console.log(z); // 123
En plus de nous aider à mieux comprendre le problème, cela peut nous permettre de tester notre code et de confirmer la présence de la vulnérabilité. Imaginons que notre application contienne le code suivant :
const _ = require('lodash');
const normalizeData = (users, ages) => {
return _.zipObjectDeep(users,ages);
}
module.exports = { normalizeData }
Nous pouvons facilement supposer que ce code est vulnérable à une attaque par pollution de prototype, mais nous pouvons aussi créer un test pour nous assurer que nous avons mis en place les mécanismes nécessaires pour empêcher que ces vulnérabilités ne se reproduisent. Il arrive que les bibliothèques introduisent des régressions contenant des vulnérabilités. Nous pouvons les prévenir en ajoutant un simple test, comme suit :
const { normalizeData } = require('../utils');
describe('normalizeData behaviour', () => {
it('should return the data structured properly', () => {
const users = ['John', 'Doe'];
const ages = [30, 40];
const result = normalizeData(users, ages);
expect(result).toEqual({ John: 30, Doe: 40 });
});
it('should not be affected by a prototype pollution (CVE-2020-8203)', () => {
normalizeData(['__proto__.z'], [123]);
expect(global.z).toBe(undefined);
});
});
Ce test échouera évidemment, car notre code est actuellement vulnérable à cette pollution de prototype et nous n’avons apporté aucune modification à notre projet pour l’atténuer.

Figure : avec Node.js@21 et lodash@4.17.0
Voyons maintenant comment atténuer cette vulnérabilité.
Quelles stratégies adopter pour atténuer une CVE ?
Il existe plusieurs stratégies pour atténuer une CVE. Nous allons en examiner quelques-unes, classées selon l’effort qu’elles demandent.
Mettre à niveau ou rétrograder les versions
La méthode la plus recommandée pour atténuer une CVE consiste à mettre à niveau la version de la bibliothèque concernée. Dans ce cas, nous pouvons passer à lodash@4.17.20 ou à une version ultérieure. C’est souvent la meilleure méthode, car les responsables de la maintenance de la bibliothèque fournissent un correctif pour la vulnérabilité, également testé avec la personne qui l’a signalée. Nous pouvons ainsi nous assurer que ce correctif fonctionne.
Après avoir appliqué ce correctif (npm i lodash@4.17.20), nous pouvons relancer le test créé précédemment et vérifier que la vulnérabilité est bien atténuée.

Figure : avec Node.js@21 et lodash@4.17.21
Même si cela semble simple, la tâche peut devenir très complexe. Nous devrons peut-être mettre à niveau ou rétrograder d’autres dépendances incompatibles avec la nouvelle version de la bibliothèque. Il est aussi possible que la nouvelle version apporte d’autres modifications incompatibles avec notre code.
Parfois, la CVE est rendue publique avant la publication du correctif. Nous devons alors envisager d’autres stratégies pour atténuer la vulnérabilité en attendant le correctif définitif.
Migrer
Si la bibliothèque n’est plus maintenue ou que ses responsables ne fournissent pas de correctif pour la vulnérabilité, nous devrons peut-être migrer vers une autre bibliothèque offrant des fonctionnalités identiques ou similaires. Même si cela représente un effort important, l’investissement peut en valoir la peine si la nouvelle bibliothèque est plus sécurisée et mieux maintenue que l’ancienne.
Nous aurons ainsi moins de CVE à examiner à l’avenir et pourrons gérer plus facilement les mises à niveau.
Appliquer un correctif manuellement (à faire soi-même)
Si nous ne pouvons ni mettre à niveau la bibliothèque ni migrer vers une autre, nous devrons peut-être appliquer nous-mêmes un correctif. Cette stratégie est également valable lorsque la CVE est rendue publique avant la publication du correctif et que nous devons atténuer la vulnérabilité au plus vite, en attendant le correctif officiel.
Tout correctif manuel exige une bonne compréhension de la bibliothèque et de la vulnérabilité. Nous pouvons nous appuyer sur le POC fourni dans le rapport CVE pour créer notre propre correctif, puis utiliser le test créé pour vérifier qu’il fonctionne. Voyons comment créer un correctif pour cette vulnérabilité :
const _ = require('lodash');
const normalizeData = (users, ages) => {
const safeUsers = users.filter(user => !/__proto__|prototype|constructor/.test(user));
return _.zipObjectDeep(safeUsers, ages);
}
module.exports = { normalizeData }
Ce correctif simple illustre comment atténuer la vulnérabilité. Toutefois, pour une meilleure conformité, consultez le correctif officiel, car notre cas de test était très élémentaire. Nous pouvons maintenant relancer le test et vérifier que la vulnérabilité est bien atténuée.

Figure : avec Node.js@21, lodash@4.17.0 et le correctif
Comment documenter les décisions prises concernant les CVE
Lorsque nous travaillons en équipe, il est important de documenter les décisions prises concernant les CVE. Cela nous permet de suivre les vulnérabilités que nous avons atténuées et celles qu’il nous reste à traiter. Nous pouvons ainsi prioriser le travail et nous assurer de ne laisser aucune vulnérabilité de côté.
Nous pouvons utiliser un simple tableau pour documenter les CVE examinées, leur gravité, leur statut, la stratégie d’atténuation et la date à laquelle la vulnérabilité a été atténuée. Cela nous permet de suivre les vulnérabilités traitées et celles qu’il nous reste à traiter.
CVE | Gravité | Statut | Stratégie d’atténuation | Date |
CVE-2020-8203 | 8.2 | Atténuée | Mise à niveau vers lodash@4.17.21 | 2024-04-15 |
Ce tableau peut être mis à jour chaque fois que nous examinons une CVE, puis partagé avec l’équipe pour que chacun connaisse les vulnérabilités auxquelles nous sommes confrontés et celles que nous avons atténuées.
Vous pouvez même ajouter ce tableau à la documentation du projet afin qu’il soit inclus dans le processus de distribution du code.
Si vous utilisez un outil pour examiner les CVE, il peut être difficile de préciser le statut d’une CVE identifiée comme faux positif ou corrigée manuellement. Par exemple, si vous utilisez Snyk, vous pouvez marquer la CVE comme ignorée.
Dans notre cas, si vous avez appliqué le correctif manuellement, vous pouvez marquer la CVE comme ignorée dans le rapport Snyk à l’aide de la commande suivante : snyk ignore --id=SNYK-JS-LODASH-567746 --reason="manual patch in place with tests".
Le contenu suivant sera généré dans le fichier .snyk :
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
version: v1.25.0
# ignores vulnerabilities until expiry date; change duration by modifying expiry date
ignore:
SNYK-JS-LODASH-567746:
- '*':
reason: manual patch in place with tests
expires: 2024-05-15T17:27:20.339Z
created: 2024-04-15T17:27:20.340Z
patch: {}
Dans l’ensemble, ce processus nécessite un certain travail manuel. Il est vivement recommandé de travailler en équipe afin de limiter autant que possible les biais et les erreurs humaines.
Liste de contrôle
Pour résumer, voici les étapes à suivre pour examiner une CVE :
Évaluer la gravité de la CVE
Obtenir plus d’informations sur le vecteur d’attaque
Déterminer la surface d’attaque
Vérifiez s’il existe une preuve de concept exploitable
Évaluez l’impact sur votre projet
Corrigez la vulnérabilité si nécessaire
Consignez les décisions prises concernant les CVE
Partagez vos conclusions avec votre équipe
Ressources supplémentaires
Pour approfondir les sujets liés à la sécurité dans Node.js, consultez mon livre Node.js for Beginners, dans lequel j’aborde de nombreux sujets liés à la sécurité dans Node.js.
Sécurisez votre code grâce à des informations de pointe
Découvrez toutes les fonctionnalités SAST de Snyk Code en seulement 30 minutes.