Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Project idea: Security sandboxing guidelines #631

Open
l0kod opened this issue Sep 24, 2024 · 4 comments
Open

Project idea: Security sandboxing guidelines #631

l0kod opened this issue Sep 24, 2024 · 4 comments

Comments

@l0kod
Copy link

l0kod commented Sep 24, 2024

As talked about in today's meeting, it would be good to have guidelines to help developers sandbox their applications.

Landlock is the Linux sandboxing mechanism designed for such use case which requires an unprivileged access control system. It can be used through 3 dedicated syscalls to create and enforce a security policy on the calling task (e.g. the developer's application) and its future children.

We already have:

Who is interested in this topic?

@david-a-wheeler
Copy link
Contributor

I like the idea of creating guidelines for Landlock, especially if there are examples.

Configuring Landlock for a specific use seems to involve writing code. If that code is built into an application, I'd want to see how to write the code so the application will still run on other systems (e.g., *BSDs, MacOS, Windows) and quietly skip Landlock. This does run the risk of an application's sandboxing quietly failing - how do you prevent that? (I bet there are easy answers, guidance would be helpful).

I see that Landlock expects to be configured by creating & compiling code. A lot of higher-security systems don't allow arbitrary code to be brought in & compiled. Is there a way to create a separate configuration file to control Landlock for a specific application? Maybe, instead of guidelines, we should build such a general tool so people can easily (re)configure Landlock for various users without recompilation.

We might want to later generalize to other sandboxing systems, e.g., bubblewrap, which I believe is used by Flatpak, libgnome-desktop, and sandwine. It's okay to give separate guidance for each separately, but cross-comparisons might help improve guidance for each.

@l0kod
Copy link
Author

l0kod commented Sep 25, 2024

I like the idea of creating guidelines for Landlock, especially if there are examples.

Sure, this tutorial should help.

Configuring Landlock for a specific use seems to involve writing code. If that code is built into an application, I'd want to see how to write the code so the application will still run on other systems (e.g., *BSDs, MacOS, Windows) and quietly skip Landlock. This does run the risk of an application's sandboxing quietly failing - how do you prevent that? (I bet there are easy answers, guidance would be helpful).

This is indeed important, as well as backward compatibility. Detecting non-Linux systems may already be done at build time for compiled software, so it would only be a matter of a #if check. Backward compatibility can be checked with a landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION) call. This is much easier with the high-level libraries though.

I see that Landlock expects to be configured by creating & compiling code. A lot of higher-security systems don't allow arbitrary code to be brought in & compiled. Is there a way to create a separate configuration file to control Landlock for a specific application?

Landlock can be seen as a building block to create sandboxes. There are two use cases:

  1. sandboxer tools (designed to launch arbitrary applications) leveraging Landlock and defining their own configuration,
  2. any other applications willing to sandbox themselves.

These two use cases are complementary. Systems need to be compiled at some point and this is where Landlock can be used for the second use case. The first use case can help when we don't own applications/services and cannot change their code (for various reasons). Of course these notions are relative and may mean something different for a developer, a sysadmin, or a distro/product maintainer.

Maybe, instead of guidelines, we should build such a general tool so people can easily (re)configure Landlock for various users without recompilation.

I'd like to help developers, who may not depend on tools installed on the system, but they know very well how their applications work and what access is legitimate and required. This is what I mean by application sandboxing: to integrate security into applications. Two advantages of this approach are that it can be transparent for users (but not for attackers) and it can be tested in a CI like any other features relying on the kernel (i.e. most of them).

There is already a few sandboxer tools that leverage Landlock, and I also plan to work on a new one, but such tool will never be as transparent and well-integrated as embedded sandboxing.

We might want to later generalize to other sandboxing systems, e.g., bubblewrap, which I believe is used by Flatpak, libgnome-desktop, and sandwine. It's okay to give separate guidance for each separately, but cross-comparisons might help improve guidance for each.

Bubblewap is a very useful sandboxer tool, but it mainly relies on namespaces, which were not designed for security and are not an access control system. This tool needs to be SUID, the use of namespaces increases the kernel attack surface, and there is no fine-grained access control. Some parts of Bubblewrap could be implemented with Landlock though.

Guidance on these tools would be nice too, but my main goal is to help developers, that can then build secure apps/tools for users, sysadmins, and distro maintainers. My understanding was that this working group is dedicated to developers, not users/sysadmins/distros.

I think application sandboxing should be part of secure development guidelines. It is complementary to the use of secure APIs/libraries, hardening compiler options, input sanitization, and other good practices.

@valoq
Copy link

valoq commented Oct 1, 2024

The idea of providing a developer guideline for sandbox technologies is something I have also been thinking about for several years and I would be happy to contribute to such a guide.

To start with a bit of feedback on existing guides based on my own experience:
Landlock is quite easy to implement in small applications and the existing documentation already does a decent job in my opinion. I have recently implemented landlock in zathura and also just opened a PR for ouch and while I found it quite easy to get started with landlock (especially compared to seccomp) there are possibly checks and cases that are missing to provide a optimal implementation. A review of the mentioned implementations may reveal potential issues that need to be addressed more in documentations, assuming I am not the only one to miss them.

On a more general note, I strongly feel like the topic of sandboxing needs a fundamental documentation that distinguished between the different approaches and meaning of the term. As the above discussion already indicates, and so do many discussions on this topic, it is easy to misunderstand what the different tools accomplish and what their limits are.
For example there is a significant different between a well designed sandbox that separates privileges within an application to run dangerous code in a well restricted child process (like OpenSSH, chromium and firefox do it) and a simple container that provides a runtime to start arbitrary applications in, which is what bubblewrap/flatpak, firejail and an even docker represent.

In many discussions there seems to be no differentiation between these two kinds of sandbox implementations, but while the first kind that implements sandboxing as part of the application code itself can potentially provide a significant resilience even against dedicated adversaries, any sandboxing tools that build around existing applications provide far less protection against adversaries
that actively try to circumvent the isolation. For example, even if syscall filter are used with bubblewrap/flatpak/firejail, the system calls that need to be whitelisted are any and all system calls that the application may require during its entire lifetime. On the other hand, even a rather simple seccomp implementation like we did for zathura can deny access to most system calls, even without the use of a broker architecture that uses a separate child process. (Though I would still like to implement one in zathura eventually). In the case of zathura, the current seccomp filter is simply enabled after the application has initialized, just before a target document is opened (read untrusted data is parsed)

Ideally it would become normal to split applications into different process to implement strong sandboxing like the role model applications OpenSSH/Chromium do it, though it may be overkill for some, more simple tools. In order to approach this process splitting/broker architecture I found the sandboxing-api project to be a most interesting approach that should not be missing in a sandbox developer guide. This approach targets libraries and allows to run the parsing code inside a different process while providing a simple stub api for any applications that want to make use of it, thereby requiring no significant changes to the application using the sandboxed library api. There are several example implementations for different open source projects like curl for example, but none of these have made it into the actual upstream repos.

One additional benefit from landlock that I personally see is that is makes the first step towards linux application sandboxing very easy. Implementing seccomp filter can be quite difficult and it requires a lot of testing since different architectures and even libc backends may use different syscalls for the same functionality. Additionally new versions of dependencies may introduce new
syscalls as well, which may break the application if the used policy is too strong (can be avoided by using errno instead of kill policy)
Landlock on the other hand is quite simple to understand and the side effects are far less severe. It makes for a good first step that addresses the most obvious target for adversaries/malware (filesystem access). And once that is implemented tested and accepted, further improvements with seccomp can provide a full sandbox implementation that makes any attempt of meaningful exploitation an expensive if not impossible endeavor.

To recap:

  • A guide should explain the different existing sandbox approaches and how they differ in terms of provided protection and drawbacks, leading towards a clear recommendation of implementing sandbox technologies inside the actual applications instead of using less effective container technology.
  • landlock should be the first step for sandbox implementations in existing projects, followed by a guide towards (lib)seccomp for meaningful kernel isolation.
  • sandboxed-api should be promoted for use in open source projects (currently mainly being used only by google)

@balteravishay
Copy link
Contributor

Thanks all for the discussion! Is this something you would like to bring to one of our next WG meetings to discuss further as a new incubating project (@l0kod @valoq) ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants