Skip to main content

Deno EUVDEUVD-2026-38547

| CVE-2026-49401 HIGH
Improper Resolution of Path Equivalence (CWE-41)
2026-06-16 https://github.com/denoland/deno GHSA-8xpq-cjcf-3wh9
8.4
CVSS 3.1 · NVD
Share

Severity by source

NVD PRIMARY
8.4 HIGH
AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N
vuln.today AI
8.4 HIGH

Attacker needs local code execution inside the sandbox (AV:L, PR:L); default case-insensitive APFS makes the bypass low-complexity (AC:L); escaping the permission boundary changes scope (S:C) to read/write protected files (C:H/I:H).

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

Primary rating from NVD.

CVSS VectorNVD

CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N
Attack Vector
Local
Attack Complexity
Low
Privileges Required
Low
User Interaction
None
Scope
Changed
Confidentiality
High
Integrity
High
Availability
None

Lifecycle Timeline

10
Analysis Updated
Jun 26, 2026 - 17:59 vuln.today
v4 (cvss_changed)
Analysis Updated
Jun 26, 2026 - 17:58 vuln.today
v3 (cvss_changed)
CVSS changed
Jun 26, 2026 - 17:52 NVD
7.3 (HIGH) 8.4 (HIGH)
Analysis Updated
Jun 23, 2026 - 18:41 vuln.today
v2 (cvss_changed)
Re-analysis Queued
Jun 23, 2026 - 18:22 vuln.today
cvss_changed
Severity Changed
Jun 23, 2026 - 18:22 NVD
MEDIUM HIGH
CVSS changed
Jun 23, 2026 - 18:22 NVD
5.2 (MEDIUM) 7.3 (HIGH)
Source Code Evidence Fetched
Jun 16, 2026 - 19:59 vuln.today
Analysis Generated
Jun 16, 2026 - 19:59 vuln.today
CVE Published
Jun 16, 2026 - 19:11 github-advisory
MEDIUM 5.2

DescriptionNVD

Summary

Deno's permission system enforces filesystem and execution restrictions by comparing the requested path against the path supplied to --deny-read, --deny-write, --deny-run, or --deny-ffi. On macOS, that comparison was done at the raw-byte level while the APFS filesystem treats different Unicode spellings of the same name as the same file.

That means a program could reach a denied path by spelling it differently than the deny rule. For example, with --deny-read=/secrets/passwörter.txt, a script could still read the file by opening /secrets/passwo\u0308rter.txt (NFD instead of NFC), or /SECRETS/PASSWÖRTER.txt (different case, since default APFS volumes are case-insensitive). Other forms include ligature characters ( vs fi, vs ff, …) and German ß vs ss.

The denied path and the requested path differed at the byte level, so Deno's permission check passed; the kernel then resolved them to the same inode and served the file anyway. The same flaw affected --deny-write, --deny-run, and --deny-ffi, which share the same path-comparison code.

Am I affected?

You are potentially affected if all of the following are true:

  1. You run Deno on macOS (the issue is specific to APFS path-equivalence

rules; Linux and Windows are not affected by this variant).

  1. You rely on --deny-read, --deny-write, --deny-run, or --deny-ffi

as a security boundary against less-trusted code - a dependency, plugin, or attacker-controlled input.

  1. The protected path contains characters that have alternate Unicode

spellings - most commonly accented characters (é, ñ, ö, …), German ß, or Latin ligatures - or you rely on case-sensitivity on a default APFS volume.

If you only run fully trusted code, or your deny rules cover paths that are pure ASCII with no case-sensitive aliases, you are not exposed to this specific bypass.

Impact

A program running with broad --allow-read (or --allow-write / --allow-run / --allow-ffi) but with --deny-* carve-outs for specific paths could read, write, execute, or load via FFI those denied paths by referring to them through a Unicode- or case-equivalent spelling. The sandbox model on macOS was weaker than the flags suggested.

Workaround

If you cannot upgrade immediately:

  • Prefer --allow-* allowlists over --deny-* denylists. Allow rules match

against the original specifier, so an attacker-supplied alternate spelling will not match a path you didn't explicitly grant.

  • Do not rely on case-sensitivity of paths on macOS for security boundaries;

default APFS volumes are case-insensitive.

Fix

On macOS, Deno now normalizes both the deny-rule path and the requested path to NFC and applies Unicode case folding before comparing them. This matches how APFS resolves paths at the inode level, so byte-different but equivalent spellings are now rejected by the same deny rule.

AnalysisAI

Permission-sandbox bypass in the Deno runtime (versions <= 2.7.13) on macOS lets untrusted code reach paths that operators explicitly blocked with --deny-read, --deny-write, --deny-run, or --deny-ffi. Because Deno compared paths byte-for-byte while APFS treats Unicode-equivalent and case-equivalent spellings as the same file, a script granted broad --allow-* but with --deny-* carve-outs can read, write, execute, or FFI-load a protected file by referring to it with an alternate spelling (NFD vs NFC, case folding, ligatures, or German ss vs ß). No public exploit identified at time of analysis, and EPSS is low (0.14%), but the bypass is trivial to perform once an attacker controls the path string.

Technical ContextAI

Deno enforces its capability sandbox in userspace by string-matching a requested filesystem/exec path against the operator-supplied deny rules before issuing the syscall. The root cause is CWE-41 (Improper Resolution of Path Equivalence): the kernel and the userspace check disagree on what 'the same path' means. macOS APFS normalizes filenames and, on default volumes, is case-insensitive, so /secrets/passwörter.txt, its NFD form /secrets/passwo\u0308rter.txt, and /SECRETS/PASSWÖRTER.txt all resolve to one inode - yet they are distinct byte strings to Deno's comparator. The denied string therefore fails to match the requested string, the permission gate opens, and the kernel serves the underlying inode. The CPE pkg:rust/deno reflects that the vulnerable comparison lives in the Rust core permissions code shared by all four --deny-* flags. The flaw is macOS/APFS-specific; the same logic on Linux and Windows is not affected by this variant.

RemediationAI

Primary fix: upgrade Deno to 2.7.14 or later (Vendor-released patch: 2.7.14), where macOS now normalizes both the deny-rule path and the requested path to NFC and applies Unicode case folding before comparing, matching how APFS resolves inodes. If you cannot upgrade immediately, the vendor-recommended workaround is to stop relying on --deny-* denylists for security and instead express the boundary as --allow-* allowlists, because allow rules match against the original specifier so an attacker-supplied alternate spelling will not match a grant you did not explicitly issue (trade-off: you must enumerate every legitimately needed path, which is more restrictive and may break code paths that depended on broad allow plus narrow deny). Additionally, do not treat macOS path case-sensitivity as a security property, since default APFS volumes are case-insensitive. Full guidance is in advisory GHSA-8xpq-cjcf-3wh9 (https://github.com/denoland/deno/security/advisories/GHSA-8xpq-cjcf-3wh9).

Share

EUVD-2026-38547 vulnerability details – vuln.today

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