6 ms·
Is there a theoretical framework that can prevent this from happening? Proof-carrying code?
by l___l 1y ago
Is there a theoretical framework that can prevent this from happening? Proof-carrying code?
- dist-epoch 1y agoThere are, but they have huge performance or usability penalties. Stuff like intents "this is a math library, it is not allowed to access the network or filesystem". At a higher level, you have app sandboxing, like on phones or Apple/Windows store. Sandboxed desktop apps are quite hated by developers - my app should be allowed to do whatever the fuck it wants.
- IshKebab 1y agoDo they actually have huge performance penalties in Javascript? I would have thought it wouldn't be too hard to design a capability system in JS. I bet someone has done it already. Of course, it's not going to be compatible with any existing JS libraries. That's the problem.
- killerstorm 1y agoYou can do that by screening module imports with zero runtime penalty.
- deleted 1y ago[deleted]
- tarruda 1y agoSomething similar to Deno's permission system, but operating at a package level instead of a process level. When declaring dependencies, you'd also declare the permissions of those dependencies. So a package like `tinycolor` would never need network or disk access.
- pxc 1y agoDoes Deno's sandboxing not extend to build time?
- diggan 1y agoProbably signatures could alleviate most of these issues, as each publish would require the author to actually sign the artifact, and setup properly with hardware keys, this sort of malware couldn't spread. The NPM CI tokens that don't require 2fa kind of makes it less useful though. Clojars (run by volunteers AFAIK) been doing signatures since forever, not sure why it's so difficult for Microsoft to follow their own yearly proclamation of "security is our top concern".
- madeofpalk 1y agoI would like to see more usage of NPM/Github Actions provenance statements https://www.npmjs.com/package/sigstore#provenance https://www.npmjs.com/package/sigstore#provenance through the ecosystem > The NPM CI tokens that don't require 2fa kind of makes it less useful though Use OIDC to publish packages instead of having tokens around that can be stolen or leaked https://docs.npmjs.com/trusted-publishers https://docs.npmjs.com/trusted-publishers
- mzl 1y agoManual verification of releases and chain-of-trust systems help a lot. See for example https://lucumr.pocoo.org/2019/7/29/dependency-scaling/ https://lucumr.pocoo.org/2019/7/29/dependency-scaling/
- killerstorm 1y agoObject-capability model / capability-based security. Do not let code to have access to things it's not supposed to access. It's actually that simple. If you implemented a function which formats a string, it should not have access to `readFile`, for example. Retrofitting it into JS isn't possible, though, as language is way too dynamic - self-modifying code, reflection, etc, means there's no isolation between modules. In a language which is less dynamic it might be as easy as making a white-list for imports.
- pjc50 1y agoPeople have tried this, but in practice it's quite hard to do because then you have to start treating individual functions as security boundaries - if you can't readFile, just find a function which does it for you. The situation gets better in monadic environments (can't readFile without the IO monad, and you cant' call anything which would read it).
- killerstorm 1y agoWell, to me it looks like people are unreasonably eager to use "pathologically dynamic" languages like JS & Python, and it's an impossible problem in a highly dynamic environment where you can just randomly traverse and change objects. Programming languages which are "static" (or, basically, sane) you can identify all imports of a module/library, and, basically, ban anything which isn't "pure" part of stdlib. If your module needs to work with files, it will receive an object which lets it to work with files. A lot of programming languages implement object-capability model: https://en.m.wikipedia.org/wiki/Object-capability_model https://en.m.wikipedia.org/wiki/Object-capability_model it doesn't seem to be hard at all. It's just programmers have preference for shittier languages, just like they prefer C which doesn't even have language-level array bound checking (for a lack of a "dynamic array" concept on a language level). I think it's sort of orthogonal to "pure functional" / monadic: if you have unrestricted imports you can import some shit like unsafePerformIO, right? You have another level of control, of course (i.e. you just need to ban unsafePerformIO and look for unlicensed IO) but I don't feel like ocap requires Haskell
- l___l 1y ago
- viraptor 1y agoYou can protect yourself using existing tools, but it's not trivial and requires serious custom work. Effectively you want minimal permissions and loud failures. This is something I'm trying to polish for my system now, but the idea is: yarn (and bundler and others) needs to talk only to the repositories. That means yarn install is only allowed outbound connections to localhost running a proxy for packages. It can only write in tmp, its caches, and the current project's node_packages. It cannot read home files beyond specified ones (like .yarnrc). The alias to yarn strips the cloud credentials. All tokens used for installation are read-only. Then you have to do the same for the projects themselves. On Linux, selinux can do this. On Mac, you have to fight a long battle with sandbox-exec, but it's kinda maybe working. (If it gained "allow exec with specified profile", it would be so much better) But you may have guessed from the description so far - it's all very environment dependent, time sink-y, and often annoying. It will explode on issues though - try to touch ~/.aws/credentials for example and yarn will get killed and reported - which is exactly what we want. But internally? The whole environment would have to be redone from scratch. Right now package installation will run any code it wants. It will compile extensions with gyp which is another way of custom code running. The whole system relies on arbitrary code execution and hopes it's secure. (It will never be) Capabilities are a fun idea, but would have to be seriously improved and scoped to work here.
- chrisweekly 1y agoWhy yarn instead of pnpm?
- viraptor 1y agoIt doesn't matter. It applies the same to all those tools.
- pnappa 1y agoYeah, LavaMoat (https://github.com/LavaMoat/LavaMoat https://github.com/LavaMoat/LavaMoat). Dependencies are pinned with capabilities, and scripts are disabled by default.
- jcgl 1y agoI think I’m gonna start wrapping most of my build commands (which are inside a makefile) with bwrap. Allow network access only for fetching dependencies. Limit disk access (especially rw access) throughout. Etc.
- jcgl 1y agoIf anyone is interested, I've added this BWRAP_BUILD variable to a makefile in my project that builds a Go and SvelteKit project. I then preface individual commands that I want sandboxed within a make target (e.g. mybin below). PATH_ELEMENTS := $(subst :, ,$(PATH)) BIND_COMMANDS := $(foreach element, $(PATH_ELEMENTS), --ro-bind-try $(element) $(element)) define BWRAP_BUILD bwrap \ --unshare-all \ --unshare-user \ --die-with-parent \ --disable-userns \ --ro-bind /usr/ /usr \ --ro-bind /lib64 /lib64/ \ --ro-bind /lib /lib \ --ro-bind /etc/alternatives/ /etc/alternatives/ \ --ro-bind $(CURDIR) $(CURDIR) \ --proc /proc \ --clearenv \ --setenv PATH $(PATH) \ $(BIND_COMMANDS) \ --setenv GOPATH $(GOPATH) \ --ro-bind $(GOPATH) $(GOPATH) \ --setenv TMPDIR $(XDG_CACHE_HOME)/go-build \ --bind $(XDG_CACHE_HOME)/go-build $(XDG_CACHE_HOME)/go-build \ --setenv XDG_CACHE_HOME $(XDG_CACHE_HOME) \ --dev-bind /dev/null /dev/null \ --setenv PNPM_HOME $(PNPM_HOME) \ --bind-try $(PNPM_HOME) $(PNPM_HOME) \ --setenv HOME $(HOME) \ --bind-try $(CURDIR)/ui/.svelte-kit $(CURDIR)/ui/.svelte-kit \ --bind-try $(CURDIR)/ui/build $(CURDIR)/ui/build \ endef mybin: $(deps) $(BWRAP_BUILD) go build -trimpath -ldflags $(ldflags) ./cmd/mybin/ Notes: most of the lines after --setenv GOPATH... are specific to my project and tooling. Some of the lines prior are specifically to accommodate my tooling, but I think that stuff should be reasonably general. Lmk if anyone has any suggestions.