I want to point out some of the consequences of the current --allow-net design and how we might want to move forward.
--allow-net does not differentiate between listen and dial.This means that if I want to allow a script to establish a client connection with a local database server on localhost I have to do --allow-net=127.0.0.1:3306 (for example). However if that DB is down then the port might be available and that same script, should it be malicious, can create a server on 127.0.0.1:3306 and listen to incoming connections. These connections would be other unsuspecting clients who are connecting to the DB with their usernames and password. Yikes! 馃槺
Typically short-lived services that need to act as servers obtain an open port from the OS. In the file-server example in Deno docs the file server is given access to all of net with --allow-net. This strikes me as far too broad and defeats the purpose of a sandbox.
A port could be specified manually, but that puts the burden on the user to find an open port. If the port is hard-coded in the script it would likely conflict with something else sooner or later, and running two instances of the script would fail.
(Note that this is only a problem for scripts that run unattended. Otherwise I can just respond to prompts from the CLI.)
Basically what I would like is an option like --allow-open-ports=1 which would allow the script to obtain one randomly assigned open port when it tries to listen.
Let me know what you think, thanks.
Good points and a clear example of the problem. I'm open to fixing this. --allow-open-ports seems kinda verbose though. I wonder if we could come up with something more succinct...
@afinch7 - do you have any opinions on this?
I like the idea of --allow-open-ports, but I'm not really a fan of adding another flag just for this. The port would need to allocated during the listen op to avoid TOCTOU problems.
I agree that --allow-net is too broad for some use cases, and I would support adding some more specific expressions like --allow-net=127.0.0.1:3306/d,127.0.0.1:3000/l.
In the long term I would like to see a system that allows code based definitions for security policy, but I think we need to figure out what we want to do with ops before we do that.
I'm not sure --allow-net=127.0.0.1:3000/l is the right way to do this. The /lcould be part of a URL, so that if in the future you want to make --allow-net able to limit requests to certain paths within a domain (like --allow-net=github.com/denoland) things will get confusing.
If you were to use a new flag some more succinct names might be:
--allow-listen--allow-serve (or --allow-server)Hi there, have there been any further thoughts on this?
I would suggest the following:
allow-net gives permissions to make outgoing requests only.allow-serve lets you create a server and bind to a port. --allow-serve=:8080--allow-serve=:osThis I believe creates a clear distinction between permissions related to making requests and permissions for creating a server, and lets you use OS-selected ports without giving the script unlimited access to net.
Thanks.
Hi all. I'm new here.
I stumbled across this issue while diving deeper into Deno tonight. So this is coming from a relative newcomer.
I'd love to see something that mimics the naming of the functions in the Deno. namespace.
--allow-net=* (same as specifying both options)
--allow-net-listen=*
--allow-net-connect=*
For listening on ports assigned by the OS, I'd expect Deno to count how many ports I've been assigned since the program started, and throw an error if I ever overcome that maximum.
--allow-net-listen-max=6
Potentially this could be extended in the future to restrict listening to a maximum number of ports at once. I'm having trouble thinking of a good use case, but for completeness, here's what that might look like:
--allow-net-listen-max-concurrently=3
I think this design is simple, easy to guess / remember, and increases with obscurity as the security requirements become more structured.
I also think those flags are reasonably concise, and larger scripts with many defined permissions would probably be run via a shell script versus a copy/pasted cli line anyway, in which case brevity becomes less crucial.
One downside I could see might be user "laziness", as it'd be convenient to just use the --allow-net shorthand over the more specific options, but on the other hand, it's always kinda impossible to stop people from taking shortcuts when defining security policies (ie. tacking on -A and calling it a day).
Anyway, figured I'd share some thoughts. Apologies if I'm not understanding the full scope of this discussion. Thanks and congrats on the 1.0 release!
Most helpful comment
Hi there, have there been any further thoughts on this?
I would suggest the following:
allow-netgives permissions to make outgoing requests only.allow-servelets you create a server and bind to a port.--allow-serve=:8080--allow-serve=:osThis I believe creates a clear distinction between permissions related to making requests and permissions for creating a server, and lets you use OS-selected ports without giving the script unlimited access to net.
Thanks.