Deno: BYONM module resolution allows package.json main path traversal to bypass --allow-read restrictions
When Deno was run in BYONM mode (nodeModulesDir: "manual"), the module resolver did not validate that a package's resolved entrypoint stayed within its node_modules/<pkg>/ directory. A malicious package.json whose main field contained .. segments was able to resolve to an arbitrary path on disk, and the resolver then read that file without consulting the --allow-read allowlist. This let a require("evil-pkg") call return the contents of a file that a direct Deno.readTextFileSync(...) call would have been blocked from reading.
In BYONM mode, Deno resolved npm packages directly from a user-managed node_modules tree. Resolution of require("pkg") proceeded by reading pkg/package.json, taking the main field, joining it to the package directory, and loading the result as a module.
The path joined from main was not constrained to the package root. A package.json such as:
```json
{ "main": "../../../secret.json" }
```
resolved to node_modules/pkg/../../../secret.json, escaping node_modules entirely. The BYONM permission check accepted any path that contained a node_modules component and did not reject .. traversal, so the resolved path was loaded without a read-permission check.
Because resolution loaded JSON entrypoints by parsing their contents and returning them through require, this exposed the contents of arbitrary .json files reachable by the OS user to the requiring code, even when --allow-read had been narrowed to a specific directory.
The same file accessed via Deno.readTextFileSync was correctly blocked. The bug was that module resolution did not enforce the same read-permission boundary that the filesystem APIs enforced.
The reporter supplied a self-contained PoC. Layout:
```
/tmp/deno_byonm_poc/
├── app/
│ ├── deno.json (BYONM enabled)
│ ├── exploit.ts (require("evil-pkg"))
│ └── node_modules/
│ └── evil-pkg/
│ └── package.json (main: "../../../secret.json")
└── secret.json (outside --allow-read scope)
```
Run:
```bash
deno run --no-prompt --allow-read=/tmp/deno_byonm_poc/app exploit.ts
```
Observed:
Deno.readTextFileSync("/tmp/deno_byonm_poc/secret.json") — blocked, asexpected.
require("evil-pkg") — returned the parsed contents of secret.json,bypassing the read allowlist.
A control run with BYONM disabled (--no-config) blocked the require call.
The vulnerability allowed a hostile npm package installed under a BYONM node_modules to read JSON files outside the directories granted via --allow-read, up to the privileges of the OS user running Deno. In practice this exposed configuration and credential files (.env.json, cloud credentials, package lockfiles, etc.) that the user had deliberately excluded from the read scope.
The vulnerability did not grant any capability beyond what the OS user already held, did not affect runs that granted unrestricted --allow-read, and required the user to have installed and then required a hostile package, i.e. an existing supply-chain compromise. The reason it warranted a security advisory rather than a routine bug fix is that Deno's permission model
promised that --allow-read=<scope> was a hard boundary *even over untrusted npm code*, and that promise was broken.
Not affected:
path that rejected the traversal).
--allow-read (no boundary to bypass)..js/.cjs/.mjs targets executedrather than exposing file contents, which already implied attacker code
execution within the granted permission set.
Users on unpatched versions could mitigate by:
nodeModulesDir: "manual") for projects that dependedon untrusted packages.
package.json main fields in node_modules for .. segmentsbefore running.
--allow-read only when the read scope already covered every filethe OS user could see (in which case there was no boundary to bypass and no
additional exposure).
This issue can be reached with local access to the system, attack complexity is low, an attacker needs low-level privileges on the target. No user interaction is required. The scope is unchanged, so the impact stays within the vulnerable component. Rated impact: confidentiality high, integrity none, availability none.
The score comes from this vector: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
JLSEC-2026-657 is recorded against 1 package.
Published on 7 July 2026 and last revised on 18 July 2026. No public exploit is currently recorded for this entry. Record sourced from OSV.
github.com (Web)
github.com (Web)
deno-jll has other advisories on record. If you are patching this one, these are worth checking on the same host:
Details
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Affected Packages
| Software | From version | Fixed in |
|---|---|---|
| deno-jll | — | — |
References
Similar Threats
Free Vulnerability Check
BotEraser helps you identify potentially vulnerable plugins and themes by checking your installation against JLSEC-2026-657 and other known CVE records.
Scan My Site Free →No credit card required · Results in minutes
ⓘ Data Notice: The information presented above has been compiled from publicly available internet sources. Boteraser aggregates this data solely for informational purposes and does not independently classify, evaluate, or endorse any findings about the vulnerabilities listed. The accuracy and completeness of this information is the sole responsibility of the original publishers. Boteraser and its operators accept no liability for any decisions made based on this data.
Stay up to date with the latest from Boteraser.
We use cookies to improve your experience on our site. By using our site, you consent to cookies.
Manage your cookie preferences below:
Essential cookies enable basic functions and are necessary for the proper function of the website.
CloudFlare provides web performance and security solutions, enhancing site speed and protecting against threats.
Service URL: developers.cloudflare.com (opens in a new window)
These cookies are needed for adding comments on this website.
These cookies are used for managing login functionality on this website.
Statistics cookies collect information anonymously. This information helps us understand how visitors use our website.
Google Analytics is a powerful tool that tracks and analyzes website traffic for informed marketing decisions.
Service URL: policies.google.com (opens in a new window)
You can find more information in our Cookie Policy and Privacy Policy.