After talks with the USSO desktop team, Kees Cook, Ubuntu developer Didier Roche, and Kubuntu developer Johnathan Riddell, I'm back to update this thread. I know a lot more about the GNOME keyring, I've made some tweaks, and I think I can present my design in a more convincing way.
Restatement of the status quo ============================= On the server side, Launchpad credentials are associated with a consumer key (the name of the application that requested the credential). Each credential has an associated access level which limits what the application can do under your name. On the client side, launchpadlib's login_with() method caches credentials unencrypted in your ~/.launchpadlib/[host]/credentials directory. The get_token_and_login() method can be used to get a token without writing it to /credentials, but most applications use login_with(), and most of the ones I've seen use get_token_and_login() also write the token to disk somewhere. This setup works great when integrating other websites into Launchpad, because you don't have any control over (eg.) Facebook, and because third-party websites don't all share a data store. Although third-party websites can use launchpadlib, they can't use login_with(), which is designed for desktop use. This setup doesn't make much sense when integrating desktop applications running in a GNOME environment. You have control over the environment. Any application running as you can easily access your credentials and act as the union of all your OAuth tokens. Not only that, login_with() stores the tokens unencrypted on disk. Unless you've enabled home directory encryption, if your hard drive is stolen, all of your credentials will be compromised. Restatement of my design ======================== Now I'll restate my design as a two-step process. I hope I can make at least the first step sound uncontroversial. Step 1: Store credentials in the GNOME keyring ---------------------------------------------- The first improvement is to change login_with() to start storing Launchpad credentials in the GNOME keyring (if available), with disk storage as a fallback. This will prevent the stolen-hard-drive attack. With Launchpad credentials in the GNOME keyring, a suitably paranoid end-user can also take countermeasures against certain other attacks by moving their Launchpad credentials out of the "login" keyring (where they will be stored by default) and into a keyring for which they've set an idle timeout. You can do this from the "Passwords and Encryption Keys" desktop accessory. Idle timeout sidebar ~~~~~~~~~~~~~~~~~~~ Setting an idle timeout means that if you unlock a keyring and then walk away from your computer for N seconds, the keyring will automatically lock back up. The next time any application wants access to one of the keys in that keyring, you'll have to type your unlock phrase again. This stops an attack where someone stops by your running computer when you're not around, and snoops on your passwords. It also offers a little protection against malware that tries to dump an unlocked keyring: if you suddenly get a password dialogue out of nowhere, you'd do well to be suspicious. It doesn't protect against a keylogger. If you set the idle timeout to 0 seconds, you will have to type your unlock password *every* time an application wants access to *any* key in that keyring. If you're careful, this will give you complete protection against malware that tries to dump a keyring. It still won't protect against a keylogger, though. Step 2: Authorize the desktop, not the application -------------------------------------------------- Setting an idle timeout offers you some additional options for security. But even if you set your idle timeout to zero, you have no way of ensuring that the 'apport' credential is only used by the apport application.[Footnote 1] Any authorized application can access your entire keyring. The second improvement is to acknowledge this, by relaxing the requirement that each desktop app have its own individually authorized OAuth token, while maintaining that requirement for integrated websites. This should have the side effect of solving the problem I'm actually trying to solve--getting third-party developers to accept the token authorization process instead of trying to hack around it. The desktop authorization will be done through a one-time browser open, as described in my earlier email. Desktop authorization can be done permanently or on a time-limited basis, and revoked at any time from the Launchpad website. Token expiration or revocation will cause another browser open. (About) as good as it gets ========================== Why am I basing this design around a system (the GNOME keyring) that has obvious shortcomings? Because what we're doing now is worse, and because there's nothing lying around that's better than the GNOME keyring. It's not hard to come up with a better system than the one I propose. But my proposal has five desirable properties: a) Brings our security *up* to the standards set by GNOME and the Ubuntu Single Sign-On project. b) Doesn't assume desktop improvements that might or might not ever happen (see below). c) Addresses the problem I'm really trying to solve: that third-party developers find our *existing* per-app authorization system too onerous. d) Doesn't require any desktop development up front, although desktop developers can improve its usability later (see below). e) Can be deprecated in favor of a real per-app authorization system if the desktop improvements ever happen--assuming we can come up with a design that third-party developers will put up with. Most of the alternate designs I've seen/invented come up short in b or c, which are deal-breakers IMO; as well as in d, which is not. I can argue specific cases off-list if anyone is interested. When will the GNOME keyring improve? ==================================== We'd look pretty silly if we went to desktop-wide integration and then the next release of GNOME featured per-application per-key ACLs. It would still be a lot of work to _implement_ a per-application authorization system that wouldn't drive our third-party developers to cheap hacks, but it would be theoretically possible. But, it doesn't look likely to happen anytime soon. This is from http://live.gnome.org/GnomeKeyring/SecurityPhilosophy: --- While it'd be nice for gnome-keyring to someday be hardened against active attacks originating from the user's session, the reality is that the free software "desktop" today just isn't architected with those things in mind. We need completion and integration things like the following. Kudos to the great folks working on parts of this stuff: * Trusted X (for prompting) * Pervasive use of security contexts for different apps (SELinux, AppArmor) * Application signing (for ACLs) --- Those are some heavy prerequisites. According to Didier Roche, GNOME 2.28 included a very simple step towards protecting against active attacks: a dialog that pops up the first time some application wants access to a keyring, letting you grant or deny access. That's not exactly the feature we want, but it's a start. In order to limit access by application, we need to correctly identify which application wants access. But we won't even get this feature. The feature was *removed* after it became clear that, without application signing, it's trivial to spoof the name of an already-allowed application. At the most recent GUADEC, Didier and some other developers discussed alternate ways of doing this feature, but didn't come up with anything good. I took a look at the KDE Wallet, the closest competitor to the GNOME keyring, to see if there's something the GNOME developers were missing. The stories are pretty much the same. Once an application has access to your wallet, it has access to that _entire_ wallet. ("Wallet" here means "keyring"--you can have more than one.) You can ban bad applications from your wallets, and you can put a watch on your wallets so that you get notified any time a new application tries to get access. But there's no verification that an application is what it claims to be. According to Jonathan Riddell, "the application name is taken from the KAboutData", which is easy to spoof. This feature is basically the one added to GNOME and then removed. Desktop-based improvements we could do now ========================================== Benji and I plan to do the work necessary to implement steps 1 and 2 of this design. There are some additional improvements possible on top of that, to improve the experience on the desktop. Any of these may require additional server-side design and implementation work, which I'm happy to do, given a partner who's serious about the desktop side. 3. Martin's suggestion. If a user's Launchpad account is tied into their USSO account, it's theoretically possible to exchange USSO credentials for Launchpad credentials without opening a web browser. Since all users now (and most users in the future) tie their Launchpad account into their USSO account, this would be a big usability win, getting rid of browser opens entirely for many users. 4. Kees is interested in seeing a new gnome-keyring backend for managing Launchpad tokens. IMO this backend can't do all that much, given that it's still using gnome-keyring. But it could provide some benefits, like the ability to limit the client-side storage of a token to the current session. Conclusion ========== There are a lot of good ideas in this thread, but many of them require that the GNOME keyring know which application is asking for a key, the way Launchpad knows which user is making a request. Unfortunately, it doesn't know, and it won't know for the forseeable future. Without this ability, there's not much point in keeping more than one set of Launchpad credentials on the desktop. The best thing to do from a user-experience standpoint is to authorize the desktop itself, rather than individual applications. Footnote 1 ========== (from "Step 2: Authorize the desktop, not the application") You can approximate this behavior by creating more keyrings. For instance, you create a separate zero-timeout keyring for each Launchpad access level: "read public", "read private", etc. Keep your Launchpad credentials sorted by access level. Give each keyring a different password. Be sure to only unlock the appropriate keyring for the application you're running. This won't stop one app from using another app's credentials, but it will stop one app from claiming a higher access level than you gave it. If you absolutely want to prevent one app from using another app's credentials, you can create a separate keyring for each application, each keyring named after the application. These schemes are far too tedious and complicated for anyone to put up with, and they won't stop a simple userspace keylogger. They also won't stop malware from waiting around and making fake requests for the tokens of the applications you're running, or opening fake windows that ask for the unlock key. Leonard
signature.asc
Description: This is a digitally signed message part
_______________________________________________ Mailing list: https://launchpad.net/~launchpad-dev Post to : launchpad-dev@lists.launchpad.net Unsubscribe : https://launchpad.net/~launchpad-dev More help : https://help.launchpad.net/ListHelp