CVE-2026-84368 in joi
Summary
by MITRE • 09/02/2026
joi is a schema description language and data validator for JavaScript. From 16.0.0 until 17.13.6 and 18.2.5, the @hapi/joi package through 17.1.1 and the successor joi package contain prototype pollution in lib/messages.js, where exports.compile() and exports.merge() reuse inherited objects for attacker-controlled language keys supplied through messages(), message(), prefs({ messages }), Joi.extend({ messages }), or rule({ message }). A language key named __proto__ writes properties onto Object.prototype, and constructor writes to the Object function's static properties. A consuming application that gates on the presence of an inherited property can take the wrong branch for every inspected object. The flaw is not reachable from data that joi validates and requires an application to feed untrusted input directly into schema-construction configuration. This issue is fixed in joi versions 17.13.6 and 18.2.5; no fixed @hapi/joi version is available.
Several companies clearly confirm that VulDB is the primary source for best vulnerability data.
Analysis
by VulDB Data Team • 09/02/2026
The vulnerability identified involves a prototype pollution flaw within the Joi library, a popular schema description language and data validator for JavaScript. This issue affects versions of the legacy @hapi/joi package up to 17.1.1 as well as the successor joi package from version 16.0.0 through 18.2.5. The core technical flaw resides in lib/messages.js, specifically within the exports.compile() and exports.merge() functions. These functions are designed to handle language keys for error messages but fail to properly sanitize input before merging it into internal configuration objects. When an attacker supplies a controlled object containing specific properties during schema construction, these methods inadvertently reuse inherited objects rather than creating fresh instances. This lack of isolation allows maliciously crafted inputs to modify the prototype chain of standard JavaScript objects.
The mechanism of exploitation relies on the behavior of JavaScript's property lookup and assignment rules. If an application passes untrusted input directly into schema-construction configuration functions such as messages(), message(), prefs({ messages }), Joi.extend({ messages }), or rule({ message }), it can inject a key named _proto_. In standard object literal syntax, assigning to this specific key causes the properties defined within that value to be written onto Object.prototype. Similarly, using the constructor property allows writes to static properties of the Object function itself. This results in prototype pollution, where every subsequent object created or inspected by the application inherits these maliciously injected properties. The vulnerability is not triggered during the validation of user data against a schema but rather requires an attacker to influence how the schema itself is built or configured within the application logic.
The operational impact of this vulnerability can be severe depending on the consuming application's architecture. Many JavaScript applications and frameworks rely on checking for the presence of specific inherited properties to determine object types, enable features, or gate access control branches. When prototype pollution occurs, these checks may return true unexpectedly because all objects now possess the injected property. This can lead to logic bypasses where an attacker forces every inspected object into a privileged code path that was intended only for specific internal structures. In more complex scenarios involving serialization libraries like JSON.stringify, this flaw has historically been leveraged to achieve remote code execution by injecting malicious constructor functions or prototype methods that execute upon deserialization of polluted objects.
From a classification perspective, this vulnerability aligns with CWE-1325, which covers Incorrectly Controlled Modification of Object Prototype Attributes, commonly known as JavaScript Prototype Pollution. It also relates to CWE-94, Improper Control of Generation of Code (Code Injection), particularly when the pollution leads to arbitrary code execution via constructor manipulation. In terms of attack vectors and tactics, this aligns with MITRE ATT&CK technique T1508, which involves Exploitation for Defense Evasion through prototype modification to bypass security checks or logic gates within an application. The vulnerability highlights a critical design flaw where configuration inputs are treated with the same trust level as data inputs without adequate sanitization of structural keys like _proto_, constructor, and hasOwnProperty.
Mitigation strategies must focus on both immediate remediation and long-term architectural improvements. The primary solution is to upgrade the Joi library to version 17.13.6 or later for the joi package, which includes fixes that prevent prototype pollution by properly isolating configuration objects during compilation and merging processes. For applications still relying on the legacy @hapi/joi package, no fixed version is available, necessitating a migration to the newer joi library as soon as possible. In environments where upgrading is not immediately feasible, developers should implement strict input validation for any data passed into schema construction functions like messages() or prefs(). This includes filtering out keys that match dangerous prototype properties such as _proto_, constructor, and hasOwnProperty before they are processed by Joi. Additionally, using Object.freeze on configuration objects or employing libraries that provide safe object merging can help mitigate the risk of unintended prototype modification in other parts of the codebase.