Prototype pollution is one of the most insidious and misunderstood vulnerabilities in the JavaScript ecosystem. It has affected some of the most widely used npm packages in history, including lodash, jQuery, and minimist — libraries installed billions of times. In this article, we will explain exactly what prototype pollution is, how attackers exploit it, and what you can do to protect your Node.js applications.
What is Prototype Pollution?
In JavaScript, every object inherits properties from a prototype chain. When you create a plain object with {}, it inherits from Object.prototype. Prototype pollution occurs when an attacker can inject properties into an object's prototype, causing those properties to appear on every object in the application.
Think of it this way: if someone can modify Object.prototype, they effectively modify every single object in your program. This is because JavaScript's prototype chain means that property lookups walk up the chain until they find a match — and Object.prototype sits at the very top.
Here is a simple example that demonstrates the core concept:
JavaScript
// Normal behavior
const user = {};
console.log(user.isAdmin); // undefined
// Prototype pollution attack
const malicious = JSON.parse('{"__proto__": {"isAdmin": true}}');
Object.assign({}, malicious);
// Now EVERY object has isAdmin = true
const anotherUser = {};
console.log(anotherUser.isAdmin); // true — this is the attack!
This happens because __proto__ is a special accessor property that references an object's prototype. When a function blindly copies properties — including __proto__ — it can overwrite the prototype of the target object, which in many cases is Object.prototype itself.
How Prototype Pollution Works
There are three primary vectors for prototype pollution attacks in JavaScript:
1. The __proto__ accessor
The most common vector. When user-controlled input is parsed from JSON and then merged into an object, the __proto__ key can be used to modify the prototype:
JavaScript
// Vulnerable deep merge function
function deepMerge(target, source) {
for (const key in source) {
if (typeof source[key] === 'object' && source[key] !== null) {
if (!target[key]) target[key] = {};
deepMerge(target[key], source[key]);
} else {
target[key] = source[key];
}
}
return target;
}
// Attacker sends this payload
const payload = JSON.parse(
'{"__proto__": {"polluted": true}}'
);
const config = {};
deepMerge(config, payload);
// Every object is now polluted
console.log({}.polluted); // true
2. constructor.prototype
Even if you filter out __proto__, attackers can use constructor.prototype to reach the same goal:
JavaScript
const payload = {
"constructor": {
"prototype": {
"polluted": true
}
}
};
// obj.constructor is Object, so obj.constructor.prototype
// is Object.prototype
deepMerge({}, payload);
console.log({}.polluted); // true
3. Object.assign with nested objects
While Object.assign itself does a shallow copy and is generally safe, many libraries implement their own deep merge or extend functions. These custom implementations are where the danger lies. Functions like $.extend(true, ...) in jQuery or _.merge() in lodash performed deep recursive copying without checking for prototype-accessing keys.
Real-World Impact: Famous Cases
Prototype pollution is not a theoretical concern. It has affected some of the most popular packages in the npm registry:
lodash.merge — CVE-2018-16487
lodash is one of the most downloaded packages on npm, with over 40 million weekly downloads. In 2018, researchers discovered that lodash.merge(), lodash.mergeWith(), and lodash.defaultsDeep() were all vulnerable to prototype pollution. An attacker could craft a malicious object that, when merged, would pollute Object.prototype and affect the behavior of the entire application. The vulnerability was rated CVSS 9.8 (Critical) and affected all lodash versions before 4.17.11.
jQuery $.extend — CVE-2019-11358
jQuery's deep extend function $.extend(true, {}, userInput) was vulnerable to prototype pollution in all versions before 3.4.0. Given that jQuery is present on over 70% of all websites, this vulnerability had an enormous blast radius. Attackers could use it in combination with other vulnerabilities to achieve cross-site scripting (XSS) or denial of service.
minimist — CVE-2020-7598
minimist is a lightweight argument parser used by thousands of CLI tools. Versions before 1.2.3 were vulnerable to prototype pollution through carefully crafted command-line arguments. Since minimist is a transitive dependency of many build tools, this vulnerability silently affected millions of projects.
The impact chain
The real danger of prototype pollution lies in what comes after. On its own, adding a property to Object.prototype might seem harmless. But combined with other application logic, it can lead to:
- Remote Code Execution (RCE) — polluting properties used by template engines (e.g.,
__lookupGetter__in Handlebars) can lead to arbitrary code execution - Authentication bypass — polluting
isAdmin,role, or similar authorization properties - Denial of Service (DoS) — polluting properties that break application logic, crash loops, or exhaust resources
- SQL Injection — polluting query builder properties in ORMs that use object-based query construction
Vulnerable vs. Safe Code
Let us look at a practical comparison between vulnerable and safe implementations of a common pattern — a deep merge utility:
Vulnerable implementation
JavaScript
// VULNERABLE — do not use!
function deepMerge(target, source) {
for (const key in source) {
if (typeof source[key] === 'object'
&& source[key] !== null
&& !Array.isArray(source[key])) {
if (!target[key]) target[key] = {};
deepMerge(target[key], source[key]);
} else {
target[key] = source[key];
}
}
return target;
}
Safe implementation
JavaScript
// SAFE — blocks prototype pollution vectors
function safeDeepMerge(target, source) {
const BLOCKED_KEYS = new Set([
'__proto__', 'constructor', 'prototype'
]);
for (const key of Object.keys(source)) {
if (BLOCKED_KEYS.has(key)) continue;
if (typeof source[key] === 'object'
&& source[key] !== null
&& !Array.isArray(source[key])
&& Object.keys(source[key]).length > 0) {
if (!Object.hasOwn(target, key)) {
target[key] = {};
}
safeDeepMerge(target[key], source[key]);
} else {
target[key] = source[key];
}
}
return target;
}
The key differences in the safe version are: it uses Object.keys() instead of for...in (which only iterates own enumerable properties), it explicitly blocks dangerous keys like __proto__, constructor, and prototype, and it uses Object.hasOwn() instead of the in operator for checking existing keys.
How to Detect Prototype Pollution
Detecting prototype pollution in your dependencies requires a multi-layered approach:
npm audit
The built-in npm audit command checks your dependency tree against the GitHub Advisory Database. Run it regularly and pay special attention to vulnerabilities classified as prototype pollution:
Bash
# Check for known vulnerabilities
npm audit
# Get only high and critical severity
npm audit --audit-level=high
# Generate a JSON report for automation
npm audit --json > audit-report.json
Manual code review
When reviewing your own code or third-party packages, look for these red flags:
- Deep merge or deep clone functions that do not filter keys
- Use of
for...inloops withouthasOwnPropertychecks - Direct property assignment from user input (e.g.,
obj[userKey] = userValue) - Path-based property access like
set(obj, 'a.b.c', value)where the path comes from user input
Static analysis tools
Several tools can help detect prototype pollution at the code level:
- ESLint with the
eslint-plugin-securityplugin flags dangerous patterns - Snyk and Socket.dev provide supply chain security scanning with prototype pollution detection
- CodeQL has built-in queries for prototype pollution in JavaScript
- npm audit signatures verify that packages have not been tampered with on the registry
How CVE OptiBot Helps
Detecting prototype pollution manually across dozens of projects with hundreds of dependencies is not sustainable. This is exactly the problem CVE OptiBot solves.
Upload your lockfile, get instant results
Simply upload your package-lock.json file and CVE OptiBot will scan every dependency — including transitive ones — against known vulnerability databases. Prototype pollution CVEs like those affecting lodash, jQuery, and minimist are instantly flagged with severity ratings, affected version ranges, and recommended upgrades.
Continuous monitoring catches new vulnerabilities
Prototype pollution vulnerabilities are discovered regularly. A dependency that is safe today might have a critical CVE disclosed tomorrow. CVE OptiBot runs daily automated scans of all your projects and sends you email alerts the moment a new vulnerability is published. You do not have to remember to run npm audit — the monitoring is always on.
Multi-project dashboard
If you manage multiple projects — which most agencies and development teams do — CVE OptiBot gives you a unified dashboard where you can see the security posture of every project at a glance. No more logging into each project individually to check for vulnerabilities.
PDF reports for clients
For agencies, CVE OptiBot generates professional PDF security reports that you can share with your clients, demonstrating that their applications are being actively monitored and secured.
Prevention Best Practices
Beyond detection, here are concrete steps to prevent prototype pollution in your Node.js applications:
1. Use Object.create(null) for dictionaries
When you need a plain key-value store, use Object.create(null) instead of {}. Objects created this way have no prototype, so they cannot be polluted:
JavaScript
// Vulnerable: inherits from Object.prototype
const config = {};
// Safe: no prototype chain at all
const config = Object.create(null);
config.host = 'localhost';
config.port = 3000;
// __proto__ is just a regular property here, not a special accessor
config.__proto__ = 'harmless string';
console.log({}.test); // undefined — no pollution possible
2. Use Map instead of plain objects
The Map data structure is inherently immune to prototype pollution because it does not use the prototype chain for key lookups:
JavaScript
// Instead of plain objects for user data
const userPreferences = new Map();
userPreferences.set('theme', 'dark');
userPreferences.set('language', 'en');
// Attempting __proto__ just creates a normal entry
userPreferences.set('__proto__', 'anything');
console.log({}.anything); // undefined — safe!
3. Validate and sanitize input
Always validate user input before using it as object keys or in merge operations. Strip out dangerous keys at the input boundary:
JavaScript
function sanitizeInput(obj) {
if (typeof obj !== 'object' || obj === null) return obj;
const clean = Object.create(null);
for (const key of Object.keys(obj)) {
if (key === '__proto__' || key === 'constructor'
|| key === 'prototype') {
continue; // Skip dangerous keys
}
clean[key] = typeof obj[key] === 'object'
? sanitizeInput(obj[key])
: obj[key];
}
return clean;
}
// Use at the API boundary
app.post('/api/config', (req, res) => {
const safeBody = sanitizeInput(req.body);
updateConfig(safeBody);
});
4. Freeze the prototype
As a defense-in-depth measure, you can freeze Object.prototype early in your application startup to prevent any modifications:
JavaScript
// At application startup, before any other code runs
Object.freeze(Object.prototype);
// Now attempts to pollute will silently fail
// (or throw in strict mode)
Object.prototype.polluted = true;
console.log({}.polluted); // undefined — frozen!
Warning: freezing Object.prototype can break some libraries that rely on modifying it. Test thoroughly before deploying this in production.
5. Use schema validation libraries
Libraries like zod, joi, or ajv validate input structure before your application processes it. They ensure that only expected fields with expected types pass through:
JavaScript
import { z } from 'zod';
const ConfigSchema = z.object({
host: z.string(),
port: z.number().int().positive(),
debug: z.boolean().optional(),
});
// Only whitelisted fields pass through
const result = ConfigSchema.safeParse(userInput);
if (result.success) {
applyConfig(result.data);
// result.data cannot contain __proto__ or other
// unexpected keys
}
6. Keep dependencies up to date
Many prototype pollution vulnerabilities have been patched in updated versions of popular packages. Regularly updating your dependencies is one of the most effective defenses:
- Update lodash to 4.17.21 or later
- Update jQuery to 3.4.0 or later
- Update minimist to 1.2.6 or later
- Review transitive dependencies with
npm lsto find outdated nested packages
Conclusion
Prototype pollution is a uniquely JavaScript vulnerability that exploits the language's prototype inheritance model. It has affected some of the most popular packages in the npm ecosystem and can lead to severe consequences ranging from denial of service to remote code execution.
The good news is that with the right tools and practices, you can effectively protect your applications. Use Object.create(null) or Map for untrusted data, validate input at your API boundaries, keep dependencies updated, and use CVE OptiBot to continuously monitor your entire dependency tree for new vulnerabilities.
Security is not a one-time task — it is an ongoing process. Start monitoring your npm packages today and stay ahead of the next prototype pollution CVE before it affects your users.
Le prototype pollution est l'une des vulnerabilites les plus insidieuses et mal comprises de l'ecosysteme JavaScript. Elle a affecte certains des packages npm les plus utilises de l'histoire, notamment lodash, jQuery et minimist — des bibliotheques installees des milliards de fois. Dans cet article, nous allons expliquer exactement ce qu'est le prototype pollution, comment les attaquants l'exploitent, et ce que vous pouvez faire pour proteger vos applications Node.js.
Qu'est-ce que le Prototype Pollution ?
En JavaScript, chaque objet herite de proprietes via une chaine de prototypes. Lorsque vous creez un objet simple avec {}, il herite de Object.prototype. Le prototype pollution se produit lorsqu'un attaquant peut injecter des proprietes dans le prototype d'un objet, faisant apparaitre ces proprietes sur tous les objets de l'application.
Pour illustrer simplement : si quelqu'un peut modifier Object.prototype, il modifie effectivement chaque objet de votre programme. Cela est possible car la chaine de prototypes de JavaScript remonte jusqu'a trouver une correspondance — et Object.prototype se trouve tout en haut de cette chaine.
Voici un exemple simple qui demontre le concept fondamental :
JavaScript
// Comportement normal
const user = {};
console.log(user.isAdmin); // undefined
// Attaque par prototype pollution
const malicious = JSON.parse('{"__proto__": {"isAdmin": true}}');
Object.assign({}, malicious);
// Maintenant CHAQUE objet a isAdmin = true
const anotherUser = {};
console.log(anotherUser.isAdmin); // true — c'est l'attaque !
Cela se produit parce que __proto__ est une propriete d'accesseur speciale qui reference le prototype d'un objet. Lorsqu'une fonction copie aveuglement les proprietes — y compris __proto__ — elle peut ecraser le prototype de l'objet cible, qui est dans la plupart des cas Object.prototype lui-meme.
Comment fonctionne le Prototype Pollution
Il existe trois vecteurs principaux pour les attaques de prototype pollution en JavaScript :
1. L'accesseur __proto__
Le vecteur le plus courant. Lorsque des donnees controlees par l'utilisateur sont parsees depuis du JSON puis fusionnees dans un objet, la cle __proto__ peut etre utilisee pour modifier le prototype :
JavaScript
// Fonction de fusion profonde vulnerable
function deepMerge(target, source) {
for (const key in source) {
if (typeof source[key] === 'object' && source[key] !== null) {
if (!target[key]) target[key] = {};
deepMerge(target[key], source[key]);
} else {
target[key] = source[key];
}
}
return target;
}
// L'attaquant envoie ce payload
const payload = JSON.parse(
'{"__proto__": {"polluted": true}}'
);
const config = {};
deepMerge(config, payload);
// Chaque objet est maintenant pollue
console.log({}.polluted); // true
2. constructor.prototype
Meme si vous filtrez __proto__, les attaquants peuvent utiliser constructor.prototype pour atteindre le meme objectif :
JavaScript
const payload = {
"constructor": {
"prototype": {
"polluted": true
}
}
};
// obj.constructor est Object, donc obj.constructor.prototype
// est Object.prototype
deepMerge({}, payload);
console.log({}.polluted); // true
3. Object.assign avec des objets imbriques
Bien que Object.assign lui-meme effectue une copie superficielle et soit generalement sur, de nombreuses bibliotheques implementent leurs propres fonctions de fusion profonde ou d'extension. Ces implementations personnalisees sont la source du danger. Des fonctions comme $.extend(true, ...) dans jQuery ou _.merge() dans lodash effectuaient une copie recursive profonde sans verifier les cles d'acces au prototype.
Impact concret : les cas celebres
Le prototype pollution n'est pas une preoccupation theorique. Il a affecte certains des packages les plus populaires du registre npm :
lodash.merge — CVE-2018-16487
lodash est l'un des packages les plus telecharges sur npm, avec plus de 40 millions de telechargements hebdomadaires. En 2018, des chercheurs ont decouvert que lodash.merge(), lodash.mergeWith() et lodash.defaultsDeep() etaient tous vulnerables au prototype pollution. Un attaquant pouvait creer un objet malveillant qui, une fois fusionne, polluait Object.prototype et affectait le comportement de toute l'application. La vulnerabilite a ete evaluee a CVSS 9.8 (Critique) et affectait toutes les versions de lodash anterieures a 4.17.11.
jQuery $.extend — CVE-2019-11358
La fonction d'extension profonde de jQuery $.extend(true, {}, userInput) etait vulnerable au prototype pollution dans toutes les versions anterieures a 3.4.0. Etant donne que jQuery est present sur plus de 70 % de tous les sites web, cette vulnerabilite avait un rayon d'impact enorme. Les attaquants pouvaient l'utiliser en combinaison avec d'autres vulnerabilites pour realiser du cross-site scripting (XSS) ou du deni de service.
minimist — CVE-2020-7598
minimist est un parseur d'arguments leger utilise par des milliers d'outils CLI. Les versions anterieures a 1.2.3 etaient vulnerables au prototype pollution via des arguments de ligne de commande soigneusement construits. Comme minimist est une dependance transitive de nombreux outils de build, cette vulnerabilite affectait silencieusement des millions de projets.
La chaine d'impact
Le veritable danger du prototype pollution reside dans ce qui suit l'attaque initiale. En soi, ajouter une propriete a Object.prototype peut sembler inoffensif. Mais combine avec la logique applicative, cela peut mener a :
- Execution de code a distance (RCE) — polluer des proprietes utilisees par les moteurs de templates (par ex.
__lookupGetter__dans Handlebars) peut conduire a l'execution de code arbitraire - Contournement d'authentification — polluer des proprietes comme
isAdmin,roleou d'autres proprietes d'autorisation - Deni de service (DoS) — polluer des proprietes qui cassent la logique applicative, provoquent des boucles infinies ou epuisent les ressources
- Injection SQL — polluer les proprietes du constructeur de requetes dans les ORM qui utilisent la construction de requetes basee sur les objets
Code vulnerable vs. code securise
Examinons une comparaison pratique entre des implementations vulnerables et securisees d'un pattern courant — un utilitaire de fusion profonde :
Implementation vulnerable
JavaScript
// VULNERABLE — ne pas utiliser !
function deepMerge(target, source) {
for (const key in source) {
if (typeof source[key] === 'object'
&& source[key] !== null
&& !Array.isArray(source[key])) {
if (!target[key]) target[key] = {};
deepMerge(target[key], source[key]);
} else {
target[key] = source[key];
}
}
return target;
}
Implementation securisee
JavaScript
// SECURISE — bloque les vecteurs de prototype pollution
function safeDeepMerge(target, source) {
const BLOCKED_KEYS = new Set([
'__proto__', 'constructor', 'prototype'
]);
for (const key of Object.keys(source)) {
if (BLOCKED_KEYS.has(key)) continue;
if (typeof source[key] === 'object'
&& source[key] !== null
&& !Array.isArray(source[key])
&& Object.keys(source[key]).length > 0) {
if (!Object.hasOwn(target, key)) {
target[key] = {};
}
safeDeepMerge(target[key], source[key]);
} else {
target[key] = source[key];
}
}
return target;
}
Les differences cles de la version securisee sont : elle utilise Object.keys() au lieu de for...in (qui n'itere que sur les proprietes propres enumerables), elle bloque explicitement les cles dangereuses comme __proto__, constructor et prototype, et elle utilise Object.hasOwn() au lieu de l'operateur in pour verifier les cles existantes.
Comment detecter le Prototype Pollution
La detection du prototype pollution dans vos dependances necessite une approche multi-couches :
npm audit
La commande integree npm audit verifie votre arborescence de dependances par rapport a la base de donnees GitHub Advisory. Executez-la regulierement et pretez une attention particuliere aux vulnerabilites classees comme prototype pollution :
Bash
# Verifier les vulnerabilites connues
npm audit
# Obtenir uniquement les severites haute et critique
npm audit --audit-level=high
# Generer un rapport JSON pour l'automatisation
npm audit --json > audit-report.json
Revue de code manuelle
Lors de la revue de votre propre code ou de packages tiers, recherchez ces signaux d'alerte :
- Les fonctions de fusion profonde ou de clonage profond qui ne filtrent pas les cles
- L'utilisation de boucles
for...insans verificationhasOwnProperty - L'assignation directe de proprietes depuis l'entree utilisateur (par ex.
obj[userKey] = userValue) - L'acces aux proprietes base sur un chemin comme
set(obj, 'a.b.c', value)lorsque le chemin provient de l'entree utilisateur
Outils d'analyse statique
Plusieurs outils peuvent aider a detecter le prototype pollution au niveau du code :
- ESLint avec le plugin
eslint-plugin-securitysignale les patterns dangereux - Snyk et Socket.dev fournissent une analyse de securite de la chaine d'approvisionnement avec detection du prototype pollution
- CodeQL dispose de requetes integrees pour le prototype pollution en JavaScript
- npm audit signatures verifie que les packages n'ont pas ete alteres sur le registre
Comment CVE OptiBot vous aide
Detecter manuellement le prototype pollution dans des dizaines de projets comportant des centaines de dependances n'est pas viable a long terme. C'est exactement le probleme que CVE OptiBot resout.
Importez votre lockfile, obtenez des resultats instantanes
Importez simplement votre fichier package-lock.json et CVE OptiBot analysera chaque dependance — y compris les dependances transitives — par rapport aux bases de donnees de vulnerabilites connues. Les CVE de prototype pollution comme celles affectant lodash, jQuery et minimist sont instantanement signalees avec des evaluations de severite, les plages de versions affectees et les mises a jour recommandees.
Le monitoring continu detecte les nouvelles vulnerabilites
Les vulnerabilites de prototype pollution sont decouvertes regulierement. Une dependance sure aujourd'hui pourrait avoir un CVE critique divulgue demain. CVE OptiBot effectue des scans automatises quotidiens de tous vos projets et vous envoie des alertes email des qu'une nouvelle vulnerabilite est publiee. Vous n'avez pas besoin de penser a executer npm audit — le monitoring est toujours actif.
Tableau de bord multi-projets
Si vous gerez plusieurs projets — ce qui est le cas de la plupart des agences et equipes de developpement — CVE OptiBot vous offre un tableau de bord unifie ou vous pouvez voir la posture de securite de chaque projet en un coup d'oeil. Plus besoin de vous connecter a chaque projet individuellement pour verifier les vulnerabilites.
Rapports PDF pour les clients
Pour les agences, CVE OptiBot genere des rapports PDF professionnels de securite que vous pouvez partager avec vos clients, demontrant que leurs applications sont activement surveillees et securisees.
Bonnes pratiques de prevention
Au-dela de la detection, voici des mesures concretes pour prevenir le prototype pollution dans vos applications Node.js :
1. Utilisez Object.create(null) pour les dictionnaires
Lorsque vous avez besoin d'un simple stockage cle-valeur, utilisez Object.create(null) au lieu de {}. Les objets crees de cette maniere n'ont aucun prototype et ne peuvent donc pas etre pollues :
JavaScript
// Vulnerable : herite de Object.prototype
const config = {};
// Securise : aucune chaine de prototypes
const config = Object.create(null);
config.host = 'localhost';
config.port = 3000;
// __proto__ est juste une propriete normale ici,
// pas un accesseur special
config.__proto__ = 'chaine inoffensive';
console.log({}.test); // undefined — aucune pollution possible
2. Utilisez Map au lieu d'objets simples
La structure de donnees Map est naturellement immunisee contre le prototype pollution car elle n'utilise pas la chaine de prototypes pour la recherche de cles :
JavaScript
// Au lieu d'objets simples pour les donnees utilisateur
const userPreferences = new Map();
userPreferences.set('theme', 'dark');
userPreferences.set('language', 'fr');
// Tenter __proto__ cree simplement une entree normale
userPreferences.set('__proto__', 'nimporte quoi');
console.log({}.nimporte); // undefined — securise !
3. Validez et assainissez les entrees
Validez toujours les entrees utilisateur avant de les utiliser comme cles d'objets ou dans des operations de fusion. Supprimez les cles dangereuses a la frontiere de l'input :
JavaScript
function sanitizeInput(obj) {
if (typeof obj !== 'object' || obj === null) return obj;
const clean = Object.create(null);
for (const key of Object.keys(obj)) {
if (key === '__proto__' || key === 'constructor'
|| key === 'prototype') {
continue; // Ignorer les cles dangereuses
}
clean[key] = typeof obj[key] === 'object'
? sanitizeInput(obj[key])
: obj[key];
}
return clean;
}
// Utiliser a la frontiere de l'API
app.post('/api/config', (req, res) => {
const safeBody = sanitizeInput(req.body);
updateConfig(safeBody);
});
4. Gelez le prototype
Comme mesure de defense en profondeur, vous pouvez geler Object.prototype au demarrage de votre application pour empecher toute modification :
JavaScript
// Au demarrage de l'application, avant tout autre code
Object.freeze(Object.prototype);
// Les tentatives de pollution echoueront silencieusement
// (ou lanceront une erreur en mode strict)
Object.prototype.polluted = true;
console.log({}.polluted); // undefined — gele !
Attention : geler Object.prototype peut casser certaines bibliotheques qui dependent de sa modification. Testez minutieusement avant de deployer cela en production.
5. Utilisez des bibliotheques de validation de schemas
Des bibliotheques comme zod, joi ou ajv valident la structure des entrees avant que votre application ne les traite. Elles garantissent que seuls les champs attendus avec les types attendus passent :
JavaScript
import { z } from 'zod';
const ConfigSchema = z.object({
host: z.string(),
port: z.number().int().positive(),
debug: z.boolean().optional(),
});
// Seuls les champs autorises passent
const result = ConfigSchema.safeParse(userInput);
if (result.success) {
applyConfig(result.data);
// result.data ne peut pas contenir __proto__
// ou d'autres cles inattendues
}
6. Maintenez vos dependances a jour
De nombreuses vulnerabilites de prototype pollution ont ete corrigees dans les versions mises a jour des packages populaires. La mise a jour reguliere de vos dependances est l'une des defenses les plus efficaces :
- Mettez a jour lodash vers la version 4.17.21 ou ulterieure
- Mettez a jour jQuery vers la version 3.4.0 ou ulterieure
- Mettez a jour minimist vers la version 1.2.6 ou ulterieure
- Examinez les dependances transitives avec
npm lspour trouver les packages imbriques obsoletes
Conclusion
Le prototype pollution est une vulnerabilite propre a JavaScript qui exploite le modele d'heritage par prototypes du langage. Elle a affecte certains des packages les plus populaires de l'ecosysteme npm et peut entrainer des consequences graves allant du deni de service a l'execution de code a distance.
La bonne nouvelle est qu'avec les bons outils et pratiques, vous pouvez efficacement proteger vos applications. Utilisez Object.create(null) ou Map pour les donnees non fiables, validez les entrees a la frontiere de vos API, maintenez vos dependances a jour, et utilisez CVE OptiBot pour surveiller en continu l'ensemble de votre arborescence de dependances face aux nouvelles vulnerabilites.
La securite n'est pas une tache ponctuelle — c'est un processus continu. Commencez a surveiller vos packages npm des aujourd'hui et gardez une longueur d'avance sur le prochain CVE de prototype pollution avant qu'il n'affecte vos utilisateurs.