Evince and security

Honestly, we need to take a hard look at what to do with Evince. I’m not sure. What we should not do is port it to GTK 4 and otherwise leave its current architecture intact. Using poppler in the main process is not safe. We need to push that out to a subprocess that is sandboxed by bwrap (when not running under flatpak) or flatpak-spawn (subsandbox for when running under flatpak). And that sounds hard to do.

Currently our safest way to view PDFs is to use Epiphany, where the sandbox comes for free via WebKitGTK.


P.S. This all applies exactly the same to image viewers and media players. Anything using GStreamer, GtkVideo, GtkPicture, etc. etc.

I think that is a somewhat maximalist view of security that may not be too helpful, and I think it is offtopic in this discussion.

Is it really off topic, though? My point is that porting evince to GTK 4 now without further thought to how it ought to work in the long run may not be a good use of time. I’m really not sure. Maybe it’s reasonable to both port to GTK 4 and separately figure out how to sandbox the use of poppler, but maybe it’s easier to start from scratch with a WebKitWebView and PDF.js. I don’t know, but if someone wants to port evince to GTK 4, that would be the top thing I would want to think through before starting.

It’s not a maximalist view of security. Our core apps don’t have to be as secure as Fort Knox, but they should be more or less generally safe to use. We have a PDF reader: it ought to be safe to open a PDF without having to trust that whoever created that PDF will not try to gain control of your laptop. Currently that is not true because poppler is written in an unsafe language. That doesn’t mean we shouldn’t use poppler at all, but we should expect it to be hacked and design so that the damage is contained when it happens. Other core applications that I worry about: Image Viewer, Videos, Music, and Photos. Porting to GTK 4 is a major development effort, and an ideal time to think about how to make the applications safer.

1 Like

Put it in a flatpak?

My main complaint is that this appears to be just stop energy: If we don’t port evince to GTK4, we will still have an unsafe pdf viewer, in addition to an outdated-looking one.


Assuming there are no major sandbox holes like --filesystem=home, then that is a great solution. Sadly, distros (including Fedora) are still shipping our apps without flatpak.


I agree with Matthias here, though I see your concern Michael.
Could it maybe be tackled in a different initiative?
It wouldn’t be very productive to block any ports to GTK4 over it.

@hergertme worked on textrange and pieceplustree already which could hypothetically be used for something like Abiword or GOffice-next, @hub any thoughts?

Thats were I would expect standardisation around using subprocesses for filters and bubble wrapping all the things.

And even if that’s not desired, I still think that any initiative regarding subprocesses and evince should be separate to a GTK4 port.

No, AbiWord isn’t a solution to any of your problems.

I started to try to port AbiWord to Gtk4 back in the 3.96 days - it somewhat did built and started to run. And now I need to rewrite most of the event management, menu, etc.

The PieceTable in AbiWord. isn’t the problem. Not sure why this is being brought up.

And goffice is also a blocker for AbiWord it needs to be ported first or strip it out of AbiWord.

Oh, sorry. Wasn’t implying that it was a problem, was just mulling over the idea of a shared piecetable for applications which target a potential goffice-next, like e.g dia etc I believe Libreoffice and Calligra take that route.

A lot of bits and pieces in Builder use a private GDBusConnection over a pipe to an inferior process (which can easily be wrapped with bwrap or flatpak-spawn). That allows using D-Bus interfaces and gdbus-codegen to create the RPCs in a fairly simple manner. Most of the content can be passed across using FD passing (even inside/outside flatpak containers).

This can work very well for decoding pages like evince, loading images into framebuffers, etc.

I would also suggest we wrap poppler this way.

Evince seems to currently be using FileChooserNative, is there some reason this cannot work with the file portal to open PDFs? It seems that should be doable. (Sorry if this is offtopic, if there is an issue for this we can move discussion there)

It’s less about how evince finds the file to open and more about how it processes that file using libpoppler. In particular, PDF is a huge attack surface (Adobe Acrobat even has an ecmascript engine) and so keeping it isolated is definitely one of the biggest benefits browsers got when moving to a JavaScript PDF viewer.

Sure, but I mean specifically for the --filesystem=home permission on the flatpak. I’d expect even with isolating poppler, one would still want to also get rid of that permission if possible. The difference there would be for the user that sees something like “this app needs access to your entire home directory” in GNOME Software, etc.

CC @gpoo since this got split into a separate thread.

Yeah, definitely. We should aim for both.

Also even if its a flatpak, currently its safer to use webkit on the host with its own bwrap setup as the media process there only have access to the resources needed. When epiphany runs with flatpak on the other hand the webkit sandboxing is disabled and the media decoders for example have access to the network. Same goes for Totem.

Maybe that could be solved once we are able to sub-namespace bwrap? Haven’t looked at it much.

This is not true. flatpak-spawn is called with --no-network to ensure the web process has no network access even though the parent process does. flatpak-spawn is pretty nice.

Of course Totem has no sandbox other than the primary flatpak sandbox. This seems hard to fix.

totem is actually the only GNOME app we know for sure has been successfully exploited in the wild. (That article doesn’t say it was totem, but we know it was totem, presumably via some unknown GStreamer vulnerability. Facebook never disclosed the vulnerability to us.) In this case, the only goal was to reveal the victim’s IP address, so the main flatpak sandbox would actually not have helped much at all: a subsandbox that restricted network would have been required.

But I don’t think we need to let perfect be the enemy of the good here. Even a sandbox that allows network would be a lot better than no sandbox at all. An attack where one’s only goal is to reveal the victim’s IP or exfiltrate the limited number of files that totem has access to (presumably ~/Videos?) is a weird edge case. So if we only care about flatpaks, then I think the status quo is OK, even though it could be better. But many users still use totem via RPM (e.g. me, I am using normal Fedora Workstation), and that is very unsafe.

1 Like

Personally also in favor of splitting up the work into 2 separate initiatives. Do we have a clue on how much effort both of them would be?

Ideally, we can even split these up into smaller pieces so that multiple people work on it simultaneously if needed. Also, some work might need to be shared anyway, which would be a good starting point

The following may be obvious to everyone else here, but it was not obvious to me until I recently looked into whether Endless OS could simply remove evince from the base OS and instead preinstall the Flatpak from Flathub, motivated in part by sandboxing…

GTK’s print dialog’s preview functionality is implemented by invoking Evince, specifically:

#define PRINT_PREVIEW_COMMAND "evince --unlink-tempfile --preview --print-settings %s %f"

(where %f is the PDF filename and %s is the print settings filename).

evince in turn exec’s evince-previewer which provides the preview window.

The Evince Flatpak on Flathub does include the previewer executable. I briefly tested running it by hand, but when I hit Print it would try and fail to invoke lpr and so printing would fail.

So: sandboxing PDF rendering is not as simple as “put Evince in a Flatpak”, and replacing Evince also involves replacing the print-preview mechanism. All solvable but would involve deep thought and programming!

I was thinking more about this in terms of poppler. To me this seems to mean turning every poppler API call into a GVariant serializable method that can get pushed over a socket into a sandbox. Then it would render into a memfd and send that back. Not sure if there is any prior art for this…