joi
Ecosystem: npm
Downloads: 112.89 Mln
- 0CriticalAffects 0 versions
- 3HighAffects 5 versions
- 0MediumAffects 0 versions
- 2ModerateAffects 4 versions
- 2LowAffects 4 versions
- Critical0 (0.0%)
- High3 (42.9%)
- Medium0 (0.0%)
- Moderate2 (28.6%)
- Low2 (28.6%)
Monthly breakdown
- Critical
- High
- Medium
- Moderate
- Low
- 1 vulnerabilities
- Critical: 0
- High: 1
- Medium: 0
- Moderate: 0
- Low: 0
- 5 vulnerabilities
- Critical: 0
- High: 2
- Medium: 0
- Moderate: 1
- Low: 2
- 1 vulnerabilities
- Critical: 0
- High: 0
- Medium: 0
- Moderate: 1
- Low: 0
Vulnerabilities (7)
Known vulnerabilities affecting joi, based on data from OSV.
| ID | Severity | Summary | Affected versions | Published | Source |
|---|---|---|---|---|---|
| GHSA-4528-x5fx-h6hg | High | joi: quadratic-time split in `string().email({ multiple: true })` allows denial of service### Summary `Joi.string().email({ multiple: true })` takes quadratic time to split a value that contains a long run of whitespace. One request with 100 KB of spaces blocks the Node.js event loop for several seconds, which causes a denial of service. ### Details When the `multiple` option is set, the `email` rule splits the value into addresses with a regular expression that removes whitespace on each side of the separator: ```js const regex = new RegExp(`\\s*[${options.separator ? escapeRegex(options.separator) : ','}]\\s*`); // ... const emails = options.multiple ? value.split(regex) : [v |
| GitHub (opens in a new tab) | |
| GHSA-6h2x-m376-mqjq | High | joi: Quadratic regular-expression backtracking in `Joi.string().isoDate()`### Impact Any application that validates a user-supplied string with `Joi.string().isoDate()` can be stalled by a single request. One of the regular expressions the rule runs over the input was unanchored, so a valid ISO date followed by a long run of fractional-second digits made the regex engine restart its search from every position in the string, costing time proportional to the square of the input length. 64 KB of digits costs about 1.4 s and 256 KB about 22 s. ### Patches Upgrade to version 17.13.7 or 18.2.6 depending on your current major version. ### Workarounds None except capping |
| GitHub (opens in a new tab) | |
| GHSA-mrx9-2rrp-rhpx | High | Duplicate Advisory: joi: Quadratic regular-expression backtracking in `Joi.string().isoDate()`## Duplicate Advisory This advisory has been withdrawn because it is a duplicate of GHSA-6h2x-m376-mqjq. This link is maintained to preserve external references. ## Original Description joi (npm package `joi`, hapi.js) versions >=17.2.0 <17.13.7 and >=18.0.0 <18.2.6 are vulnerable to regular expression denial of service in the `Joi.string().isoDate()` validation rule. One of the regular expressions the rule applies to the input is unanchored, so a valid ISO date followed by a long run of fractional-second digits causes the regex engine to restart its search from every position in the string, |
| GitHub (opens in a new tab) | |
| GHSA-wr44-6hxh-3jwq | Moderate | joi messages compilation allows prototype replacement through __proto__ error codesjoi before versions 17.13.8 and 18.2.9 contains a prototype pollution vulnerability in the messages compilation function that accepts __proto__ as an error code. Attackers can supply __proto__ keys in custom messages to replace the returned object's prototype, breaking downstream code relying on Object.prototype methods. |
| GitHub (opens in a new tab) | |
| GHSA-6w3j-5fw6-r9vr | Low | joi: Prototype pollution via a `__proto__` language key in custom messages### Impact An application that passes attacker-controlled data into joi's custom message configuration (`messages()`, `message()`, `prefs({ messages })`, `Joi.extend({ messages })` or `rule({ message })`) lets the attacker write properties onto `Object.prototype`, where every object in the process then inherits them. A key named `__proto__` was treated as a language name, and the code reused the object it found at that key, which resolves to the prototype rather than to a new own property; a key named `constructor` did the same to the `Object` function's statics. A consuming application that g |
| GitHub (opens in a new tab) | |
| GHSA-gg4h-3hg2-grpc | Low | joi: object().rename() with a template target can set the validated object's prototype### Impact Applications are affected only if a schema renames keys with a regular-expression source and a `Joi.expression()` / `Joi.x()` target that interpolates the pattern's own match data, combined with `{ multiple: true }`, for example `.rename(/^x-(.+)$/, Joi.x('{#1}'), { multiple: true })`. Because the target is rendered from the matched input key, an attacker who controls input keys can send `x-__proto__` with an object value and make the rename target render as `__proto__`, which sets the prototype of the object joi returns instead of creating a key on it. The global `Object.prototype |
| GitHub (opens in a new tab) | |
| GHSA-q7cg-457f-vx79 | Moderate | joi has an uncaught RangeError on deeply nested input through recursive `link()` schemas### Impact Denial of service via untrapped exception in services validating user-supplied JSON / object input with recursive link schemas. The blast radius depends on how the application invokes joi: - Highest impact: `validate()` called without `try/catch` in a request handler would cause an unhandled exception, potentially crashing the process. - Lower impact: `validateAsync()` or `validate()` inside a `try/catch`, the validation fails, but the error type is `RangeError` rather than a structured `ValidationError`, complicating error handling. ### Patches Upgrade to version >= 18.2.1. ### |
| GitHub (opens in a new tab) |
- GHSA-4528-x5fx-h6hgHighjoi: quadratic-time split in `string().email({ multiple: true })` allows denial of service
>= 17.1.1, < 17.13.9>= 18.0.0, < 18.3.1
### Summary `Joi.string().email({ multiple: true })` takes quadratic time to split a value that contains a long run of whitespace. One request with 100 KB of spaces blocks the Node.js event loop for several seconds, which causes a denial of service. ### Details When the `multiple` option is set, the `email` rule splits the value into addresses with a regular expression that removes whitespace on each side of the separator: ```js const regex = new RegExp(`\\s*[${options.separator ? escapeRegex(options.separator) : ','}]\\s*`); // ... const emails = options.multiple ? value.split(regex) : [v
CVE: CVE-2026-118772
- GHSA-6h2x-m376-mqjqHighjoi: Quadratic regular-expression backtracking in `Joi.string().isoDate()`
>= 17.2.0, < 17.13.7>= 18.0.0, < 18.2.6
### Impact Any application that validates a user-supplied string with `Joi.string().isoDate()` can be stalled by a single request. One of the regular expressions the rule runs over the input was unanchored, so a valid ISO date followed by a long run of fractional-second digits made the regex engine restart its search from every position in the string, costing time proportional to the square of the input length. 64 KB of digits costs about 1.4 s and 256 KB about 22 s. ### Patches Upgrade to version 17.13.7 or 18.2.6 depending on your current major version. ### Workarounds None except capping
CVE: CVE-2026-92599
- GHSA-mrx9-2rrp-rhpxHighDuplicate Advisory: joi: Quadratic regular-expression backtracking in `Joi.string().isoDate()`
>= 18.0.0
## Duplicate Advisory This advisory has been withdrawn because it is a duplicate of GHSA-6h2x-m376-mqjq. This link is maintained to preserve external references. ## Original Description joi (npm package `joi`, hapi.js) versions >=17.2.0 <17.13.7 and >=18.0.0 <18.2.6 are vulnerable to regular expression denial of service in the `Joi.string().isoDate()` validation rule. One of the regular expressions the rule applies to the input is unanchored, so a valid ISO date followed by a long run of fractional-second digits causes the regex engine to restart its search from every position in the string,
- GHSA-wr44-6hxh-3jwqModeratejoi messages compilation allows prototype replacement through __proto__ error codes
< 17.13.8>= 18.0.0, < 18.2.9
joi before versions 17.13.8 and 18.2.9 contains a prototype pollution vulnerability in the messages compilation function that accepts __proto__ as an error code. Attackers can supply __proto__ keys in custom messages to replace the returned object's prototype, breaking downstream code relying on Object.prototype methods.
CVE: CVE-2026-90771
- GHSA-6w3j-5fw6-r9vrLowjoi: Prototype pollution via a `__proto__` language key in custom messages
>= 17.2.0, < 17.13.6>= 18.0.0, < 18.2.5
### Impact An application that passes attacker-controlled data into joi's custom message configuration (`messages()`, `message()`, `prefs({ messages })`, `Joi.extend({ messages })` or `rule({ message })`) lets the attacker write properties onto `Object.prototype`, where every object in the process then inherits them. A key named `__proto__` was treated as a language name, and the code reused the object it found at that key, which resolves to the prototype rather than to a new own property; a key named `constructor` did the same to the `Object` function's statics. A consuming application that g
CVE: CVE-2026-122131
- GHSA-gg4h-3hg2-grpcLowjoi: object().rename() with a template target can set the validated object's prototype
>= 16.0.0, < 17.13.5>= 18.0.0, < 18.2.4
### Impact Applications are affected only if a schema renames keys with a regular-expression source and a `Joi.expression()` / `Joi.x()` target that interpolates the pattern's own match data, combined with `{ multiple: true }`, for example `.rename(/^x-(.+)$/, Joi.x('{#1}'), { multiple: true })`. Because the target is rendered from the matched input key, an attacker who controls input keys can send `x-__proto__` with an object value and make the rename target render as `__proto__`, which sets the prototype of the object joi returns instead of creating a key on it. The global `Object.prototype
CVE: CVE-2026-84367
- GHSA-q7cg-457f-vx79Moderatejoi has an uncaught RangeError on deeply nested input through recursive `link()` schemas
>= 18.0.0, < 18.2.1< 17.13.4
### Impact Denial of service via untrapped exception in services validating user-supplied JSON / object input with recursive link schemas. The blast radius depends on how the application invokes joi: - Highest impact: `validate()` called without `try/catch` in a request handler would cause an unhandled exception, potentially crashing the process. - Lower impact: `validateAsync()` or `validate()` inside a `try/catch`, the validation fails, but the error type is `RangeError` rather than a structured `ValidationError`, complicating error handling. ### Patches Upgrade to version >= 18.2.1. ###
CVE: CVE-2026-48038