I think that's the better approach - just assume all packages are malicious by default. Can't rely on scanners because of the large number of packages and attacks.
I think that's the better approach - just assume all packages are malicious by default. Can't rely on scanners because of the large number of packages and attacks.
1. An attacker who can access your development environment and your production environment is worse than one who can only access your production environment. You might say "but the end goal is prod", but it's not that simple because of (2).
2. We already have very good tooling for isolating services at runtime. Separating them onto different instances, firewall/security groups, limited API keys, docker/ containers, apparmor, selinux, etc. We have a lot of tooling for "a service in production is owned". What we lack is "a library in dev environment is owned".
3. Devs often have more privileges than your services. It's unfortunate but at a lot of companies, perhaps given some lateral movement around dev envs, you'll find SSH keys to production, browser session cookies that give you console access, source code, chat sessions, internal documents, git keys, gpg keys, etc.
So I'm actually fine with a tool that sandboxes the build process but leaves open the hole of "but the attacker can patch the binary and execute code in production". That's a huge win.
If we can spot odd behavior during development and eliminate it from our stacks, the product will be more secure for end users too.
There was a time when convenience overrode any security doubts in my mind. But now I routinely use these tools to restrict access, monitor, and review runtime behavior.
The only allowed package (gem) server was one ran by the project. This package-server scanned, vetted and manually checked any version of a lib before "publishing it".
If you wanted to e.g. upgrade a package, you'd have to do this on this server first. It would then go through some steps, -automatic scanning, risk analysis, sometimes even needing the eyes of someone from a security team. After that the package was published on this server, and you could pull it onto your dev machine and use it in CI/staging/test/prod etc. Similar steps, to get a new package listed.
IMO this is better, because it stops supply-chain attacks before they hit your code, not after they've (potentially) infected the system.
Edit: for clarity "only allowed package" wasn't enforced very strictly. A linter and CI would catch any changes to code that would want to fetch packages from elsewhere. It wasn't to protect against rogue developers, but against "stupid me, accidentally upgrading to a version that is infected" and such.
If you run everything from the new UID, it will mostly be contained to it's own $HOME directory and be unable to modify your user's files or system files. Some distros do not protect home directories from being read so it might be worth setting your actual user's $HOME to umask 0700 or whatever.
If you are using bwrap while running X11 and not running the sandbox with a new UID, the sandboxed processes may be able to escape via the X11 socket! This can happen even when you don't mount the X11 socket into the sandbox (see abstract sockets)! I think unsharing the network namespace fixes this specific issue (not 100% sure), but there are probably more subtle footguns like this.
I really suggest running Wayland with XWayland disabled, and the Wayland socket protected from the sandbox if you want to use bwrap for security purposes!
Is there no way to safely run graphical applications in a bwrap sandbox? I thought Wayland was supposed to be better about this.
On Wayland, assuming you don't have XWayland enabled and running, it depends on the specific compositor you are using and what Wayland protocols it supports.
Sandboxing GUI stuff on Wayland requires at the very least not having XWayland running, and also requires understanding what the compositor allows clients to do by default. Some compositors may have permission dialogues that prevent clients from doing stuff that you didn't expect.
Unless your code is never going to touch important data or resources, like for example (but not limited to) being used commercially in any vein then you can’t keep it in a padded cell forever.
Where possible, persuade end users too to be equally careful. The "linux is safe" cliche blinds both us and end users to its obvious security problems, like running every script as the logged-in user with the same level of access. These malware developers know it and rely on it. That's why we need to move everybody towards a restrict-monitor-verify mindset by default.
It's absolutely not a foolproof approach, but it is a lightweight layer that can be used in a "defense in depth" approach.
1. https://github.com/ossillate-inc/packj [Disclaimer: I built it]
What you are building is mainly a smoke detector (and maybe a bit of a sprinkler if it takes some decisions itself), not fireproof doors (that only at install, not test- or runtime). Smoke detectors by themselves cannot prevent fires from spreading and are not completely reliable.
Analysis tools are still useful - even with perfect language-level access and resource control, packages which are given many required permissions may behave maliciously (e.g. through compromise of any component in the development or distribution pipeline), or return malicious data (which is out of scope/unsolvable at the language level). Both approaches complement each other nicely.
I'm very frustrated with firejail since I can't for example block execution in my home directory, with the exception of one subdirectory.
It just can't be done.