Skip to main content

Node.js CVE-2026-39859

| EUVDEUVD-2026-20611 MEDIUM
Path Traversal (CWE-22)
2026-04-08 https://github.com/harttle/liquidjs GHSA-v273-448j-v4qj
6.3
CVSS 4.0 · GitHub Advisory
Share

Severity by source

GitHub Advisory PRIMARY
6.3 MEDIUM
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Primary rating from GitHub Advisory · only source for this CVE.

CVSS VectorGitHub Advisory

CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
X

Lifecycle Timeline

4
EUVD ID Assigned
Apr 08, 2026 - 15:16 euvd
EUVD-2026-20611
Analysis Generated
Apr 08, 2026 - 15:16 vuln.today
Patch released
Apr 08, 2026 - 15:16 nvd
Patch available
CVE Published
Apr 08, 2026 - 15:04 nvd
MEDIUM 6.3

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 18 npm packages depend on liquidjs (10 direct, 8 indirect)

Ecosystem-wide dependent count for version 10.25.5.

DescriptionGitHub Advisory

liquidjs 10.25.0 documents root as constraining filenames passed to renderFile() and parseFile(), but top-level file loads do not enforce that boundary.

The published npm package liquidjs@10.25.0 on Linux 6.17.0 with Node v22.22.1. A Liquid instance configured with an empty temporary directory as root still returned the contents of /etc/hosts when renderFile('/etc/hosts') was called. I have not exhaustively checked older releases yet; 10.25.0 is the latest tested version.

Root cause:

  • src/parser/parser.ts:83-85 calls loader.lookup(file, LookupType.Root, ...) and then reads the returned file.
  • src/fs/loader.ts:38 passes type !== LookupType.Root into candidates().
  • For LookupType.Root, enforceRoot is false, so src/fs/loader.ts:47-66 accepts resolved absolute paths and fallback results without any contains() check.

This appears adjacent to the March 10, 2026 fix for CVE-2026-30952, which hardened include / render / layout but not the top-level file-loading APIs.

Proof of concept:

javascript
const fs = require('fs');
const os = require('os');
const path = require('path');
const { Liquid } = require('liquidjs');

const safeRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'liquidjs-safe-root-'));
const engine = new Liquid({ root: [safeRoot], extname: '.liquid' });

engine.renderFile('/etc/hosts').then(console.log);

Expected result: a path outside root should be rejected. Actual result: /etc/hosts is rendered successfully.

Impact: any application that treats root as a sandbox boundary and forwards attacker-controlled template names into renderFile() or parseFile() can disclose arbitrary local files readable by the server process.

Suggested fix: apply the same containment checks used for partial/layout lookups to LookupType.Root, and reject absolute or fallback paths unless they remain within an allowed root. A regression test should verify that renderFile('/etc/hosts') fails when root points to an unrelated directory.

AnalysisAI

Path traversal in liquidjs 10.25.0 allows local file disclosure when renderFile() or parseFile() receives absolute paths or traversal sequences, despite the root parameter being documented as a sandbox boundary. An attacker controlling template filenames passed to these APIs can read arbitrary files accessible to the Node.js process, such as /etc/hosts or sensitive configuration files. The vulnerability affects liquidjs versions prior to 10.25.5; a vendor-released patch is available. No public exploit code or active exploitation has been identified at the time of analysis.

Technical ContextAI

liquidjs is a JavaScript/TypeScript implementation of the Liquid template engine commonly used in Node.js applications. The root cause lies in inconsistent path containment enforcement across the file-loading code path. When renderFile() or parseFile() is invoked, the parser calls loader.lookup() with LookupType.Root, which skips the enforceRoot check present in partial/layout lookups (CWE-22: Improper Limitation of a Pathname to a Restricted Directory). The loader's candidates() function at src/fs/loader.ts:47-66 accepts resolved absolute paths and fallback results without verifying they remain within the configured root directory. This differs from CVE-2026-30952 (March 10, 2026), which hardened the include, render, and layout directives but overlooked top-level file-loading APIs. The vulnerability is present in the npm package liquidjs (CPE: pkg:npm/liquidjs) across affected versions.

RemediationAI

Upgrade liquidjs to version 10.25.5 or later immediately. This patched version enforces the same root containment checks for top-level renderFile() and parseFile() calls as it does for partial and layout lookups. Verify the upgrade via npm audit or package-lock.json. In the interim, if upgrading is blocked, validate and sanitize all template filenames passed to renderFile() and parseFile() to reject absolute paths and traversal sequences (e.g., reject /*, ../, or leading slashes). However, such input filtering is not a substitute for the vendor fix. See GitHub PR #870 and commit f41c1fc02fe901598f3328118b42b13bc6bc9b04 for technical details of the patch. Refer to the full advisory at https://github.com/harttle/liquidjs/security/advisories/GHSA-v273-448j-v4qj.

CVE-2024-55591 CRITICAL POC
9.8 Jan 14

FortiOS and FortiProxy contain an authentication bypass via the Node.js websocket module allowing unauthenticated remote

CVE-2014-7205 CRITICAL POC
10.0 Oct 08

Eval injection vulnerability in the internals.batch function in lib/batch.js in the bassmaster plugin before 1.5.2 for t

CVE-2025-59528 CRITICAL POC
10.0 Sep 22

Flowise version 3.0.5 contains a remote code execution vulnerability in the CustomMCP node. The mcpServerConfig paramete

CVE-2017-14849 HIGH POC
7.5 Sep 28

Node.js 8.5.0 before 8.6.0 allows remote attackers to access unintended files, because a change to ".." handling was inc

CVE-2017-5941 CRITICAL POC
9.8 Feb 09

An issue was discovered in the node-serialize package 0.0.4 for Node.js. Rated critical severity (CVSS 9.8), this vulner

CVE-2014-3744 HIGH POC
7.5 Oct 23

Directory traversal vulnerability in the st module before 0.2.5 for Node.js allows remote attackers to read arbitrary fi

CVE-2014-9566 HIGH POC
7.5 Mar 10

Multiple SQL injection vulnerabilities in the Manage Accounts page in the AccountManagement.asmx service in the Solarwin

CVE-2013-4660 MEDIUM POC
6.8 Jun 28

The JS-YAML module before 2.0.5 for Node.js parses input without properly considering the unsafe !!js/function tag, whic

CVE-2015-5688 MEDIUM POC
5.0 Sep 04

Directory traversal vulnerability in lib/app/index.js in Geddy before 13.0.8 for Node.js allows remote attackers to read

CVE-2026-45321 CRITICAL POC
9.6 May 12

Credential-harvesting malware compromised 84 versions of 42 TanStack npm packages on 2026-05-11 via chained GitHub Actio

CVE-2014-7192 CRITICAL POC
10.0 Dec 11

Eval injection vulnerability in index.js in the syntax-error package before 1.1.1 for Node.js 0.10.x, as used in IBM Rat

CVE-2013-4450 MEDIUM POC
5.0 Oct 21

The HTTP server in Node.js 0.10.x before 0.10.21 and 0.8.x before 0.8.26 allows remote attackers to cause a denial of se

Share

CVE-2026-39859 vulnerability details – vuln.today

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