Wednesday, 6 June 2012

Revelation password manager considered harmful (but now fixed)

UPDATE: It would appear that most of these issues have now been corrected in the latest version of Revelation, which is great. I leave the post below just for historical reference.

Personally, I have changed to using keepassx, which has some really nice features (like password auto-type) and has an Android app to go with it.

I am writing this post to draw attention to long-standing security issues in the revelation password manager.

I should start off by saying that I was not the first person to find these issues. Erik Grinaker, the original author, planned a new revelation file format to address some of these issues in 2009. However, it seems he stopped maintaining the project around that time. Later, Jakob Westhoff noted these security problems in a 2010 blog post and wrote a fork which improved the security (though probably not by enough), but it was not merged into the revelation mainline. After sitting unmaintained for over a year, Mikel Olasagasti Uranga became the new maintainer.

This security issue went more-or-less unnoticed until February this year when someone posted this issue on the revelation bug tracker. Despite being marked as a "critical" bug, it is still yet to be fixed, while plenty of less important things have been changed and new versions have been released.

As a user of revelation, I was first aware of Jakob's post last year, and while I found it quite concerning, I was busy and didn't do anything about it at the time. I also assumed that it was just a theoretical weakness and that I didn't have much to worry about. It wasn't really until now that I looked into it and saw just how serious this is. I posted on the revelation bug tracker today explaining the real-world implications for this.

To summarise, recent generations of desktop Intel processors can decrypt a 64 byte buffer (enough to test a key) with AES256 in under 384 cycles. Running 12 threads concurrently on a high-end desktop PC (6 cores, hyper-threaded, 3.9Ghz) could probably average 70 cycles per key tested, or about 55,714,285 keys/second. Checking to ensure we got the expected output would take a bit more time, so let's conservatively estimate that we can test 25,000,000 keys/second.

While it would take on the order of 1061 years to crack on average by guessing arbitrary 256 bit keys, revelation's implementation is so insecure that an alphanumeric (a-z A-Z 0-9) password with 8 characters can be cracked in a little over 7 weeks on average. This is because it just takes the password (worth not much more than ~50 bits) and sticks about 200 bits of zeros on the end (effectively cutting the time to crack the key by a factor of 2200.)

If that can be done with a single machine, imagine how fast it would be with a custom hardware solution. Yes, you may be using a more complicated password than 8 alphanumeric characters, but even still your plain text password is probably still crackable in a reasonable time-frame given enough resources.

Essentially, relatively short plain text passwords don't have anywhere near 256 bits of entropy. ASCII password characters have around 6-7 bits of entropy each, so even 10 characters will give you no more than 70 bits of entropy. The way to get around this is to make it slower to compute the key from the password text. Specifically, if testing a key requires K cycles to compute the key and D cycles to test it, changing to a more complicated key derivation function (KDF) K2 will effectively "add" log2(K2+D)-log2(K+D) bits of entropy.

While Erik's 2009 proposed file format mentions PBKDF2, a secure key derivation function, his pseudocode just uses 10,000 iterations of SHA256 without combining the salt or password into the hash function again. Jakob's fork was similar, and is probably not secure enough either. Given that revelation only needs to compute the key once (when the file is first opened), if it takes a second or two to open this would not be much of a problem.

