Plash: tools for practical least privilege

The powerbox: a GUI for granting authority

Introduction to powerboxes

What is a file powerbox?

A file powerbox is a kind of file chooser dialog box, and it works the same from the user's perspective. The difference is that as well as telling the application which file to access, it dynamically grants the application the right to access the file.

This helps provide security: It means that the application does not have to be given access to all of the user's files by default. This is an example of applying the principle of least privilege/authority: the aim is to give the program the authority it needs to do its job, but no more.

Why "least privilege" is important: an example

Suppose you run Gnumeric to view a spreadsheet you downloaded from the Internet. Gnumeric might not be a malicious program, but suppose it has a buffer overrun bug -- quite possible considering that it is written in C -- and the spreadsheet exploits that bug.

If Gnumeric runs with all your authority, the dodgy spreadsheet can read any of your files (such as "~/sensitive-file.txt", or your private keys from "~/.ssh") and send them back to its creator.

But if Gnumeric runs with minimum authority, the malicious spreadsheet can't do anything except write to the file it was opened from, and open a powerbox to request a file. The application cannot specify a default pathname for the powerbox to open, so for the spreadsheet to get access to a sensitive file, the user would have to specifically choose that file. The malicious spreadsheet would find it very hard to get access to ".ssh": why would the user choose ".ssh" if Gnumeric opened a powerbox out of the blue without a good reason?

How do powerboxes work?

In order for the powerbox file chooser to provide security, it cannot be implemented by the application and its libraries. It must be implemented as a separate, trusted component, and it must run in its own protection domain.

The idea is that the file chooser has a trusted path to the user, so only the user can enter a filename into it. This allows the system to distinguish between requests made by the user and requests made by the application.

The history of powerboxes

Powerboxes have been implemented in a couple of other systems already:

How to run programs to use the powerbox

Here is an example of running the simple text editor Leafpad so that it uses the powerbox:

pola-run --prog /usr/bin/leafpad \
  --env LD_PRELOAD=powerbox-for-gtk.so \
  -B -fl /etc \
  --x11 --powerbox --pet-name "Leafpad"

Limitations

X Window System security

The biggest limitation is that the X Window System provides no security. The security of a powerbox relies on the powerbox having a secure path to the user, so that the user can enter a filename into the powerbox but the application can't. However, under X, this isn't true: one X client can spoof keypresses by sending keypress events to another client.

So the present system only raises the bar to a successful attack, rather than ruling an attack out.

UI limitations

Currently, the powerbox is the only way you can dynamically add files to the namespace of an application that has been launched using pola-run. It would be useful to have a command line tool (similar to gnuclient, as used with Emacs) for granting an application access rights to further files.

Reviewing and revoking

There is currently no way to review what authority has been granted to applications using the powerbox, and no way to revoke this authority.

Nested use of pola-run

Nested use of pola-run with the --powerbox option is not very useful at present: the nested instance of pola-run will provide its own powerbox manager. At the moment, the powerbox_req_filename object is only able to attach a file into an existing file namespace and return a filename. It needs to be extended so that it can return a reference to a file or slot object. The nested instance of pola-run can then attach this reference into the namespace it created.

Secure handling of symlinks

As it stands, using Gtk's file chooser, the powerbox does not provide a secure UI for handling Unix symlinks. The user is not shown symlink destinations at all, yet the powerbox manager will follow symlinks, even though the symlink destination could have been written to the filesystem by an untrusted application.

A possible solution is to change the file chooser to display symlink information, and perhaps require the user to double click on a symlink to follow it.

Backup and temporary files

Backup files are not handled. Arguably, when the user chooses FILE, the powerbox should also grant access to FILE~ and #FILE# (the latter is used by Emacs' auto-save feature).

Persistence

There is no persistence. An application's access rights are not saved across sessions.

Integrations: powerbox for Gtk applications

The powerbox/Gtk integration reimplements Gtk's GtkFileChooserDialog interface so that it opens a file powerbox for choosing files or directories. This means that existing, unmodified Gtk applications can use the powerbox.

GtkFileChooserDialog is replaced using an LD_PRELOADed shared object (powerbox-for-gtk.so), which replaces the gtk_file_chooser_dialog_*() functions. This shared object will work across different versions of Gtk. (Perhaps in the future, it could be compiled into Gtk.)

The powerbox/Gtk integration does not change the older GtkFileSelection interface, which is deprecated and exposes too many internal details to change.

How it works

The replacement GtkFileChooserDialog class inherits from GtkDialog, and hence from GtkWindow etc. However, it must prevent GtkWindow from ever opening a window on the screen; this is done by the powerbox manager instead. GtkFileChooserDialog achieves this by overriding the GtkWidget "map" method with code that does not pass the call on to GtkWindow. Instead, the "map" method invokes the powerbox API.

Limitations

Earlier version of the GtkFileChooserDialog replacement

My first attempt at a replacement GtkFileChooserDialog class did not inherit from the GtkDialog class, on the grounds that it did not need to open a GtkDialog window itself. It inherited from GtkObject and nothing else.

This caused some problems, because applications expect GtkFileChooserDialog to inherit from GtkDialog (and so, indirectly, from GtkWindow, GtkWidget, etc.) as documented. This did not cause applications to crash: the Gtk API functions just print a warning and return if passed objects that don't belong to the expected class.

The old version is still included, as gtk-powerbox-noninherit.c.

Integrations: powerbox for Emacs/XEmacs

The powerbox.el Emacs Lisp module changes Emacs to use a powerbox. It replaces Emacs' read-file-name function, which usually prompts for a filename using the minibuffer. This function is used when you type C-x C-f, or when you choose "Open" from the "File" menu. The replacement read-file-name function opens a "File Open" powerbox instead.

To run XEmacs to use the powerbox, use:

pola-run --prog /usr/bin/xemacs -B -f /etc --cwd / \
  --powerbox --pet-name "XEmacs" --x11 \
  -a=-l -a=/usr/share/emacs/site-lisp/plash/powerbox.el

GNU Emacs 21 does not work under Plash. The CVS version (to be released as GNU Emacs 22) has reportedly been fixed.

The powerbox API

The powerbox manager is compiled into the pola-run program launcher. When the --powerbox option is used, pola-run will pass the application being launched an object under the name powerbox_req_filename.

An application can invoke the object powerbox_req_filename to request a file from the user. In response, the powerbox manager will open a file chooser. If the user selects a filename, the powerbox manager attaches the file (or file slot) into the application's file namespace, and returns the filename to the application.

When the application invokes powerbox_req_filename, it can pass some arguments, such as:

There is a simpler helper program called powerbox-req which invokes the powerbox_req_filename capability. This is a command line program which is used by the Emacs integration.

The --pet-name argument provides a name for the powerbox manager to put in the title bar of the powerbox, so the user can tell which application the request comes from.

The powerbox manager uses Gtk's original GtkFileChooserDialog to provide a file chooser.