One of many original triggers to build SilverBullet (I was using Obsidian at the time) was that I found its plug-in system somewhat problematic from a security perspective. Basically it enabled running arbitrary JavaScript in the Obsidian client. So you’d have to trust the plugin authors to not do malicious stuff. Using Obsidian basically meant installing a hundred plugins, so this made me feel slightly uncomfortable. I had ideas on how to do this better and therefore built the PlugOS system into SilverBullet, where plugs largely run in a sandbox that does not have access to random JS APIs, but can only communicate with the client through syscalls. I never got to really security harden it, but the model in principle allows for this.
Then, a year or so ago, I decided to target SilverBullet really at the true power user: a hacker-style, self hosted audience. Basically, people that know what they’re doing technically, and can take responsibility for the code they run (to some degree). This, in my mind, made it ok to introduce Space Script — which, much like Obsidian plugins, effectively eval
your own JavaScript code in the main browser thread. Again, powerful (and easy to implement), but potentially dangerous if you don’t know the code you’re running. My rationale at the time was that it would only run code that you can actually see on your page (in a space-script) block, and it would never be much. So it should be ok. Still, I added an environment variable to disable space script completely, for those who are not comfortable with it.
Then, Space Lua happened. Once more, one of my arguments for introducing it was the idea of offering a much more controllable runtime environment than “random JavaScript.”
And, once again, the debate in my head came back to balancing power vs security given our audience.
For instance, should I offer Lua APIs to:
- Make HTTP requests? This could be used in malicious ways, potentially.
- Embed inline HTML widgets (currently this is supported, and a very powerful feature, but questionable from a security perspective)
- Import external JavaScript libraries (don’t tell anybody, but this is actually possible with the
js.import
call in Lua): super powerful feature, but again: you’re effectively allowing to run arbitrary JS code again - Give access to the DOM somehow?
- Allow running of shell commands on the server?
etc. etc.
Now since I control the Lua environment, I could give users fine grained controls about what to allow and what not to allow. HTTP calls yes, but only to domains A, B, and C. And JS imports no, or only with exceptions. And perhaps only from space lua scripts stored in specific folders. That type of thing. Technically this is feasible. It’s hard, but I’m sure it can somehow be done.
I envision that in time, a lot of Lua code will be distributed via Libraries. For instance, code completion for Space Lua is already implemented and distributed as such: Library/Std/Lua
Could we expect that people who import such a library read the code to make sure that it’s ok? Should they just trust the source (me — so, obviously ok). Or should we somehow design a system that sandboxes such libraries more than their “own” code? This is actually pretty damn tricky. There are a bunch of destructive syscalls already, like space.deletePage
, which one could argue should be disabled by default.
Or… considering the target audience, do we just say: YOLO. You choose SilverBullet to have the power, and we should trust you with it. If you download SilverBullet, everything out of the box is safe and ok. The moment you start to pull scripts from random sources it’s your responsibility to make sure to check them. We’re not going to pretend to try to make this very safe.
Because going that route (power over security) would simplify a lot.
Opinions?