Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-84367

CVE-2026-84367: Joi JavaScript Validator Privilege Escalation

CVE-2026-84367 is a privilege escalation flaw in Joi JavaScript validator allowing prototype pollution through rename operations. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-84367 Overview

CVE-2026-84367 is a prototype pollution vulnerability [CWE-1321] in joi, a widely-used schema description language and data validator for JavaScript. The flaw affects joi versions 16.0.0 through 17.13.4 and 18.0.0 through 18.2.3. It resides in the internals.rename() implementation within lib/types/keys.js, used by object().rename(). When a schema combines a regular-expression source, a Joi.expression() or Joi.x() target that interpolates match data, and the { multiple: true } option, an attacker can derive the target key from attacker-controlled input. Fixed versions are 17.13.5 and 18.2.4.

Critical Impact

An attacker submitting a crafted key such as x-__proto__ can set the prototype of the object returned by validate(), potentially altering downstream property lookups on that object.

Affected Products

  • joi versions 16.0.0 through 17.13.4
  • joi versions 18.0.0 through 18.2.3
  • Applications using object().rename() with regex sources, Joi.expression()/Joi.x() targets, and { multiple: true }

Discovery Timeline

  • 2026-09-01 - CVE-2026-84367 published to NVD
  • 2026-09-01 - Last updated in NVD database

Technical Details for CVE-2026-84367

Vulnerability Analysis

The vulnerability arises in joi's key-renaming logic. When a schema author configures object().rename() with a regular-expression pattern as the source and a dynamic template target using Joi.expression() or Joi.x(), the rename target is computed from the input key's captured match data at validation time. With { multiple: true } enabled, joi does not restrict the resulting target from resolving to reserved property names such as __proto__.

An attacker supplying a payload containing the key x-__proto__ with an object value causes the template to render __proto__ as the target key. Instead of assigning an own property, the assignment mutates the prototype of the object returned by validate(). The mutation is scoped to that specific returned object; the global Object.prototype is not modified. Applications that iterate, serialize, or dispatch on properties of the validated object may still behave incorrectly, exposing the caller to logic errors and downstream injection paths.

Root Cause

The root cause is missing sanitization of computed rename targets in internals.rename(). The code path treated any rendered template output as a valid destination key, including JavaScript reserved keys like __proto__, constructor, and prototype. Static-string targets and schemas using the default { multiple: false } do not reach the vulnerable code path.

Attack Vector

Exploitation requires an application that (1) accepts attacker-controlled JSON or object input, and (2) validates that input using a joi schema matching the vulnerable pattern. The attacker sends an input whose key matches the regex source and whose interpolated template value resolves to __proto__, along with an object value that becomes the polluted prototype.

javascript
// Patch from lib/types/keys.js adds a reserved-key check
'object.regex': '{{#label}} must be a RegExp object',
'object.rename.multiple': '{{#label}} cannot rename {{:#from}} because multiple renames are disabled and another key was already renamed to {{:#to}}',
'object.rename.override': '{{#label}} cannot rename {{:#from}} because override is disabled and target {{:#to}} exists',
+ 'object.rename.proto': '{{#label}} cannot rename {{:#from}} because target {{:#to}} is a reserved key',
'object.schema': '{{#label}} must be a Joi schema of {{#type}} type',
'object.unknown': '{{#label}} is not allowed',

Source: GitHub Commit Fix 172ecec

Detection Methods for CVE-2026-84367

Indicators of Compromise

  • Incoming request payloads containing keys with __proto__, constructor, or prototype substrings, particularly matching regex-based rename patterns.
  • Application logs showing validated objects with unexpected inherited properties after calls to joi's validate().
  • Runtime errors or altered control flow immediately following schema validation of user-supplied JSON.

Detection Strategies

  • Perform static analysis of application source to identify object().rename() usages combining regex sources, Joi.expression()/Joi.x() targets, and { multiple: true }.
  • Inspect the resolved joi version in package-lock.json or yarn.lock and flag any version outside 17.13.5+ or 18.2.4+.
  • Enable request-body inspection at the API gateway or WAF to identify polluting key patterns before they reach the validator.

Monitoring Recommendations

  • Log validated object structures at debug level in non-production environments to spot unexpected prototype chain modifications.
  • Alert on Software Composition Analysis (SCA) findings that reference GHSA-gg4h-3hg2-grpc.
  • Monitor Node.js application error rates and unhandled exception patterns after deployments that update input-handling code.

How to Mitigate CVE-2026-84367

Immediate Actions Required

  • Upgrade joi to version 17.13.5 or 18.2.4 across all Node.js services and shared libraries.
  • Audit schemas for object().rename() calls that use regex sources with Joi.expression() or Joi.x() targets and { multiple: true }.
  • Rebuild and redeploy container images so pinned transitive dependencies pick up the patched joi version.

Patch Information

The fix is applied in lib/types/keys.js and rejects rename targets that resolve to reserved keys such as __proto__, returning a new object.rename.proto validation error. Details are available in GitHub Pull Request #3134, GitHub Pull Request #3135, and the GitHub Security Advisory GHSA-gg4h-3hg2-grpc.

Workarounds

  • Replace Joi.expression()/Joi.x() rename targets with static string targets where feasible.
  • Set { multiple: false } on affected rename() calls to avoid the vulnerable code path.
  • Pre-filter incoming keys to reject any input key containing __proto__, constructor, or prototype substrings before validation.
bash
# Upgrade joi to a patched version
npm install joi@^17.13.5
# or
npm install joi@^18.2.4

# Verify installed version
npm ls joi

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.