deno icon indicating copy to clipboard operation
deno copied to clipboard

`new Worker()` does not honor `permissions: { import }`

Open lowlighter opened this issue 7 months ago • 1 comments

deno 2.3.3 (stable, release, x86_64-unknown-linux-gnu)

//worker.ts
onmessage = async () => {
  console.log(await import("jsr:@std/text"))
  self.close()
}
//test.ts
const worker = new Worker(new URL("worker.ts", import.meta.url), { type: "module", deno: { permissions: { import: false }}})
worker.postMessage(null)

The worker is able to successfully import external package while it has been denied permissions:

vscode ➜ /workspaces/metrics5 (x2025) $ deno run -I --allow-read=worker.ts --no-prompt test.ts 
[Module: null prototype] {
  closestString: [Function: closestString],
  compareSimilarity: [Function: compareSimilarity],
  levenshteinDistance: [Function: levenshteinDistance],
  toCamelCase: [Function: toCamelCase],
  toKebabCase: [Function: toKebabCase],
  toPascalCase: [Function: toPascalCase],
  toSnakeCase: [Function: toSnakeCase],
  wordSimilaritySort: [Function: wordSimilaritySort]
}

Using import: [] or import: ["deny.invalid"] (workaround from #29502 in the cli) yields the same result

I suspect this come from the default values that somehow doesn't get overriden when passing the deno.permissions object to a new worker https://github.com/denoland/deno/blob/ab9673dcc172e2c0b7a521b3527eb5ce2cf3858c/cli/args/mod.rs#L889-L896

In the main context you're able to deny default by overriding the flag as expected, so it'd be assumed that it's possible to do in workers too

vscode ➜ /workspaces/metrics (x2025) $ deno run --allow-import=deny.invalid --no-prompt test.ts 
error: Uncaught (in promise) TypeError: JSR package manifest for '@std/text' failed to load. Requires import access to "jsr.io:443", run again with the --allow-import flag
console.log(await import("jsr:@std/text"))
            ^
    at async file:///workspaces/metrics/test.ts:3:13

lowlighter avatar May 29 '25 04:05 lowlighter

Also there's no userland workaround since #27050 is still open

vscode ➜ /workspaces/metrics (x2025) $ deno eval 'Deno.permissions.query({name:"import"})'
error: Uncaught (in promise) TypeError: The provided value "import" is not a valid permission name
Deno.permissions.query({name:"import"})
                 ^
    at Permissions.querySync (ext:runtime/10_permissions.js:211:13)
    at Permissions.query (ext:runtime/10_permissions.js:203:34)
    at file:///workspaces/metrics/$deno$eval.mts:1:18

lowlighter avatar May 29 '25 05:05 lowlighter

I'm pretty sure the error comes from prepare_load() in cli/module_loader.rs.

There is a branch to consider workers as dynamic modules to trigger permissions checks: https://github.com/denoland/deno/blob/1ef0d0838ee6785da0458dc09ad936c00364741a/cli/module_loader.rs#L1104

But I'm pretty sure the import permissions are always inherited from parent as the following block suggest: https://github.com/denoland/deno/blob/1ef0d0838ee6785da0458dc09ad936c00364741a/cli/module_loader.rs#L1068-L1072

They get passed at two places in the same function: https://github.com/denoland/deno/blob/1ef0d0838ee6785da0458dc09ad936c00364741a/cli/module_loader.rs#L1114-L1121 https://github.com/denoland/deno/blob/1ef0d0838ee6785da0458dc09ad936c00364741a/cli/module_loader.rs#L1131-L1135

lowlighter avatar Sep 02 '25 03:09 lowlighter