But that fails for developers (which is more or less synonymous with "CLI users"). Development is all about data and fine grained tools, not apps.
You check out a file with git, then edit it with vim, and build it with gcc, which pulls in headers generated with a python script, itself having been configured with, I dunno, cmake gadgetry. Where do you draw the boundaries here?
I mean, you can draw a big circle around all your development activities. Products have been invented that do that. They're called "IDE's", and are sort of the metaphorical opposite of the command line tools we're discussing, and not really a solution to the people choosing to use this environment.
Alternatively, you can view the whole development system as a sandbox. Do your work in a separate VM or docker instance, for example. Some people actually do that (in particular folks with windows desktops who need linux tooling will recognize this), and while it's not generally considered a security technique, it certainly could be.
I would really like some simple way to limit what build scripts can do. For example, they shouldn't be able to read and write arbitrary files in my home directory, even though they should be able to read /usr/lib and the like. They shouldn't be able to contact the Internet (or even the LAN) without explicit permission. They shouldn't be able to do anything with my display unless I permit it.
Is there some command available for Linux that lets me set up a quick sandbox so I can detect and stop trojans in build scripts? Virtual machines, chroots, containers, and Docker are all good but they don't solve this problem. SELinux has the potential to solve this but it's extremely complex. Instead of "./configure && make", I want to type something like "sandbox ./configure && sandbox make"; sandboxed build scripts should work the same as if they're outside the sandbox.
I would guess the biggest hurdle in using such systems is the complexity and expertise required in drafting the specific rules that should apply in your threat model.
Though docker does not completely isolate the build process, it definitely limits writable local directories to those explicitly mounted into a container.
An extra bonus is that docker also installs on Windows and on MacOS and is controlled seamlessly, so our developers are free to choose whatever OS is needed for native development.
Of course, we should be aware that exploits are quite likely to exist, since much of Linux was designed without a notion of namespaces.
For me, the main issue with docker in terms of security is that it's not clear what security you're giving up when running containers (eg, various projects expect you to do `docker run -v /var/run/docker.sock:/var/run/docker.sock ...`, and things like `docker-compose` essentially specify arbitrary invocations of containers). When ways of escaping are discovered, they get fixed, since those escaping mechanisms are not really considered part of the execution model for containers.
Have you heard of Plash?
http://www.cs.jhu.edu/~seaborn/plash/html/
While the software itself is outdated, and the design is fundamentally limited by the goal of compatibility with existing Unix programs, I think it's a good proof-of-concept of how you could design a sandboxed command line, especially if you were building everything from scratch.
Basically, any filename argument you pass to a command is no longer just a string; it becomes a capability granting that command access to that file.
So:
- Check out with git: `git clone https://url foo` includes `foo`, so you're giving it permission to create a directory named `foo`. Other git commands don't take the repo root as an argument. If you're redesigning the world, perhaps they should. Alternately, git could have a custom sandbox that identifies the directory containing .git and grants access to the whole thing.
Note: In Plash you have to stick in `=>` to grant read-write access, but I'll ignore syntax details since I'm thinking more in terms of broad strokes of a hypothetical design.
- Edit with Vim: `vim foo.c` gives permission to `foo.c`. (Vim also supports opening new files within the editor; in theory that could be redirected to some sort of powerbox, though it's harder than with GUIs.)
- Configure with cmake: `cmake .` would grant permission to read/write the current directory.
- Run make: You'd want syntax like `make .` rather than implying the current directory. (Again, Plash has a solution for this but I don't care about the specifics.)
- Generate headers with a Python script: make would invoke the script, passing it the input/output paths as capabilities.
- Build with GCC: One of the Plash examples is `gcc -c foo.c => -o foo.o`.
Will Vim be allowed to read `~/.vimrc`?
If not, how should I configure Vim system-wide?
(If the answer is "with a daemon", then: is Vim allowed to connect to the daemon and read its configuration?)
If yes, why?
(If the answer is "because you configured the system so", then: how is this different from SELinux?)
Just kidding. :)
The thing is that access to shared state is hard. Any access is a potential security threat.
Finding a balance between functionality and security is one of those areas that I fear are in the NP-hard-equivalent area of system design.
For example: I mark ~/school/operating-systems as a development directory. I place git, vim, wget, curl, and make on the blacklist (potentially globally-configured). Additionally I whitelist ~/.config/git for git and ~/.vim for vim. This allows core commands that we consider 'safe' like cd, mv to be run without restrictions - presumably they are only being used manually or from sandboxes tools like Make. But when I execute git from anywhere inside ~/school/operating-systems, it will only be able to R/W inside that directory and within the ~/.config/git directories. Meanwhile read access to system folders lets Make etc. work properly.
With a single global configuration + directory-specific overrides, it remains pretty straightforward and doesn't require a huge time investment like AppArmor/SeLinux do. Meanwhile all non-dev work remains unaffected. If you need to download and build a random program, just mark it as a dev directory and you're pretty safe. It's not perfect, but better than nothing
I don't recall the exact configuration format, but it's something really simple, like
whitelist ~/src/*None of this should not require access to things like my web browser, my ~/.config directory, some directory like ~/build/go containing an unrelated project.
> They're called "IDE's"
IDEs don't exist for security reasons, but I think you can at least use the existence of these things as evidence that there is a sensible way of scoping development activities. I imagine it wouldn't be a major hindrance if IDEs did provide this sandbox functionality, where you could still launch a shell within the IDE, and that shell would be in a mount/pid namespace controlled by the IDE.
Personally, I want something that applies not just to development, but general computer use. If you go back 15 years, it was probably fairly typical for someone to expect to download an run an "EXE" file. Now the expectation is that a website or phone app is used instead, which has fewer security implications.
Surely there must be some path for moving to something more secure when it comes to commandline usage.
It does! I want to configure git and vim globally, I want to start a development server and use my browser to access it. I want to netcat a file because IT policies restrict ssh...
"su - project1"
Maybe? I don't really think it's an opposite thing anymore. Most of my projects are written/browsed/debugged in an IDE but not built/configured/etc. in the IDE, and the testing, git, docker, code review, etc. work just happen in a console instance or web browser next to the IDE.
To a lesser degree, seccomp is similar but you don't have an easy way of applying a profile to a binary (instead the binary would need to self-apply the profile or you'd need to come up with a separate way of running programs so that a profile would be auto-applied).
The problem is that users want to be able to edit any file on the filesystem with their text editor -- if you don't allow vim to edit files in /etc/ then admins won't be able to do their job (though, please use "sudo -e" instead of "sudo vi").
It can, in two ways: the current context (say, user_dev_t) needs execute permissions on the declared type of the executable (say, git_exec_t), and additionally, you can declare a type transition to be performed per calling context.
To keep with the git example (I admit it's a bit contrived), you could label your .git directory as git_repo_t and deny access for both user_t (normal user context) and user_dev_t (user dev context). Then, you can define a type transition as above (user_dev_t -> git_exec_t => git_t), and allow only the context git_t access to git_repo_t files. With this setup in place:
- git, as called from within user_dev_t works as normally
- git, as called from user_t, has no defined type transition so will try to access git_repo_t under the user_t context, which will fail.
Usually I check over things like make files and am immediately concerned if I'm told to run a "build.sh" (especially as root.)
On android the security is kind of an illusion anyway, it's pretty common for apps to either find ways to escape it or trick the user into granting permissions that the apps abuse. The worst offenders are often preinstalled by the hardware vendor anyway and since you don't usually control the OS are impossible to remove.
These sound like security bugs, which should obviously be addressed, but "there are bugs" shouldn't be a reason to dismiss the entire goal of isolation-based security. When it comes to the browser, there are obviously occasional issues to do with colouring of visited links, sandbox escapes, information exposure due to speculative CPU execution. Overall though, what's important is that there is a security model and that the implementation issues are addressed.
I hope we can at least put it off until it's a real problem and not turn the world upside down for a largely theoretical one. I also doubt any sort of sandboxing will be effective and practical to run software from untrusted sources.
Recently posted on HN: http://http.jameshfisher.com/2019/05/26/i-can-see-your-local...
On Android and iOS, any application is supposedly running in its own sandbox, where it can't just randomly access files used by the rest of the system (including other applications).
The web is obviously strongly based around a security model where a website ultimately can't do much in terms of information access (eg, a properly designed website's information is protected from other websites) .. as I understand it, this was not always the case (we're not using ActiveX anymore, right?).
In the desktop space, this pattern is supposedly supported by Flatpak, and I think the macOS store (though I'm not sure about this—I haven't actually used either).
Meanwhile, when a random developer decides to run `make` or `npm install` or `mvn install` or even `vim foo.txt`, they're essentially trusting their entire computer to whoever created the content in their working directory.
Will there be some revolution at some point that encourages people to somehow isolate their commandline activities to different realms, thus limiting the scope of any attack like this?