With the CPU above where a key can be tested in 384 cycles, extending the key derivation to take ~1 second would add about 23 bits of effective entropy (though you'd probably want to base the timing on older hardware). Using a cryptographically secure salt would also prevent a collection of different revelation password databases being cracked simultaneously. Slowing the key testing by using memory-intensive algorithms would also likely be several orders of magnitude better than simple hashing iterations, since they render CPU caches ineffective and custom hardware attacks impractical (see scrypt, for example).

So, what should be done about this?
  1. As much as I love revelation, it is unacceptable to be using in its current form. Anyone using or distributing it should consider it as effectively compromised until it is fixed. As of today, I am going to look into other password managers to use until it is fixed (if you recommend any, please comment).
  2. The authors need to make it a priority to fix this. Essentially, revelation needs to use a better key derivation function (KDF). Furthermore, revelation should show the user their password strength for the database as it would when adding a password to the database. Since slowing down the key derivation can only add at most around 20 bits of entropy (about 3 characters worth), it's still important for users to choose long and varied passwords (between 15 and 20 characters) to give enough entropy for AES encryption. Furthermore, revelation could even time how long it takes to compute the key and decrypt the beginning of a file to guess, based on their password length/complexity, how many years it would take to crack if a machine with 1000x as much power were available. Anything that comes in at under 2000 years is much too weak (don't forget Moore's law.)
  3. Old password databases should be converted to the new format and for disclosure of this issue users should be notified that their old revelation password databases are potentially insecure and that they should attempt to update or erase any of their older databases.
  4. People need to spread the word in the Linux community about this.
UPDATE: Looking through the revelation code to see if any of the other formats revelation supports are more secure (many are, but not as much as I'd like; not many use salts that are long/varied enough or hashed properly), I discovered that the fpm exporter doesn't encrypt the passwords at all. Even though it asks the user for a password when exporting or importing, it actually only uses it to encrypt the version number, leaving everything else in plain text. Checking the source history, I found this has been broken since 2004.

I found that Martin Schwenke publicly posted a comment regarding this some time ago, so I don't consider this to be an irresponsible disclosure.

Friday, 18 May 2012

The Fine Line Between Reminding and Nagging - Astrid on Android

I was going to post a short tweet to @weloveastrid, but decided that 140 characters was not quite enough to explain what I wanted to say. In fact, what started as just one idea in a couple of hundred words became a rather long essay, so I apologise if it's too long to read -- I've tried to split it up into logical sections for ease of reading. I mostly list the most straightforward ideas to implement first, followed by the harder or more lofty suggestions.

I recently began managing my "To Do" list with Astrid on Android. So far, I'm really liking it, but there's something that's beginning to bother me. That is, Astrid has gone a little bit overboard with the reminders, and has reached the point of becoming a nagging thing that I am inclined to just ignore.

I had a few ideas to help improve this:

Grouping reminders:

Even if you ignore all of the other suggestions in this post, I'd like you to consider this simple one. Currently, tasks without a specific time-of-day will get reminders at a certain time (e.g. 6pm.) I've been finding that recently, I'll suddenly get several reminders in a row, and Astrid does not handle it very well. I open the first reminder, and go to start editing it, but while doing that the second reminder appears and interrupts the process, and then I lose track of which one I am editing, and then another reminder, etc! Even worse, if I hit snooze on a bunch of them, then an hour (or whatever amount of time) later I'll get another bunch of reminders at around the same time again! This is really frustrating, but there's an easy solution:

When you do a reminder, just do a quick check for any other tasks which also have reminders in the next, say, 10 minutes. Then, instead of showing a screen for each, show a summary like:

You have 3 reminders:
Sort Paperwork
Feed the pets (in 5 minutes)
Write essay on open source software (in 9 minutes)
Clicking on one would expand it where it lies and show the usual options, but after dealing with a task the screen would stay there if there were still other reminders showing and allow the user to deal with those. In addition, the Astrid notification icon should support a number in the corner, so instead of having three Astrid logos in the status bar, have just one with small numbers superimposed on it e.g. "2, 3, 4, 5, 5+".

Distinguish between reminders and "completion checks":

Okay, so "completion checks" is not the best term, but that's not the point. What I'm talking about is that every so often, Astrid will make my phone vibrate a lot and pop up a reminder with three possible actions:

Reminder: Sort Paperwork
Have you done this yet?
So, what's the problem here? Well, while this claims to be a reminder, it is actually asking me whether I have completed it. These two concepts are fundamentally different, and it makes it very hard to answer this dialogue.

Let's say I already have sorted my paperwork. In that case, I don't need a reminder, but I am happy to say that I have indeed completed it. In fact, if I am looking through my to do list and spot something I've already completed, I just check it off -- I shouldn't wait until the next "reminder" to tell Astrid that I've done it, because there may not even be another reminder scheduled.

On the other hand, let's say I haven't done my paperwork. I have asked for a reminder because I thought maybe I would forget to do it. For whatever reason, it's not something I can do instantly, otherwise it would already be done. So I have a dilemma: I haven't completed it yet, so I can't answer [Complete]. I have no need to [Edit] the event, unless perhaps I've set the wrong due date or notification settings. And lastly, [Snooze] may not be what I want to do either -- snooze says "I'm concentrating on something else right now, so remind me later when I am not busy."

What if I have time to do it right now (especially if I have set a specific reminder time for a reason), but I can't just do it instantly? I can either:
  1. Ignore the reminder until I've completed the task, and then open it and press [Complete]. Unfortunately, ignoring notifications is a good recipe for getting behind on things. Furthermore, Astrid will probably give me regular reminders in spite of my ignoring it, which will feel very nagging.
  2. Press [Complete] before I've completed the task, and just hope I don't get interrupted before finishing the task and potentially forget about it.
  3. Press [Snooze] and try to guess a time-frame in which I think I can complete the task. The problem with this one is that "snooze" does not mean "yes, I'll start it right now / I am already working on it." It means, "I am busy -- ask me later". Furthermore, if the task takes me longer than I expect, getting repeated reminders will feel very much like nagging.
So, what's the solution? Make reminders remind, not check for completeness. That is, reminders should not assume the task has been completed. If the "encouragements" option is on, encouragements like "Have you done this yet?" are in fact discouraging if they are supposed to be reminders of things you still need to do. Instead, I think that a dialogue like this would be much better:

Reminder: Sort Paperwork
A job started is a job half done.
[Okay, I'll work on it now.]
[I'm busy, please ask me in [1 hour]]
[It's already done!]

In this case, the "Edit", "Snooze" and "Complete" equivalents work as before. If it's possible, I think having a default snooze time set would be helpful (read: a little less painful), and this should be dynamic (read the last section for more.) If the duration can appear to be editable in some way, then users will know they can press that to change the amount.

So what about this "Okay, I'll work on it now" button? My current idea is that it could start a kind of "You're working on ..." service with a notification icon:

The "You're Working On" Service:

As mentioned above, this would be a persistent notification icon, and when shown, it can have a relatively uncluttered screen containing:
  1. The name of the task you're working on prominently displayed, which should link to the task in case people want to edit it or get ideas. Potentially, if more than one task is set as "being worked on", the name part could become a drop-down so you can change to the "working on" overview for a different task.
  2. A "non-ticking" timer (that is, rough descriptions of time elapsed like "15 minutes" instead of "14:20", "14:21", etc.) Tapping the timer should switch to a ticking timer (minutes, seconds etc), tapping it again should hide the timer and just say "Show Timer", and tapping it once more would bring it back to the non-ticking timer.
  3. A pause/resume button for the task's timer. When paused, the screen should visibly change and "Paused" should be displayed prominently, and below it should appear the text "In case I forget to resume this, Astrid should remind me at [hour:minute]" where a clock time widget is shown (e.g. set 30 minutes in the future). At said time, the usual reminder is shown.
  4. An encouragement, if enabled.
  5. Whether paused or not, there should be buttons to say "Cancel working on this now" and "I've completed this now."
  6. To really polish this feature, a simple "Pomodoro" style timer would be fantastic, with a tick box like "Remind me to take breaks" and some way of opening the timing options. This feature should be disabled when paused.
  7. One other awesome feature would be a tick box like "Silent mode" with subtitle "While working on this task." This feature should be disabled when paused.
This service could also be shown when a task is opened and the clock button is pressed.

Detect Procrastination:

Alternatively, what if I have time to sort the paperwork right now, but I would rather procrastinate? Well, in this case, I'll probably want to [Snooze]. But if I'm a true procrastinator, pressing snooze just once will probably not be enough, and procrastinators are by nature unrealistic about when they will finish tasks. In such a case, I'll hit [Snooze] and leave it on 1 hour, unrealistically expecting that I will actually start it in 1 hour. When I don't, I'll hit [Snooze] again, and will probably make a very bad habit of it. While I believe having the option to "Start this now" would help people to get going, I also think that Astrid should detect repeated snoozing and try to help break the cycle (if such a mode is enabled, which should be the default). This idea is based on suggestions from qualified psychologists. A huge number of people struggle with procrastination (and procrastinators are especially likely to believe that a "To Do List" app will solve all their problems and so I suspect a large number of Astrid users suffer from procrastination). Some of these suggestions may initially seem condescending, but I think they could be genuinely helpful.

Ways of breaking the procrastination cycle:
  1. Someone in the habit of procrastinating doesn't need to be reminded more often; in fact, reminding them less often is more likely to stop them developing an automatic snooze reflex. So, even if ideas 2 and 3 in this section are not implemented, Astrid should ramp up the default time it offers to the user. Start snooze for each task with a default of 1 hour, then 2 hours, then 4 hours, etc. At some point (for example if doubling it again would make it go into the "quiet hours" or into the next day), it should start snoozing for day(s) at a time. In the worst case scenario, a user that continually goes with the default snooze will at least see it exponentially less often. Of course, the user is always free to change it back to 1 hour, or to disable the ramping.
  2. After multiple snoozes on the same task (without editing it in between etc), Astrid can give some encouragements specifically related to procrastination along with the reminder:
    • You can feel much better if you get a dreaded but small task out of the way first.
    • Try working hard on a task you enjoy to get you in the mood for doing other tasks.
    • Just get started! Do you have 5 minutes you could spend on this right now?
    • Set reasonable goals, like working on big tasks for just 30 minutes at a time.
    • Spend some time visualising yourself overcoming any initial difficulties to starting a task.
    • What specifically is the next thing you need to do on this task? Just start with that.
  3. After three or four snoozes, things can get a bit more interesting. Astrid could actually give a different dialogue before the usual reminder:
    Trouble getting started? Sort Paperwork
    We don't want to be nagging you, so perhaps we can offer some help:
    [My task is a bit big to handle at once]
    [I can't start until someone/something ...]
    [I'm not in the mood to do this]
    [Just turn off reminders for this task]
    [None of these apply
    Each option (except the last two) could offer some helpful and specific advice and possible actions, along with just an "Edit task" button and a "No thanks" button. The back button should go back to the previous dialogue.
    • Task too big? --> "Consider splitting your task into more manageable pieces. If you like, you can use the boxes below to make some more specific tasks:", then three or four "[________] [+]" boxes like the one found on the bottom of the main Astrid screen. If they fill them all up they can dynamically create more. Ideally, these would be part of some kind of sub-task feature, but until that's well supported, perhaps have a drop down "Spread default due dates throughout: [1 week]", with some different options for the default due dates, so they are staggered a little more helpfully. A number of the other defaults for these tasks could also be automatically inherited from the original task. Have a tickbox for removing the original task. If not ticked, the original task should simply not have any reminders set until after all the new tasks are due (this should be written somewhere on the screen).
    • Can't start until someone/something ...? --> "If you're waiting on someone else or something else to happen, you need to be realistic about your control over the situation. Perhaps schedule a date when you will follow them up, or when you will make some other action to resolve this. Otherwise, consider spacing your reminders differently." Give a box to allow the addition of a new item "Create Follow-Up task", and if such a task is added, a tickbox "[] Turn off reminders for original task" should be checked automatically.
    • Not in the mood to do this? --> "Research has shown that, in fact, the longer you wait for motivation to happen by itself, the less motivation you'll have (until you start getting close to serious deadlines). In fact, research shows that one of the best generators of motivation is in fact just starting -- after you do even 20 minutes of work on a task, you'll very likely be more motivated than if you had waited 20 minutes hoping for more motivation". Have a "Get started now" button (which would go to the "Working on ..." screen).
    • Just turn off reminders for this task. --> Exactly what it says. For users who can't be bothered editing the reminder settings. An "are you sure?" dialogue can be displayed first, just in case it's accidentally pressed.
    • None of these apply --> Just go to the normal reminder screen, and perhaps don't show the "trouble getting started?" box again for this task until a few more snoozes in a row. This should be formatted slightly different to the above choices (e.g. slightly different colour).
I think all of these things would go a considerable way towards helping those inclined to procrastination. I think users would receive it well, and of course, non-procrastinators are unlikely to run into the more "intrusive" screen here. Even though I know all these tips on a rational level, perhaps having the phone remind me at the times I am feeling most averse to study/work would help me to snap out of the cycle. Users may even like the extra dialogue features so much that they want them to be accessible from a menu within the task properties.

In conclusion:

Here's a quick summary of my suggestions:
  • Group closely scheduled reminders to prevent a flood of notifications.
  • Make reminders clearly about reminding and not about checking for completeness.
  • Expand the timer feature to be a fully-fledged "I'm working on ..." screen so people can feel good about pressing "Yes, I'm going to do it" and then actually getting started. Having a Pomodoro timer on this would be a killer feature.
  • Procrastination is a very widespread problem, and I think users would appreciate a nudge towards actual solutions to common issues. Simple things like increasing the snooze intervals, keeping track of repeated snoozing and offering more procrastination-relevant tips and even suggested remedies for some common issues could be very handy.
Thank you for reading my suggestions. I hope these ideas could at least spurn some useful discussion or provide some direction for a more thorough approach to these kind of issues.