RE: Sandboxing thumbnailers/file preview code


Hey Steve,

I'm curious whether the file preview
back-end could reuse thumbnailers and if custom file preview functions
could be entirely replaced with standalone thumbnailer executables.

They cannot. The thumbnailers don't use any UI widgets, and provide none
of the necessary niceties to be usable as file previews. What you might
think as usable when previewing a PDF will completely fall apart when
previewing a video. There's also no "thumbnailer" for audio :)

Sorry I wasn't very explicit. I feel that an arbitrary application wanting to
setup a preview widget does so because it wants to handle a specific mime-type,
in which case it could do IPC to a service that is responsible for generating
previews (or thumbnails :) maybe thumbnailer is not the right name for the
service I have in mind). The Content Selection / File Chooser Dialog would then
automatically display a preview when available, without the app ever knowing
about the file or the preview's contents.

It might be also that the arbitrary app wants to create a specific type of preview
of the currently selected file, rather than the system's default. There are three
approaches to that:

1) Assuming that there is a background preview service and that the app can propose
its own previewer for the mime types it targets, then the app can specifically ask
for the preview widget to use its thumbnailer (and if AppFoo is calling the dialog
then by default the background preview service could look for AppFooPreviewer/Thumbnailer).

This means that the preview code is written as a simple separate binary/script.

2) The code is provided directly within AppFoo, as a callback. This means that
the callback needs to be given access to the files to preview, needs to be prevented
from talking to the rest of the application at all and needs to be sandboxed from
*within* the binary. This is, obviously, much much harder to achieve. There are
some research tools that do a good job at compartmentalisation but I'm not sure
how well they handle compartments that actively want to leak information. This
might also break in more unexpected ways since it's less clear to guenuine developers
that the actual app and the preview code should be separate entities.

3) The last solution, which I do not recommend, is to give the app access to any
file ever selected in a content selection dialog/file chooser dialog and to live
with the security implications -- essentially that breaks the sandboxing model.

As a security guy I don't reason in terms of how much code can be "secured" but
rather in terms of where I as an attacker would place my malicious code. If I can
get the user to install an app that will be forcibly sandboxed by their OS, but
I can still run some preview code on some files with internet access (or anything
else that involves the desktop environment running complicated code with high
privileges), then I'm still likely to make profit. So as painful as it is, if we
are serious about creating an OS where untrusted apps can be sandboxed, then all
aspects of how an app can hurt the user need to be revised. That's why I don't
advise solution #3 :)

In an OS with sandboxed apps, one would really want to also sandbox
thumbnailers: they run with the desktop environment's privileges and
could potentially steal every file they're given (or more). I've had a
quick glimpse at the GNOME Thumbnailer and it seems very easy to
sandbox it. Instead of directly launching the untrusted thumbnailer,
you'd give its path as a parameter to a generic Sandboxed Worker.

There's already some code in Fedora to use SELinux to provide some
minimal sandboxing of thumbnailers, not allowing some of them to write
anywhere but in the thumbnail directory for example.

SELinux looks great at first glimpse, but the problem is that it comes with no
default policy for untrusted third-party thumbnailers. If I install a file named
/usr/bin/AppFooPreview, its default label probably is unconfined_u:object_r:exec_t?

I don't think you can force a domain name when executing an unlabelled binary,
though I haven't touched SELinux in years. I assume that only systems running in
strict mode would enforce a policy (which might in fact be too unpermissive).

Also, if the app developer did provide a SELinux policy, this policy would be
written by her/him and not by the good people (DEs and distributors). How do you
tell whether that 3rd-party code is malicious? Sandboxing means that the default
policy is just enough for a basic/no-fancy-things previewer. Of course one could
try and extend the sandbox worker to provide extra services. One could even setup
a notion of worker profile that would describe in flexible ways what can be
allowed - except that those profiles would need to be signed by distributors to
avoid attacks.

The worker could be a well-known D-Bus name or user systemd service
that sets up a Docker/LXC container, makes a read-only bind of the
input file's path and a write-only bind to the output file's path. It
could have a switch just like systemd services to remove networking,
and possibly start with very a limited system interface (using
seccomp2, with options to allow extra syscalls depending on the
worker's task).

You're getting deep into the technical implementation here, and I'm not
sure that should be done before defining the necessary interface. FWIW,
you don't need bind mounts to do this, you'd pass a read-only fd through
D-Bus, and avoid all kind of side-effects.

You'd probably do a bind mount to provide the session's D-Bus socket to the
sandbox, anyway :) Though getting fd's through rather than files allows for
capability restriction on e.g. Capsicum-enabled systems.

One other issue that might arise is that the D-Bus daemon might not handle well
the fact that a sandboxed binary has a different network and PID namespaces. This
is something that I need to look into for other bits anyway.

But that would mean that thumbnailers that use network information to
provide a thumbnail wouldn't work (downloading game or video covers for
example), those that use local databases wouldn't work either (like
audio file covers cached with libmediaart not being accessible to the
thumbnailer), etc.

Third-party untrusted thumbnailers that use the network cannot really be considered
sandboxed. Of course networking or read-write access to other resources can be
enabled for any thumbnailer, but that should be in the hands of distributors
rather than arbitrary app developers -- I'd rather know Arch Linux and GNOME only
let thumbnailers written by people *they* trust read my files. Read-only access
to resources is always fine though.

I think it's important to list all the possible types of thumbnailers,
which accesses they need, and then discuss the possible implementations.


Will put that on the todo-list! Is there a GNOME-provided list in any repository
already? I'm not running GNOME on this machine and not in the office for a while...

Steve Dodier-Lazaro
PhD student in Information Security
University College London
Dept. of Computer Science
Malet Place Engineering, 6.07
Gower Street, London WC1E 6BT
OpenPGP : 1B6B1670

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]