Advisory Database
  • Advisories
  • Dependency Scanning
  1. npm
  2. ›
  3. liquidjs
  4. ›
  5. CVE-2026-39859

CVE-2026-39859: LiquidJS: `renderFile()` / `parseFile()` bypass configured `root` and allow arbitrary file read

April 8, 2026 (updated April 9, 2026)

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:

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.

References

  • github.com/advisories/GHSA-v273-448j-v4qj
  • github.com/harttle/liquidjs
  • github.com/harttle/liquidjs/commit/f41c1fc02fe901598f3328118b42b13bc6bc9b04
  • github.com/harttle/liquidjs/pull/870
  • github.com/harttle/liquidjs/releases/tag/v10.25.5
  • github.com/harttle/liquidjs/security/advisories/GHSA-v273-448j-v4qj
  • nvd.nist.gov/vuln/detail/CVE-2026-39859

Code Behaviors & Features

Detect and mitigate CVE-2026-39859 with GitLab Dependency Scanning

Secure your software supply chain by verifying that all open source dependencies used in your projects contain no disclosed vulnerabilities. Dependency Scanning using SBOM also detects vulnerabilities from proprietary advisories that this site does not include. Learn more about Dependency Scanning using SBOM →

Affected versions

All versions before 10.25.5

Fixed versions

  • 10.25.5

Solution

Upgrade to version 10.25.5 or above.

Impact 5.3 MEDIUM

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

Learn more about CVSS

Weakness

  • CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

Source file

npm/liquidjs/CVE-2026-39859.yml

Spotted a mistake? Edit the file on GitLab.

  • Site Repo
  • About GitLab
  • Terms
  • Privacy Statement
  • Contact

Page generated Sun, 08 Nov 2026 00:16:29 +0000.