VYPR
High severityNVD Advisory· Published Jun 12, 2022· Updated Aug 4, 2024

CVE-2021-41641

CVE-2021-41641

Description

Deno <=1.14.0 file sandbox does not handle symbolic links correctly. When running Deno with specific write access, the Deno.symlink method can be used to gain access to any directory.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Deno <=1.14.0 allows sandbox escape via symlinks, enabling arbitrary directory access with partial write permissions.

Vulnerability

Overview

CVE-2021-41647 affects Deno versions up to 1.14.0, where the file system sandbox fails to properly handle symbolic links. The core issue is that the Deno.symlink method could be used to create symlinks that point outside the allowed sandboxed directories, bypassing permission controls [1]. This occurs because the runtime did not correctly validate the resolved path of symlinks when checking permissions.

Exploitation

Prerequisites

An attacker needs to run Deno with at least specific write access permissions (e.g., limited to a subdirectory). By creating a symbolic link using Deno.symlink, they can craft a link that points to a target outside the permitted directory. For example, creating a symlink to ../../etc and then moving an ancestor directory could cause the symlink to resolve outside the sandbox [2]. The attack does not require full filesystem permissions, only the ability to create symlinks within a directory where partial write access is granted [3].

Impact

Successful exploitation allows an attacker to read or write to arbitrary files and directories on the file system, effectively achieving a full sandbox escape. This could lead to data exfiltration, system modification, or privilege escalation depending on the Deno process's environment [1].

Mitigation

The vulnerability was addressed in Deno commit d44011a69e0674acfa9c59bd7ad7f0523eb61d42, which requires both full read and full write permissions to create symlinks [4]. This fix was merged in pull request #12554 and is included in Deno versions after 1.14.0 [2]. Users should upgrade to a patched version immediately.

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
denocrates.io
< 1.16.01.16.0

Affected products

2

Patches

1
d44011a69e06

fix(runtime): require full read and write permissions to create symlinks (#12554)

https://github.com/denoland/denoDavid SherretOct 29, 2021via ghsa
3 files changed · +34 4
  • cli/dts/lib.deno.ns.d.ts+2 2 modified
    @@ -2347,7 +2347,7 @@ declare namespace Deno {
        * Deno.symlinkSync("old/name", "new/name");
        * ```
        *
    -   * Requires `allow-write` permission. */
    +   * Requires full `allow-read` and `allow-write` permissions. */
       export function symlinkSync(
         oldpath: string | URL,
         newpath: string | URL,
    @@ -2364,7 +2364,7 @@ declare namespace Deno {
        * await Deno.symlink("old/name", "new/name");
        * ```
        *
    -   * Requires `allow-write` permission. */
    +   * Requires full `allow-read` and `allow-write` permissions. */
       export function symlink(
         oldpath: string | URL,
         newpath: string | URL,
    
  • cli/tests/unit/symlink_test.ts+28 0 modified
    @@ -108,3 +108,31 @@ unitTest(
         );
       },
     );
    +
    +unitTest(
    +  { permissions: { read: true, write: ["."] } },
    +  async function symlinkNoFullWritePermissions() {
    +    await assertRejects(
    +      () => Deno.symlink("old", "new"),
    +      Deno.errors.PermissionDenied,
    +    );
    +    assertThrows(
    +      () => Deno.symlinkSync("old", "new"),
    +      Deno.errors.PermissionDenied,
    +    );
    +  },
    +);
    +
    +unitTest(
    +  { permissions: { read: ["."], write: true } },
    +  async function symlinkNoFullReadPermissions() {
    +    await assertRejects(
    +      () => Deno.symlink("old", "new"),
    +      Deno.errors.PermissionDenied,
    +    );
    +    assertThrows(
    +      () => Deno.symlinkSync("old", "new"),
    +      Deno.errors.PermissionDenied,
    +    );
    +  },
    +);
    
  • runtime/ops/fs.rs+4 2 modified
    @@ -1370,7 +1370,8 @@ fn op_symlink_sync(
       let oldpath = PathBuf::from(&args.oldpath);
       let newpath = PathBuf::from(&args.newpath);
     
    -  state.borrow_mut::<Permissions>().write.check(&newpath)?;
    +  state.borrow_mut::<Permissions>().write.check_all()?;
    +  state.borrow_mut::<Permissions>().read.check_all()?;
     
       debug!(
         "op_symlink_sync {} {}",
    @@ -1432,7 +1433,8 @@ async fn op_symlink_async(
     
       {
         let mut state = state.borrow_mut();
    -    state.borrow_mut::<Permissions>().write.check(&newpath)?;
    +    state.borrow_mut::<Permissions>().write.check_all()?;
    +    state.borrow_mut::<Permissions>().read.check_all()?;
       }
     
       tokio::task::spawn_blocking(move || {
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

6

News mentions

0

No linked articles in our index yet.