Should we, or how should we, use Deno as a sandbox for untrusted code?
I've been using Deno in this context because of some of the nice security model features. However, it's been tricky hitting snags with the model. For example, user's code runs in a WebWorker and has a specific environment with limited access to APIs. But there's no permission to enable/disable the creation of new
Worker
objects, so people can create a worker in the worker that has access to raw APIs. Is there a right way to do this?13 Replies
so people can create a worker in the worker that has access to raw APIsCould you clarify what you mean by this?
Sure, so - even if I lock down the permissions of a worker to something like reading one particular file, and
net: true
, you can can create a worker in that worker to run code in a new context with a new scope, which is something i'd like to prevent. I suspect that ShadowRealms are the long-term solution to controlling this kind of scope, but for now it's not clear what a good solution would be.
Like let's say I want to override fetch
for user code, so i do that by controlling scope. Then, a user can create a worker and use the native fetch
impl.
i'm going to block access to Worker
in scope, but I'm trying to learn whether there's a smarter way to solve this problemworkers should not be able to escalate permissions, this seems like a huge security issue if this actually works
workers should only be able to spawn workers with the same permissions or less
maybe i’m misunderstanding something about your question here?
i would suggest using deno subhosting
because you still have stuff going on with CPU/RAM limits
and ofc someone could use your service to DDOS some other url
^ if you want scale this is probably the right thing to do
or use isolated-vm, im using that one but its not deno
I think workers should just work
There should be no exploits to escape the sandbox
They could definitely ddos someone or bitcoin mine or whatever though so I’d be careful about that
thanks, yeah - it's not quite escalation, but it's more like… controlling what's in scope for user code, and then being able to access those things
like if you don't want people to be able to call, say,
Deno.env
or postMessage
, you can put their code in a function that overrides those variable reference in scope, but they can use a worker to bail out of that
i'm hunting around for things like this, that can restrict what user code can do, making parts of scope opt-in rather than opt-outI see. I think the ShadowRealm API may be able to cover this use case but I’m not too sure
very intresting!
just do
globalThis.Worker = undefined
?
that would prevent creation of new workers
also you'd want to remove some more stuff like Deno[Deno.internal]
in that scope too 🙂I did not think about that
fair enough
yeah, it's been a battle of slowly adding more and more things to function arguments like
((Worker, Deno) => {})()
so that they're set as undefined in the function scope
it seems like the ShadowRealm proposal is the perfect fix for this, though I'm not 100% sure on how it'll manage imported modules and whether that'll land anytime soon
we'd also be a user of the noDenoNamespace
option for workers, if that was still around