Hacker News new | ask | show | jobs
by zaroth 4633 days ago
The workaround is to allow access to the keychain data while the phone is locked? I assume the Loom keychain data (including the users password) is only accessible to the Loom app, just now it's accessible to the app even if the phone is locked. Doesn't give me a warm and fuzzy feeling.

Why not store username and a random token in the keychain instead of the actual password? You create the token on a valid login and keep it on the server and in the keychain. Basically it's a session cookie.

3 comments

From Apple docs:

  kSecAttrAccessibleAlways
  The data in the keychain item can always be accessed regardless of whether
  the device is locked. This is not recommended for application use. Items
  with this attribute migrate to a new device when using encrypted backups.
If the data is always accessible regardless of if the device has ever been unlocked, then by definition it must not be encrypted, or at least, it must not be encrypted with any key actually derived from the user's password!

Consider, for example, iCloud backups. The "kSecAttrAccessibleAlways" data may be encrypted, but its with a key that Apple knows. So using kSecAttrAccessibleAlways sounds a lot like how Google backups store your WiFi password.

As 'itsboncheck' mentions down-thread, a better choice (still a serious compromise) may be...

  kSecAttrAccessibleAfterFirstUnlock
  The data in the keychain item cannot be accessed after a restart until
  the device has been unlocked once by the user. After the first unlock,
  the data remains accessible until the next restart. This is recommended
  for items that need to be accessed by background applications. Items
  with this attribute migrate to a new device when using encrypted backups.
That sounds like whats happening is the value is stored encrypted in flash in the protected area which is locked with the key derived from the user's pin/password, which is what you want... But they must cache the plaintext value in some temp storage to be able to provide it while the device is locked. That's just my speculation, I don't see Apple divulging the source code anytime soon...

Storing a token in the keychain is preferable, because revoking a token is less onerous than nuking a user's password. Keeping the security set to maximum (kSecAttrAccessibleWhenUnlockedThisDeviceOnly) also seems advisable when we're talking about user password, or even access tokens. Just defer the backup task until the device is unlocked.

If you absolutely must proceed with the background task while locked, consider issuing a less-trusted token which is ONLY used for background tasks, and provide the absolute least privileges possible to accomplish the background task when presented with that token.

Also consider rotating it. For example, whenever a user connects with their full-access token, indicating their device is unlocked, it's a good time to expire the old background-task token and provide a new one. This also lets you do a "mass delete" of existing tokens in case of any funny business, and you'll have automatic recovery ("background processing will start working again next time you unlock").

> they must cache the plaintext value in some temp storage to be able to provide it while the device is locked.

From what I remember, no, they definitely don't save it in plaintext.

It's late, and I don't remember the exact details, but there are places where Apple talks about how it works.

Here's the gist, I think: When the user unlocks the phone, several encryption keys are generated using the pass code. One's used for Available After First Unlock, and that one's stored in RAM till the device reboots. Another is used for items that are only available when unlocked, and that's thrown away every time the phone is locked. Items that are restricted to the device use a key that is also derived from a private device identifier.

So not plaintext, but the decryption key is hanging around in the device.

You're definitely on target with the suggestion for a background task token though.

I agree, the whole point of the logout bug is that the keychain is locked, and that happens for a reason. I came up with a different solution that worked great for us:

Just pause the startup process of the app (in a non-blocking way) if accessing the keychain fails at startup. Then during applicationDidBecomeActive the startup continues with access to the keychain data. That way we don't weaken the security of our customers.

Good point. We thought about this as well, however solving this bug this way we wouldn't be able to continue background uploads every time the iOS7 'reboot' bug had occurred, which was fairly often.

It's a trade-off between user experience and security. As soon as Apple fixes the reboot issue, we'll increase the security level back to kSecAttrAccessibleAfterFirstUnlock.

> I assume the Loom keychain data (including the users password) is only accessible to the Loom app

I'm pretty sure that's only true for non-Jailbroken devices.