Hacker News new | ask | show | jobs
by losvedir 1366 days ago
Deno is pretty neat. I really want it to succeed. I really like TypeScript, and Deno almost gives me what I want: pretending TypeScript is a full-fledged language, with a standard library, that I can build non-frontend apps with. Let's just sweep all that JS-heritage and V8 stuff under the rug...

I've been playing with deno lately, and like it, but have been getting tripped up by some things.

I wish the standard library weren't at URLs like all the other packages. It would be great if the `deno` tool you downloaded also included the standard library, and you could just reference it without any network stuff. The documentation is also pretty cryptic (and I think autogenerated?).

The package management stuff I haven't quite wrapped my head around. Obviously, you shouldn't be downloading stuff willy-nilly, but I think with some combination of the conventional deps.ts, import_map, specifying a lock file, the vendor command, --no-remote, etc, I feel like I have all the pieces to kind of build up a reasonable approach, but I don't quite understand it all just yet.

Personally, the `--allow-read`, `--allow-net`, etc stuff feels a little gimmicky to me. I don't think other languages really have that, and I'm not sure what the threat model is here. I control the backend code, and if I'm worried about my code doing unexpected things like that I have larger issues. I just run with `-A` all the time.

4 comments

To the last point - imagine that you're using some library code, and you do an update, and now it starts trying to talk to some back-end server. That might be a good thing to stop.

Also, I'm looking forward to the idea of running a host like Deno, with applications inside that other people wrote. Kind of like sandstorm.io. I may be naive, but I'm hoping this happens really, really soon.

The problem is that you grant the privileges on the application level and not library level. You grant network access to your app and then some updated dependency suddenly starts communicating home and it wont prevent that.

It is also possible in Deno to set permissions for Workers but that's not just plug and play for existing libraries.

I suppose that depends on if you're blanket-allowing network, though. You could pass an allow list of ips/hosts that are allowed, though that's not going to be feasible for every application: https://deno.land/manual@v1.26.0/getting_started/permissions...
Yea you could restrict the app by whitelisting only the network services and folders that it will use and that's pretty valuable though at least on Linux could already easily be achieved otherwise. It's good that Deno makes it easy but let's be honest, most people will just pass -A.

I'd love to see a permissions system on a library basis. It would ask the first time a dependency is added and when a new permission is requested after an update. Javascript doesn't make that easy though by being so dynamic. SES could maybe help: https://github.com/endojs/endo/blob/master/packages/ses/READ...

On a library level won't be easy, as there will be wrapper libraries of some kind (axiom-style or whatever) and those wrapper lib will get the permission, so you'd then need a mechanism to prevent somebody calling into that library directly ... and not indirectly (say telling a third module to use the http-wrapper as a callback for some other thing) it is a rabbit hole
Workers are the solution here since they provide a security boundary. Access to the outside world must then be intermediated by your app. You might provide a version of fetch inside the worker that works through postMessage or SharedArrayBuffer allowing your app to filter the requests made by the untrusted script inside the worker.
Sure, I suppose if you granted it at the library level that might be good, but it's at the whole app level. You could maintain a very fine grained list of network URLs, though. That might be nice if you could configure in the `deno.config` file, rather than having to specify them all on the command line.

But this also gets at my "you have larger issues" comment. How is library code going to just start talking to a server? I like to review and audit all my dependencies and their changes, so it shouldn't just randomly happen. That's my whole problem with npm and its million dependencies and why I'm glad deno provides a standard library in the first place.

Regarding security:

You wrote an app that prints a quote in fancy fonts and colors in the terminal. Your code uses a library to format the text. The library attempts to read and/or write files that might contain secrets, then makes a network connection to an external address.

Contrived and silly example, but I think it illustrates the premise well.

Have you ever executed a script you didn't write? It's handy to have a runtime where you can see what a script can do from its permissions.

I'd generally like to see more languages with APIs for untrusted sections. If I know my program reads e.g. paths from untrusted files but should only ever access it's own folder, it would be nice to have a way to ensure that I can't get tricked into accessing something outside of it.

Actually, the use case of running other people's scripts is pretty neat. I audit pretty closely the code I use in my projects for work (the use case I was thinking of), but having Deno as a scripting platform, and running a script someone shared is a pretty neat place to apply the network/disk limits.
Nothing learned from node-ipc?