Severity by source
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
Network-reachable, no auth, no complexity; process crash from unhandled exception justifies A:H over the official A:L.
Primary rating from Vendor (https://github.com/hapijs/joi).
CVSS VectorVendor: https://github.com/hapijs/joi
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
Lifecycle Timeline
2Blast Radius
ecosystem impact- 78 npm packages depend on joi (32 direct, 46 indirect)
Ecosystem-wide dependent count for version 18.0.0.
DescriptionCVE.org
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 withouttry/catchin a request handler would cause an unhandled exception, potentially crashing the process. - Lower impact:
validateAsync()orvalidate()inside atry/catch, the validation fails, but the error type isRangeErrorrather than a structuredValidationError, complicating error handling.
Patches
Upgrade to version >= 18.2.1.
Workarounds
Try/catch the validation to avoid uncaught exceptions.
Resources
- Pull request: hapijs/joi#3113
AnalysisAI
Denial of service in the joi npm validation library (< 18.2.1) is triggered by submitting deeply nested JSON objects against schemas that use recursive link() definitions, causing a JavaScript call stack overflow. The untrapped RangeError propagates out of joi's link resolver - crashing the Node.js process entirely when validate() is invoked without a surrounding try/catch, or silently breaking error-handling logic when a RangeError is returned where a structured ValidationError was expected. No confirmed active exploitation (not in CISA KEV) and no public exploit code identified at time of analysis, but the attack surface is inherently wide given joi's prevalence in Node.js web services.
Technical ContextAI
joi (pkg:npm/joi) is a widely deployed Node.js schema-description and data-validation library maintained by the hapi.js project. Its link() schema type enables self-referential, recursive schemas - for example, a tree node schema that references the root schema for child nodes. Internally, link() resolution in lib/types/link.js calls linked.$_validate() recursively for each nested level of the input object. With sufficiently deep nesting (the test case in PR #3113 uses 5,000 levels), the JavaScript engine's native call stack is exhausted, raising a RangeError: Maximum call stack size exceeded. This maps to CWE-248 (Uncaught Exception): the library failed to catch this runtime exception at the link-resolution boundary, allowing it to propagate to the caller. The patch wraps the recursive $_validate call in a try/catch block that intercepts RangeError and converts it into a structured link.depth validation error, preventing process-level propagation.
RemediationAI
Upgrade joi to version 18.2.1 or later (vendor-released patch: 18.2.1) via npm install joi@>=18.2.1 or by updating the version constraint in package.json. The upstream fix is commit 2392713d3e9dd91ba752ac0c96e0eaf3d24b9a11 in PR hapijs/joi#3113, which wraps link resolution in a RangeError-catching try/catch and emits a structured link.depth error instead of propagating the exception. For deployments that cannot upgrade immediately, wrapping all validate() and validateAsync() calls in try/catch blocks prevents process crashes, but callers will receive a native RangeError object rather than a joi ValidationError, requiring additional type-checking in error handlers - a meaningful operational trade-off. As an additional defense-in-depth measure (recommended by the advisory even post-patch), set link.maxRecursion(limit) on all recursive link() schemas to enforce a deterministic depth ceiling before the call stack is threatened. See https://github.com/hapijs/joi/security/advisories/GHSA-q7cg-457f-vx79 for full details.
Same weakness CWE-248 – Uncaught Exception
View allSame technique Denial Of Service
View allShare
External POC / Exploit Code
Leaving vuln.today
EUVD-2026-44390
GHSA-q7cg-457f-vx79