Most current operating systems (all Unix-based, Windows) have one major disadvantage, which is critical to security:
By default and with minor exceptions, any application can read any system file, execute any application and read+write any user data. Minor exceptions are:
- Windows: ACLs for AppData/Roaming
- RBACs like SELinux, AppArmor: massive amount of metadata for blacklisting and whitelisting
- filesystem permissions based on user name and file metadata: limited approach
This leads to situations that can go wrong easily:
- any application running as my user ID can read all my application data and private data, leaking them to 3rd parties e.g. over the network
- any application can modify any application data of other applications, installing malware or messing them up
- any application can modify my private data without me knowing
More specific, these situations are used by attackers:
- my web browser is able to run a shell – it doesn’t have to
- my PDF reader application can edit files like
~/.bashrc
installing malware
Most problematic situations described above can be avoided by a more strict, whitelist-based design:
- by default, any application can see no files
- exceptions to the rule above:
- files owned by the application (executable)
- shared libraries used and files owned by them
- configuration files
- some applications need to be excluded from these rules, e.g. file managers or some command line tools
Access to user private data (e.g. traditional “Desktop” folder) is done by a third party, some kind of delegate process related to a file manager, displaying and handling file chooser dialogs.
Examples:
- A user want to download a file with my web browser. My web browser invokes the delegate process, which opens a file chooser letting the user choose where to save the file. The delegate may remember this location (e.g. “Downloads folder”) and permanently allow the web browser to save files there. The web browser still doesn’t have any write access to any private data except writing new files to Downloads dir.
- A user wants to edit a private file using an editor or word processor. This application calls the delegate, the delegate opens a file chooser and lets the user select a file to open. Then it transfers the file (or file descriptor) to the application.
- A user wants to edit a system config file. As above, it asks the delegate to show a file chooser dialog. The delegate can act as a authentication agent allowing an unprivileged application edit this file and doing the privileged operation (open/save file) in the delegate.
Results and positive side-effects:
- reduced attack surface. GUI applications don’t usually need to start shells
- reduced space for packaging mistakes and programming errors
- clear distinction between private user data and user-specific application data
- metadata is available for removing user-specific application data when application is removed
- have a usable and safe way for unprivileged applications editing privileged files
Downsides:
- Breaks many applications, often breaks portability of Unix applications to Redox.
- If applications were strictly complying to the XDG Base Directory Specification, porting most stuff should be easy
- User private files open/save handling has to be done through a delegate process. There is some work on that at Gnome (2) and freedesktop.org with xdg-app, named “portal” instead of “delegate” there
- probably more code
- more processes running
Any comments or ideas on that?
Is there any chance to get this implemented in Redox? Do you want to be backwards compatible or stop making the same mistakes Linux is doing?
Edit: You could use existing partial solutions and do sandboxing, chroot or use (Linux) namespaces, but this introduces an overhead. And all those technologies are not enabled by default, but have to be configured for each application. Implementations are not tested well enough and are written in a monolithic C software or kernel.