Skip to main content

hapijs joi EUVDEUVD-2026-44390

| CVE-2026-48038 MEDIUM
Uncaught Exception (CWE-248)
2026-06-11 https://github.com/hapijs/joi GHSA-q7cg-457f-vx79
5.3
CVSS 3.1 · Vendor: https://github.com/hapijs/joi
Share

Severity by source

Vendor (https://github.com/hapijs/joi) PRIMARY
5.3 MEDIUM
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
vuln.today AI
7.5 HIGH

Network-reachable, no auth, no complexity; process crash from unhandled exception justifies A:H over the official A:L.

3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
4.0 AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N

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
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
Low

Lifecycle Timeline

2
Source Code Evidence Fetched
Jun 11, 2026 - 13:57 vuln.today
Analysis Generated
Jun 11, 2026 - 13:57 vuln.today

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 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 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.

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.

Share

EUVD-2026-44390 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy