On Security

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?

I think it depends a lot on the goals/vision/target audience.

I love the freedom and hacky nature that Silverbullet has. No other platform scratches that itch better and I love it. That said, I’d not recommend it to non-IT people or ‘normies’, as it can get complex quickly and you can break a lot of things as is if you are not careful (they wouldn’t use most of the features anyway).

  • For me: gimme more power, I know what I am doing (famous last words)
  • For normies: make it more secure and fool-proof

You’ve already provided some examples; maybe offer some kind of options would be great:

  • vanilla’-mode - secure, locally, more restricted
  • danger’-mode - less restricted, less secure

Another thought: single-user vs hosting/multi-user regarding power vs security

  • single-user instance/ personal (current focus): I know what I am doing, I am responsible, I am in control and more than happy to have more power = pro power
  • multi-user instance/ providing hosting: less control, much more room for abuse, I want to limit it to provide a secure application and hosting experience = pro security

This is only relevant if the focus changes, but might be worth mentioning.


I think that is fair.

Just some thoughts - I’ll think about it a bit more.

2 Likes

This reminds me of Firefox—it’s powerful because of its extensive plugin ecosystem, but only a few plugins are officially recommended. Users have the freedom to install whatever they want, but they also take responsibility for what they run.

For SilverBullet, I think a good balance between power and security would be a permission system where plugins and scripts explicitly declare what access they need (e.g., making HTTP requests, modifying pages, executing shell commands), and users approve them before use. This way, users stay in control while keeping the flexibility that makes the tool valuable.

1 Like

I think we should separate two concerns here: code people just import and use and code people write themselves. The former would be mostly plugs (I don’t exactly know what the further plan is for libraries, maybe we would have to consider those too) and the latter space-lua.
I think that most people currently use plugs or have plugs loaded without ever really thoroughly reviewing the source code (myself included), which makes sense, because why would you take the time - or some may not have the knowledge, but are still perfectly capable using the plug.
Space-lua however will be written yourself most of the time, so we can assume it’s not malicious. Sometimes it may be copied but then I would argue that it’s still safe to assume it’s not malicious as people are then forced to look at the code compared to plugs for example. (The only time space-lua may not be safe is when a non tech-savy person just straight copies some finished solution, but firstly finished solutions should always be provided as a plug (which we should mention somewhere) and secondly I think it’s safe to assume people who use silverbullet aren’t that dumb (i.e. not tech-savy doesn’t mean dumb).)

This leads me to the conclusion that we should make plugs secure using a permission system and leave space-lua as the hackable powerful tool it is/will be.

(BTW there would still be some stuff to fix about plugs: 1. Pretty sure i was able to brick a silverbullet instance again by importing a file that wasn’t even a plug. 2. The iframes should definitely be sandboxed properly)

So here’s the thing. I think the direction where things may be heading is that people will opt to build more and more advanced functionality using Space Lua. I myself (for testing) developed a set of space lua scripts that allow me to directly interact with OpenAI-API based LLMs in various ways. Previously this was only really doable by building a plug (like @justyns did), but I would not be surprised if space lua scripts become the primary way to build deeper extensions where previously plugs were your only option.

If that’s the case, how would those be distributed? I would say libraries: Libraries

However, Libraries have no different “status” over whatever you wrote yourself. They’re yet another set of pages. Therefore SB cannot (currently) really distinguish between stuff you pulled from external sources (like for instance the Core library is currently pulled) and your own things. Both could contain space lua.

Having fine-grained permissions like this would be ideal to me at first glance. But then you raise effort needed for creating simple space script/space lua. I could then see the permissions being optional and only used if they’re defined in the frontmatter or somewhere, but most people would simply ignore it because it’s easier.

A user-friendly way of handling permissions could be something like popping up a “Do you want to allow this script to make http requests to Domain A” the first time it tries to, and then storing that in an allowlist somewhere. But again, having to approve that could get annoying and not used.

Having a whitelist of directories allowed to execute anything could also work. E.g. I keep most of my own scripts in Library/Personal and would just whitelist that whole directory.

I’m not opposed to this route if you choose it. For the most part, users could share scripts on this discourse where there’d be at least a small amount of peer review.

One last thought: An audit log of sorts for plugs/space lua/space script could be useful. Something that shows requests being made by different scripts. So if something weird does happen, there’d be a way to track it down easier.

I’ve been a Linux user since the early days. I enjoy being able to do what I want. If I mess up my system, that is my responsibility and an excellent opportunity to learn as well.

Silverbullet has been targeted from the beginning to those with a hacker mentality. Generally, the typical user will not be comfortable using Silverbullet. Even the documentation is written in such a way as to appeal to those with such a mentality assuming a certain level of knowledge or the ability to acquire it. The typical user wants everything to be easy and handed to them in very simple terms.

Given the above, I’m not in favor of making Silverbullet available to more than one user. This opens the door to people who don’t have a hacker mentality. Better to leave it in single user mode. There are plenty of other note taking apps that serve the typical user.

As it stands, the user bears the responsibility for the security of their instance of Silverbullet which, IMO, is as it should be.

This is meant for the Hacker Minded computer user. I vote to keep it powerful and flexible for those with a Hacker mentality. There are plenty of note taking apps that cater to the normal user.

6 Likes

Given the target audience (hackers), I’d say that it’s OK to give the lua script libraries a more “privileged” access. It’s similar to what would happen if you npm install some library to your computer, the library has also “privileged” access to your computer from the get-go with the postinstall script.

But of course, if we had the resources, then a permission system like on Android would be favourable.

For me, it would be enough to have:

  • Secure mode: scripts are not allowed to access FS or make network requests
  • Everything allowed mode (if we can choose only one, this would be the one)

If all work outside of the lua sandbox is done through syscalls, we’ll even keep the door open for more granular permission settings in the future.

1 Like

While I :heart: sb for its metaprogramming power, the “any page may contain code that can do everything” situation can be problematic.

As I see it, at the moment the only safe way to access content in silverbullet that is writable by others is to have space-script completely disabled.

Let’s say I have a shopping list page in silverbullet that other family members can edit, as a simple shared text file. Now anyone can add a poisoned script-item to the list, which will happily execute in my personal instance, steal my secret notes, trash my stuff etc. Could even go full root-kit by “installing” itself in my space on first view and expose a hidden api for control and exfiltration.

An effective remedy would be to have more control about what space-script can be executed depending on the location of the code.

Currently, there is the global SB_SPACE_SCRIPT choice between ‘notebook’ and ‘turing-bomb’. It could be extend to a more granular allow/deny/ask permission system that would help to create security boundaries:

Something like

allow = {"Library/","mystuff/","index"}
deny = { "Shared/","!", "#pastebin"}
ask = { "*" }

could result in space-script

  • running in my “personal” pages, no questions asked
  • not running on shared pages and federated pages (bonus: tags for pages where execution is not desired, similar to #notoc)
  • user descision anywhere else (my idea would be creating a hash for each executable block and asking for confirmation whenever the hash changes)
    • that would be nice for pages shared between a small group (like the shopping list example) where script functionality is desired but I still want to take a look and not give everyone blanket full access to my brain extension)
    • maybe even split into “ask” and “ask_once”?

The mechanism could also be extended to differentiate between different privilege levels like network, file, syscall etc.

Long-term, adding concepts for “users” and “groups” and narrowing permission levels down to stuff like “read page”, “write page” etc. , and it could emerge as backbone of a full-blown multiuser ACL system.

2 Likes

Another thing to improve security would be to whitelist/allow list the domains that can be called and commands (especially shell commands) that can be executed.

Especially if we can combine that with directory or file level allow listing.

This is going to be my rant. Ignore it as you wish.

Consider the following:

  1. Silverbullet was developed by @zef for his use.
  2. @zef decided to make silverbullet available to those with a “hackers mindset” to use as they see fit.
  3. @zef is working full-time, as I understand it, while continuing to work on Silverbullet.
  4. As Silverbullet becomes ever more complex and huge, a time will come where @zef will no longer be able to maintain the system.
  5. There are a number of people here that act as though they are typical users. They make requests/demands, criticize, and complain without lifting a single finger to help.

@zef, I would encourage you to only put into Silverbullet what you will use and nothing else.

Any other functionality should be developed in the form of scripts and plugins or as code which should be implemented into a fork of Silverbullet. Then, the developer bears all responsibility for the results while adding nothing to @zef’s work load.

To My Fellow Users: My message is simple, either find a way to use Silverbullet as is or write scripts, plugins, or additional code probably in a fork which you are willing to maintain and support to make it into something you can use.

Stop acting like a typical computer user who expects the developer of the software to create and maintain everything he wants while he acts as the critic and judge. Be willing to take part. You create and maintain what you want in Silverbullet yourself. Demonstrate that “hacker mindset”. Otherwise, there are plenty of other more complete note taking applications developed with the typical user in mind.

I came from Logseq. Logseq had everything that I wanted in a Note Taking app and I was ecstatic. Then the developers decided to move from basing it on markdown files to basing it on a database of their own design. While they insisted that they would provide a way to extract the data back to markdown files, doing so will become ever more difficult as they add more functionality to the database until they will inevitably decide to no longer provide database to markdown conversion capability. I want full control of my data. So, this was unacceptable.

Silverbullet isn’t Logseq. Attempting to make Silverbullet act like Logseq would be an arduous task indeed. I chose, instead, to see if I could create a different workflow using what Silverbullet already made available. After all, if @zef could use it, then maybe I could too.

I have come a long way down that path. I am using Silverbullet full-time. Logseq is still on my system giving me access to those files for the time being. Eventually, I’ll either incorporate some of those files into my Silverbullet PKM or I’ll delete them.

I’m still in the midst of building and modifying my Silverbullet workflow. So, I’m going to wait until my workflow stabilizes a bit more before I attempt to integrate some of the Logseq content into Silverbullet.

End of rant.

@zef, I strongly encourage you to keep Silverbullet as a system that is primarily for your use. This will keep it manageable for you. Let others fork it or modify it for themselves. I would discourage turning it into a multi-user system since the security issues alone would be a full-time job which seem to be getting more difficult as time goes on. Besides, you will never be able to please all of the user minded people since they cannot even agree among themselves. They are spoiled children. Keep silverbullet a system for the “hacker minded” only. Keep it a system that you want to use and are able to easily maintain.

2 Likes