restricting DataEngine access
Aaron J. Seigo
aseigo at kde.org
Wed Jul 13 14:37:28 CEST 2011
hi all...
this is a "RFC" type email as i start meandering my way towards selective
locking down of access of DataEngines to scripted Plasmoids (JS and QML at
least anyways). there is very little that can be done with C++ plasmoids since
it is native code running which means all bets are off anyways. Ruby and
Python are little better with their broad access to system libraries via
bindings, so this primarily concerns our desire to sandbox what can be: JS and
QML.
so .. the aim is to make it so that given a random assortment of DataEngines,
Services and Plasmoids, we can control what individual Plasmoids have access
to. initially i'm going to concentrate on a per-engine basis and think later
(if at all) about per-source access control. (Services are not shared, so that
isn't an issue here)
== Determining Need ==
there are a few possibilities on how to determine whether or not a Plasmoid
needs a given DataEngine:
a) advertise which engines it uses in its .desktop file
Pros:
* we can determine prior to loading or even installing whether or not we
can service this Plasmoid
* it would make setting up a whitelist based system very easy
* we could bug the user _once_ about which services the Plasmoid will wish
to access prior to running it
* this is the system we use for Extensions
Cons:
* it means by-hand bookkeeping on the part of the Plasmoid developer ->
all engines/services requested would have to show up in the .desktop file
b) intercept all calls to dataEngine() / service() and figure out if the
Plasmoid really, indeed, should have access to them
Pros:
* validation code needs to be in the getters anyways, so less code to
write (ok, this is a weak "pro" :)
* largely transparent to the Plasmoid writer
Cons:
* would mean interupting execution of the app, and possibly interupting
the user, everytime a new DataEngine/Service gets used
* can't know prior to install and run what the Plasmoid wants to do
in both cases, a whitelist recording system needs to be developed, though that
is a pretty simple key/value store that KConfig should be able to handle just
fine.
i'm leaning towards solution (a).
== Defining Access Conditions ==
now the big question: what DataEngines/Services can be accessed under what
terms? here are the scenarios i can currently foresee as being useful:
some DataEngines are completely harmless and should require no verification at
all. it would suck to show every access to every DataEngine for every Plasmoid
as that just seems .. well .. a bit over the top.
some may be security sensitive and completely off-limits to any scripted
Plasmoid, left only to the installed system itself.
some will need to have user agreement or some other system configuration to
allow access. this category might include things like access to
powermanagement, the phone dialer, etc.
still others may require that the plasmoid has been successfully signed by a
certain GPG key before using.
i've toyed with the idea of approving categories of things like "can access
the network" and then a DataEngine/Service advertising that they require
network access. but as i chased that idea through, it seemed not only overly
broad but probably not as useful as "access my Twitter account". what
DataEngines could do, however, is advertise that they use, e.g., network
services and that can be used as an aid in helping one decide whether or not
to allow access to that engine:
"The <foo> app is requesting access to the following services:
Network access:
* Microblogging
Hardware awareness:
* Network status"
this data should be stored in the DataEngine/Service's .desktop file. these
keys might include:
X-Plasma-Access=[OnApproval|Open|GPG]
OnApproval would be the default (for safety reasons) and then rely on the
Comment as well as optional categories being present in the .desktop file.
Open would mean "anyone can use this, i'm safe!"
GPG would mean "requires a GPG key"
X-Plasma-AccessCategory=[Network|Hardware|...] this list needs further
definitions
X-Plasma-AccessKeys=[list of approved gpg keys]
== Storing Access Priveleges ==
this should be kept KISS until we need something more: a single INI filethat
looks like something like this:
[org.kde.superPlasmoid]
DataEnginesApproved=org.kde.foo,..,..
DataEnginesDenied=org.kde.blarg,..
ServicesApproved=..,..
ServicesDenied=..,..
== Preventing Plasmoids From Breaking The System ==
where to store access priveleges is a more interesting question than it would
appear at first blush. a plasmoid that has the LocalIO extension could
currently access this file and possibly even write to it if it is in the
user's dir. assuming the approval app runs non-priveleged and as the same user
then we have an issue.
one possibility is to off-limits the location that this file is stored. this
would be easy enough to do in the bindings, though QML might give us an issue
here as QML, it turns out, has a gigantic security hole that allows any file
to be accessed anywhere on the system. ah well.. something to address in QML2
perhaps. *looks at Qt devs*
there's also the issue, however, of .desktop file cascade. if a DataEngine's
.desktop file is stored in /usr and the user adds one with the same name and
path in `kde4-config --localprefix` then they can override what happens there.
not great.
one option would be to _only_ parse the system installed .desktop file. this
would potentially suck for kiosk systems with multiple layers of directories,
however. this could possibly be worked around by either looking for it
manually and picking the "nearest" not-in-the-homedir path (which leaves open
the possibility for an environment variable to be tweaked to add a path in a
writable dir that isn't the homedir; which could be closed by requiring the
path not be writable by the user; which would break many dev installs .. ah
well :) ... or we could just not care and say "there is one set of security
definitions, system-wide, for any given DataEngine .. and they live in the
install dir". this would still allow per-user definitions, but it would be
largely in the hands of the user (or the sys admin using kiosk).
this is fine for DataEngines and Services installed system-wide, but if we
have DataEngines and Services installed in the user's dir, say via network
download, we're right back to square one.
so i'm thinking that we just don't allow random file access to anything in
$KDEHOME at all, not even via LocalIO. that closes off the entire vector for
routing around the system and leaves the implementation code simple.
thoughts?
--
Aaron J. Seigo
humru othro a kohnu se
GPG Fingerprint: 8B8B 2209 0C6F 7C47 B1EA EE75 D6B7 2EB1 A7F1 DB43
KDE core developer sponsored by Qt Development Frameworks
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
Url : http://mail.kde.org/pipermail/plasma-devel/attachments/20110713/41a985b1/attachment.sig
More information about the Plasma-devel
mailing list