Skip to main content

@hapi/inert CVE-2026-48049

MEDIUM
Path Traversal (CWE-22)
2026-06-11 https://github.com/hapijs/inert GHSA-rcvq-m9j9-6f4g
5.3
CVSS 3.1 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
5.3 MEDIUM
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
vuln.today AI
5.3 MEDIUM

Network-reachable with no authentication; confidentiality impact limited to server-readable files in same-prefix sibling directories; no integrity or availability impact.

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

Primary rating from GitHub Advisory.

CVSS VectorGitHub Advisory

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
Low
Integrity
None
Availability
None

Lifecycle Timeline

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

DescriptionGitHub Advisory

Impact

@hapi/inert serves static files from a directory configured with path (in the directory / file handlers) or relativeTo (for h.file()), with confinement enforced by the confine option (default true). Before the patch, the confinement check compared the resolved absolute path against the confine directory using a raw string-prefix test, so a sibling directory whose absolute path begins with the same characters as the confine directory (eg. /app/static-secret next to a served /app/static) was incorrectly accepted as confined. An unauthenticated remote attacker who knows or guesses such a sibling name can read any file inside it via a request like /..%2fstatic-secret/secret.txt, provided the file is readable by the server process. Only applications that happen to have a sibling directory sharing a string prefix with the served directory are exploitable; applications with no such sibling are unaffected.

Patches

Upgrade to 7.1.1.

Workarounds

For users who cannot upgrade immediately: ensure the directory served via inert has no sibling whose name starts with the same characters (for example, rename static-secret/ to secret/, or move it to a different parent directory).

Resources

Pull Request: https://github.com/hapijs/inert/pull/176

AnalysisAI

Static file confinement bypass in @hapi/inert (npm, versions 4.0.0-7.1.0) allows remote unauthenticated attackers to read arbitrary files from sibling directories when those directories share a string prefix with the configured serve path. The flaw is a classic CWE-22 path traversal rooted in a faulty string-prefix comparison that fails to enforce a directory separator boundary, meaning a path like /app/static-secret incorrectly passes the confinement check for a serve root of /app/static. No public exploit code has been identified and this CVE is not in CISA KEV, but the attack itself - a single URL-encoded traversal request - is trivially simple once the precondition of a matching-prefix sibling directory is confirmed.

Technical ContextAI

@hapi/inert is the canonical static file serving plugin for the hapi.js Node.js web framework, distributed as the npm package @hapi/inert (CPE: pkg:npm/@hapi_inert). It exposes directory and file route handlers and an h.file() response toolkit method, each governed by a confine option (default: true) intended to restrict file resolution to the configured base path. The defective code in lib/file.js used path.lastIndexOf(confineDir, 0) ! 0 as its confinement gate - a raw string-prefix test that checks only whether the resolved absolute path begins with the confine directory string, without verifying that the next character is a path separator. This is a classic CWE-22 (Improper Limitation of a Pathname to a Restricted Directory) implementation error: the absence of a separator boundary means any sibling directory whose name starts with the same characters (e.g., /app/static-secret alongside serve root /app/static) is accepted as confined. The fix in commit a65e5b271b5c3405af463469959c5e052eb23a62 (PR #176) replaces the check with path ! confineDir && !path.startsWith(confineDir + Path.sep), correctly enforcing the boundary.

RemediationAI

Upgrade @hapi/inert to version 7.1.1 using npm install @hapi/inert@7.1.1 or yarn add @hapi/inert@7.1.1; this is the vendor-released patch confirmed by commit a65e5b271b5c3405af463469959c5e052eb23a62 and advisory GHSA-rcvq-m9j9-6f4g. For deployments that cannot upgrade immediately, the vendor-recommended workaround is a file system rename: ensure no sibling directory at the same parent level shares a string prefix with the served directory - for example, rename static-secret/ to secret/ or relocate it to a different parent path. This eliminates the exploitable precondition without any code change, but it requires corresponding updates to any application configuration or tooling that references the sibling path. There is no in-process configuration option within @hapi/inert itself that mitigates this flaw short of the naming workaround or upgrading. Patch and diff: https://github.com/hapijs/inert/pull/176.

Share

CVE-2026-48049 vulnerability details – vuln.today

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