Proxying Wayland for security
Carsten Haitzler
raster at rasterman.com
Wed Jul 28 09:34:51 UTC 2021
On Wed, 28 Jul 2021 09:08:03 +0000 Alyssa Ross <hi at alyssa.is> said:
> Hi Carsten, thanks for the detailed reply.
>
> Carsten Haitzler <raster at rasterman.com> writes:
>
> > On Tue, 27 Jul 2021 19:29:45 +0000 Alyssa Ross <hi at alyssa.is> said:
> >
> >> Hi! I'm Alyssa and I'm working on Spectrum[1], which is a project
> >> aiming to create a compartmentalized desktop Linux system, with high
> >> levels of isolation between applications.
> >>
> >> One big issue for us is protecting the system against potentially
> >> malicious Wayland clients. It's important that a compartmentalized
> >> application can't read from the clipboard or take a screenshot of the
> >> whole desktop without user consent. (The latter is possible in
> >> wlroots compositors with wlr-screencopy.)
> >>
> >> So an idea I had was to was to write a proxy program that would sit
> >> in front of the compositor, and receive connections from clients. If
> >> a client sent a wl_data_offer::receive, for example, the proxy could
> >> ask for user confirmation before forwarding that to the compositor.
> >
> > The above is intended to be the job of the compositor. I would expect
> > compositors to implement this. The only decisions to be made is which
> > clients do they "lock down" and ask questions for (eg like allow copy
> > yes/no) and which they do not. The compositor has a socket to the client
> > and can use that to figure out all about the client that it wants to.
> >
> >> I could just implement this stuff in a compositor, but doing it with a
> >> proxy would mean that a known subset of the protocol could be used
> >> with any compositor, with appropriate access controls. It would also
> >> be a reusable component that could be customised to have different
> >> access control policy depending on the needs of a distributor or user.
> >
> > You could - but then the compositor thinks your proxy is the client, not the
> > actual client. This leads to lots of un-fun like if a compositor uses the
> > client socket to query what PID and then what executable etc. that is and
> > does things like shows icons based on the executable found (what desktop
> > file that maps to) etc. ... If the compositor implements some kind of load
> > balancing of rendering/updates based on PID. e.g. it may renice the PID of
> > the client based on if its on a visible virtual desktop or not. I can go
> > on...
>
> Hmm, yes, that would be a shame. In general, I saw the proxy as a way
> to move some policy decisions out of the compositor. It would still
> technically be possible to do those sorts of things by having the
> compositor asking the proxy to do it, but that would require buy-in from
> compositors.
>
> It's frustrating that there's no way to implement this sort of thing,
> which doesn't feel particularly compositor-dependent, without
> implementing it seperately for every compositor my users might want to
> use. Especially when it's likely not upstreamable to at least some of
> them -- e.g. I doubt Sway, which AIUI aims to avoid adding features
> beyond what's needed for i3 compatibility, would be interested in it.
> But I understand that that ship has probably sailed, and there's not
> really anything I can do about it without breaking the expectations of
> other things in the ecosystem.
>
> >> Which brings me to the reason I'm bringing this all up on
> >> wayland-devel. I'd be grateful for any input about this idea,
> >> especially:
> >>
> >> * Is this a sensible idea? Is there something I haven't considered
> >> which would make this unworkable, and force me to do a
> >> compositor-specific implementation instead?
> >
> > See above. I can come up with more things that will be problematic. Sure. it
> > *CAN* be done. In some cases like a "vnc proxy" whose job it is to display
> > remote clients it deals with over vnc to a local wayland compositor... it's
> > pretty much necessary. The above socket -> pid -> exe etc. isn't going to be
> > valid/useful and you can't really do that due to the real client being "off
> > machine". But for the vast vast majority of cases, they will be real local
> > clients with real PIDs etc.
> >
> >> * Is this something that would be likely to be generally useful,
> >> outside of our project? Would it make sense as something to
> >> collaborate on / have as a freedesktop.org project?
> >
> > What I think would be of value is a standardized method to decide which
> > wayland clients should be locked down and which should not be. This is
> > currently "undecided". Something a compositor can easily look up given the
> > client socket and then decide which protocol requests it will handle in
> > which way.
>
> Do I understand correctly that you're saying you'd like there to be some
> sort of oracle, outside of the compositor, that the compositor could ask
> what restrictions should be applied to a client?
Yes. or more specifically I'd like it to be as simple and basic as possible.
E.g. a file in /etc/wayland/security/securityinfo.cfg - imagine this is a .ini
file format much like .desktop files so we can re-use parsers that most things
have to eventually implement (how do you display sensible application info e.g.
while alt-tab switching and icons for apps without doing some kind of .desktop
file handling at some point? You can choose to never do this but then you may
then not bother with more security either).
Imagine there are 1 or more files that perhaps describe black or white lists in
a fairly simple way that allow the compositor to limit functions.
Personally, if I was going to lock security down 9have not gotten there yet -
have other things to do before then). I'd be happy to support something like
the above, but before that I'd do some of the following:
1 query UID/GID of the remote client. If it's not UID 0 and not UID of user
running the compositor, auto-lock-down anything like copy & paste (eg behind
such "are you sure" dialogs). We already do not support the screenshot protocol
as it can be abused .. and the compositor has it's own ability to do
screenshots and save them out to disk anyway. If we did support it, then it'd
also do a "are you sure" thing too if UID/GID are not approved. I'd consider
adding extensions to query SMACK label too if that was more widely used (or
accept patches).
2. I'd also then after this add a custom "for my compositor only" white and
black list of executable paths (probably a simple text file with a list of file
globs per line like:
deny /usr/bin/firefox
deny /usr/bin/zoom
allow /bin/screenshoot-tool
allow /usr/bin/*
allow /usr/local/bin/*
deny /*
So simple walk the list from top to bottom finding first rule that matches.
this is simple allow/deny but could make these custom rules like:
rule allow=cnp,screenshot
rule deny=
rule allow-cnp=cnp
Then use allow-cnp to allow clients to just do cnp. Of course this would just
be me - but it's simple to maintain and reason about and flexible enough to do
what is needed. Would have this file per user for sure (e.g.
~/.config/mycompositor/security/rules.cfg). The user local file parsed first for
allow/deny rules then parse the system file for a master list for the whole
system). Yes - it is coarse and only allows approval based on fill file paths.
Yes - a binary could be written to /tmp/ or $HOME/ then deleted or renamed
(vector of attack) which is why I'd have the last rule be a deny /*
(everything) unless explicitly allowed and only explicitly allow known good
directories of tools which have other system controls to limit abuse (writing
of trojans there -= eg /usr/bin will be limited to root to write to).
I am sure you spend far more time on all of this than I do and are more aware
of the problem space, so I think you are much better positioned to create
standards that are both simple to implement and powerful and secure. If all
compositors agreed on the same ruleset to load and even used the same simple
small security library to do this (e.g. you make a small lib that can be given
a socket fd and then return a list of allowed actions - eg cnp,screenshot, ...)
this would go a long way to perhaps having a standard everyone agrees on and
is minimal effort to implement.
As per your example - if some compositors choose not to do this, then they
would be less "secure" and users should be aware of this. That's up to them and
the compositor developers to deal with.
You get where I'm coming from. :)
--
------------- Codito, ergo sum - "I code, therefore I am" --------------
Carsten Haitzler - raster at rasterman.com
More information about the wayland-devel
mailing list