Quite often, security and functionality are two opposing forces. Vendors are trapped in a zero-sum game between providing their users as much freedom in the software they use and limiting said freedom to create tightly controlled and secure products. But this does not have be the case.
For the last several years, Linux users have had the opportunity to run snaps, containerized applications that bundle all their dependencies inside standalone packages. By design, snaps are isolated from one another and limited in the resources they can access. Snaps are available in the Snap Store, an app store that is similar to the prevalent software distribution model in the mobile world. This gives developers the ability to publish their applications outside the conventional Linux channels – but also brings about the question of security.
In this blog post, we would like to highlight several important security mechanisms and features in the snap ecosystem, which should help you understand how snaps work, what isolation systems and tools are in place, and the process of publication of applications to the Snap Store.
A licence to snap
Let’s start with the developers’ side of the story. There are several security mechanisms in the publication process, including application confinement, per-source control, and checks, both automatic and manual, of uploaded snap packages.
Developers create and build their applications by writing an application manifest in snapcraft.yaml. The snapcraft command parses this file and builds a snap. If the process is successful, the snap can then be uploaded to the store and made available to the users.
One of the mandatory declarations the developers must provide during the build process for their applications is the confinement level. This dictates what the application will be able to do once installed on the user’s system.
There are three levels of confinement:
- Devmode – This is a debug mode level used by developers as they iterate on the creation of their strict-level snap. This allows developers to troubleshoot applications, because they may behave differently when confined.
- Strict – This confinement level uses Linux kernel security features to lock down the applications inside the snap. By default, a strictly confined application cannot access the network, the user’s home directory, any audio subsystems or webcams, and it cannot display any graphical output via X or Wayland. This is the preferred method for building snaps. We will discuss this in more detail later on.
- Classic – This is a permissive level equivalent to the full system access that traditionally packaged applications have. Classic confinement is often used as a stop-gap measure to enable developers to publish applications that need more access than the current set of permissions allow. The classic level should be used only when required for functionality, as it lowers the security of the application.
During runtime, application confinement is enforced via Discretionary Access Controls (DAC), Mandatory Access Control (MAC) via AppArmor, Seccomp kernel system call filtering (limits the system calls a process may use), and cgroups device access controls for hardware assignment. Specifically, Ubuntu also uses YAMA Linux Security Module in Canonical-supported kernels, and provides ptrace scoping, symlink and hardlink restrictions.
As mentioned earlier, a strictly confined snap is considered untrusted, and it runs in a restricted sandbox. By design, untrusted applications:
- can freely access their own data
- cannot access other applications data
- cannot access non-application-specific user data
- cannot access privileged portions of the OS
- cannot access privileged system APIs
- may access sensitive APIs with user permission provided the API asks for permission at time of access or the permission is granted to the application outside of snap installation
Strictly confined applications are not always functional with the default security policy. For example, a browser without network access or a media player without audio access do not serve their intended purpose. To that end, snap developers can use interfaces. These allow developers to expand on existing permissions and security policies and connect their applications to system resources.
Interfaces are commonly used to enable a snap to access OpenGL acceleration, sound playback or recording, the network and the user’s $HOME directory. But which interfaces a snap requires, and provides, is very much dependent on the type of snap and its own requirements.
An interface consists of a connection between a slot and a plug. The slot is the provider of the interface while the plug is the consumer, and a slot can support multiple plug connections.
Some interfaces can be auto-connected. Users have the option to manually control interfaces – connect and disconnect them. If you do want to see what type of interfaces any snap application has, you can check this on the command line:
snap interfaces gimp
Snap Store review
All uploaded snaps are reviewed before they are published. When the author of an application releases a new version, the snap package is uploaded to the Snap Store and the snap undergoes automatic reviews. Part of this review process involves examining the snap’s requested resources. In fact, users can run these checks themselves before uploading the snap, to make sure there are no issues that could delay the publication of their snap. This is done using the review-tools snap, as we discussed in the troubleshooting article last week.
If a snap passes the review, it can be made immediately available to users and devices. If it doesn’t, the snap is blocked and a manual review is triggered. The store’s upload policies and the security policies associated with an individual snap’s declared interfaces work together to limit the number of attack surfaces.
Moreover, classically confined snaps are reviewed by the Snap Store reviewers team before they can be published. Snaps that use classic confinement may be rejected if they don’t meet the necessary requirements. In parallel, the review team will work with developers to identify any missing features in the snap service to enable publishers to move from classic to strict confinement.
Snap Store – the user side
A user’s journey into snaps will start by the discovery of new applications in Snap Store. This can be done online, through the store, a desktop store frontend, or on the command line in a terminal window. For instance, snap find browser will show results for all the snaps that have the string ‘browser’ in one of their searchable fields (name, summary or description). Similarly, snap install firefox will install the latest, stable version of the Firefox snap on your system.
The Snap Store also comes with several other mechanisms designed to make both the snap installation and user experience safe and reliable:
- Snaps are digitally signed.
- Verified publishers have a badge so they can be easily identified.
- Users have tools to vet the publisher via ratings, reviews and the ability to report a snap.
Integration in traditional software managers
Snap installation is also possible through desktop store frontends that support the snap backend functionality. GNOME Software and KDE Discover are two examples of such programs.
When users download and install snaps, they have the option to review the list of “permissions” that an application requires, and manually override them. This is similar to installation prompts that users see on smartphones. In some cases, this may change or break the application behavior.
For instance, if you disable the camera interface in a VoIP client, you will not be able to use video in calls, or the application may crash. The security (AppArmor) policies are tuned to deny (but not kill) a process that tries to perform a disallowed action, and users should check errors messages if they encounter problems.
Snaps are designed and configured to be automatically updated when a new version is available. From the security standpoint, this provides users with the latest bug fixes and patches for the software they use.
The snapd service will query the Snap Store periodically (four times a day by default) and install new updates. It will first check and verify the signature of the snap with the Store’s public key. If the verification succeeds, the snap will then be installed.
Snap a day (four times a day) keeps the doctor away.
The updates mechanism is designed to be reliable, so if an update fails (for whatever reason), the snapd service will roll the application back to the previous version without a loss of functionality.
But the updates are only as good as developers publishing important updates and security patches to their software.The Snap Store also features automatic notifications on security vulnerabilities detected in the store. Software publishers will receive emails informing them about outdated packages in their snaps, so they can address them.
Is this perfect?
No. But it is a fairly reasonable, flexible model that has some advantages over the classic deployment methods. In the real world, there will always be a compromise between security and functionality. Too much of the former, and the application becomes unusable. Too much of the latter, and there is a risk of things getting out of hand.
Snap security cannot work around the underlying issues in the operating system, but it can limit what the applications do to some level while still providing the essential functionality that is expected from the software. They also introduce control granularity, through the confinement levels and interfaces, which are not available otherwise. The user also has the ability to manually tweak the behavior of the snaps if they choose so.
Lastly, while snaps aims to protect the system from applications and applications from each other, they cannot address inherent flaws in the applications themselves. This means that applications must keep the bundled software components up to date.
Snap security is a layered system that builds on solid foundations already laid out in Linux. The security exists on all levels of the snaps lifecycle, including the store, the installation, confinement during runtime, and the system-level mechanisms that prevent snaps from affecting other applications or the underlying libraries.
Automatic updates are another important feature. It allows users to run the latest available version of software, with all the associated bug fixes and patching, and helps developers maintain good security and reliability of their products. In a follow-up article, we will delve on the underlying security mechanisms in Ubuntu, as well as talk about Ubuntu Core. For now, if you have any comments, please hop over to the forum for a discussion.