D
Deno

help

How to restrict global scope in dynamically created function?

PPLPavel (Pasha) Lechenko2/12/2024
I want to dynamically create a function using Function() constructor. How can I restrict access to global scope? For example, this code:
console.log(new Function('return Deno.exit(1)')())
console.log(new Function('return Deno.exit(1)')())
should return something like Uncaught ReferenceError: Deno is not defined instead of providing full access to Deno's properties and methods. Is it even possible?
Llcasdev2/12/2024
This is not possible
Mmarvinh.2/12/2024
yup like luca said, it is not possible
PPLPavel (Pasha) Lechenko2/12/2024
Got it. Would be nice to see it in the roadmap 😉 A simple scenario/use-case - I want to allow my users to evaluate their ts/js script snippets in context of my object(s). In nodejs there is another option to run some code in restricted sandbox - use vm (https://nodejs.org/api/vm.html). In Deno I get:
~$ deno
Deno 1.40.3
exit using ctrl+d, ctrl+c, or close()
REPL is running with all permissions allowed.
To specify permissions, run `deno repl` with allow flags.
> import vm from 'node:vm'
undefined
> vm.runInNewContext('a',{a:123})
Uncaught ReferenceError: a is not defined
at <anonymous>:1:1
> const ctx = vm.createContext({a:123})
Uncaught Error: Not implemented: createContext
at notImplemented (ext:deno_node/_utils.ts:9:9)
at Object.createContext (node:vm:33:3)
at <anonymous>:1:37
>
~$ deno
Deno 1.40.3
exit using ctrl+d, ctrl+c, or close()
REPL is running with all permissions allowed.
To specify permissions, run `deno repl` with allow flags.
> import vm from 'node:vm'
undefined
> vm.runInNewContext('a',{a:123})
Uncaught ReferenceError: a is not defined
at <anonymous>:1:1
> const ctx = vm.createContext({a:123})
Uncaught Error: Not implemented: createContext
at notImplemented (ext:deno_node/_utils.ts:9:9)
at Object.createContext (node:vm:33:3)
at <anonymous>:1:37
>
Are there any plans to implement/support this?
Mmarvinh.2/12/2024
Quoting node's documentation page about the vm modules https://nodejs.org/api/vm.html
The node:vm module is not a security mechanism. Do not use it to run untrusted code.
No description
Mmarvinh.2/12/2024
FYI: Wasn't on our radar so far that there is a bug with the second parameter. I've filed an issue https://github.com/denoland/deno/issues/22395
GitHub
Bug: Second argument to runInNewContext not supported · Issue #22...
Input code: import * as vm from "node:vm"; vm.runInNewContext('a',{a:123}) Node: $ node Welcome to Node.js v20.11.0. Type ".help" for more information. > vm.runInNewC...
IioB2/12/2024
This is technically possible but I would strongly, strongly recommend against it If you use the deprecated with statement you can replace globalThis with a proxy which allows you to define what code inside the with statement has access to
PPLPavel (Pasha) Lechenko2/12/2024
Thank you. Sounds like dirty workaround. @lino-levan Here is a dirty trick:
console.log(
new Function(
[...Object.getOwnPropertyNames(globalThis)],
`const z = [];
for(const k of this.b) z.push(-k);
return [
self,
globalThis,
Deno,
crypto,
Object,
String,
Array,
this,
this.a.toUpperCase(),
this.b.filter(v => v > 2),
z]`
).bind(
{ a : "QWErty",
b : [ 1, 2, 3, 4, 3, 2, 1 ]
})
.call()
)
console.log(
new Function(
[...Object.getOwnPropertyNames(globalThis)],
`const z = [];
for(const k of this.b) z.push(-k);
return [
self,
globalThis,
Deno,
crypto,
Object,
String,
Array,
this,
this.a.toUpperCase(),
this.b.filter(v => v > 2),
z]`
).bind(
{ a : "QWErty",
b : [ 1, 2, 3, 4, 3, 2, 1 ]
})
.call()
)
This undefines all members of globalThis and allows access only to this poor-man's expression evaluator 🤣
IioB2/12/2024
interesting
PPLPavel (Pasha) Lechenko2/12/2024
even cooler:
const xxx = new Function(
'$',
[...Object.getOwnPropertyNames(globalThis)],
`const z = [];
for(const k of this.b) z.push(-k);
$.log('\\n\\nHello Console!\\n\\n');
return {
self: self,
globalThis: globalThis,
Deno: Deno,
crypto: crypto,
Object: Object,
String: String,
Array: Array,
this: this,
'this.a.toUpperCase()': this.a.toUpperCase(),
'this.b.filter(v => v > 2)': this.b.filter(v => v > 2),
'z': z}`
).bind(
{ a : "QWErty",
b : [ 1, 2, 3, 4, 3, 2, 1 ]
})
({log:console.log});

console.log('xxx', xxx)
const xxx = new Function(
'$',
[...Object.getOwnPropertyNames(globalThis)],
`const z = [];
for(const k of this.b) z.push(-k);
$.log('\\n\\nHello Console!\\n\\n');
return {
self: self,
globalThis: globalThis,
Deno: Deno,
crypto: crypto,
Object: Object,
String: String,
Array: Array,
this: this,
'this.a.toUpperCase()': this.a.toUpperCase(),
'this.b.filter(v => v > 2)': this.b.filter(v => v > 2),
'z': z}`
).bind(
{ a : "QWErty",
b : [ 1, 2, 3, 4, 3, 2, 1 ]
})
({log:console.log});

console.log('xxx', xxx)
This returns:
Hello Console!


xxx {
self: undefined,
globalThis: undefined,
Deno: undefined,
crypto: undefined,
Object: undefined,
String: undefined,
Array: undefined,
this: {
a: "QWErty",
b: [
1, 2, 3, 4,
3, 2, 1
]
},
"this.a.toUpperCase()": "QWERTY",
"this.b.filter(v => v > 2)": [ 3, 4, 3 ],
z: [
-1, -2, -3, -4,
-3, -2, -1
]
}
Hello Console!


xxx {
self: undefined,
globalThis: undefined,
Deno: undefined,
crypto: undefined,
Object: undefined,
String: undefined,
Array: undefined,
this: {
a: "QWErty",
b: [
1, 2, 3, 4,
3, 2, 1
]
},
"this.a.toUpperCase()": "QWERTY",
"this.b.filter(v => v > 2)": [ 3, 4, 3 ],
z: [
-1, -2, -3, -4,
-3, -2, -1
]
}

Looking for more? Join the community!

Recommended Posts
Typing for Dynamic importsSo I have a function like this that uses a dynamic import like ```ts export async function func1(imError with fetch called from npm moduleI am trying to use the `tsdav` NPM package with Deno, and have run into a problem with making an HTTCompile to exeEvery time I run my exe I get the following error, But when I start my code normally with node main.What does this library "assert" does?Hi https://deno.land/std@0.215.0/assert/mod.ts What does it do in this example? https://docs.deno.coWhat does this library "assert" does?https://deno.land/std@0.215.0/assert/mod.ts What does it do in this example? https://docs.deno.com/rLooking for an alternative to deno_domHi I'm looking for an alternative library to https://deno.land/x/deno_dom@v0.1.45/deno-dom-wasm.ts PCompile to exeEvery time I run my exe I get the following error: But when I start my code normally with node maiRunning untrusted code, eval-styleI have a project that on occassion I want to be able to execute JS code that I can then quickly get Available disk spaceI'm writing an API which will potentially create a large temporary file. I thought it would useful Verify AWS SNS signature with PEM certificateHello, I'm trying to verify aws sns messages in deno given a signing cert (in pem format, RSA sha1) Headers for WebSocket clientI need to connect Deno (as a client) to a WebSocket server that requires custom headers on connectioDeno testing with local oak serverI'm trying to setup a simple oak application for a few tests. The test steps work as expected but I Anyone aware of a streaming multipart parser for Deno?I'd like to handle the parts of a multipart/form-data stream in a server as they arrive rather than Deno does not deliver all the information with the EventSourceIs there some configuration or do I have to iterate in some way so that the entire message is delivegoogleapis.deno.devWhere can I find support for that lib? Tried [here](https://github.com/lucacasonato/deno_googleapisDeno LSP vscode issues when using Remote ExplorerOnce in every few minutes I have to restart LSP because it stops resolving unimported names which isHow to use Deno modules in Vite app (Vue specifically)I scaffolded an app using https://docs.deno.com/runtime/tutorials/how_to_with_npm/vue#run-npmcreate-deno_bindgen release 9.0@divy When is it coming? I've been waiting for a while for release 9.0... Is there any work going oIs it possible to connect to Deno KV from the browser?I'm intrigued by the premise of Deno KV, but I'm having trouble understanding how it currently worksDeno AI Assistant - How Are You Built?I'm interested to learn the architecture behind the Deno AI assistant. 1. What model(s) are used? 2