PT-2026-50145 · Crates.Io · Deno
Published
2026-06-16
·
Updated
2026-06-16
·
CVE-2026-49401
CVSS v3.1
5.2
Medium
| Vector | AV:L/AC:L/PR:L/UI:N/S:C/C:L/I:L/A:N |
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/passwou0308rter.txt
(NFD instead of NFC), or /SECRETS/PASSWÖRTER.txt (different case, since
default APFS volumes are case-insensitive). Other forms include ligature
characters (fi vs fi, ff 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:
- You run Deno on macOS (the issue is specific to APFS path-equivalence rules; Linux and Windows are not affected by this variant).
- You rely on
--deny-read,--deny-write,--deny-run, or--deny-ffias a security boundary against less-trusted code — a dependency, plugin, or attacker-controlled input. - 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.
Fix
Found an issue in the description? Have something to add? Feel free to write us 👾
Related Identifiers
Affected Products
Deno