Thanks for posting this. Fortunately I'm not one of the ones affected, but I took the opportunity to rotate my Dropbox password and audit/prune my authorized devices.
I had a bunch of old devices in that list and removing each one triggered a full page refresh, which took longer than normal thanks to the JS-driven single-page design of the dashboard. The removal request itself went over AJAX, so I guess someone figured it was easier to throw away the page state every click than to remove an element from the list's DOM. Made the whole thing much more tedious than it needed to be; a form with a series of checkboxes and a single "remove" button at the bottom would have done fine.
So some of the removal requests go over AJAX, other submit a form. I started to write some JS to inject into the page to add checkboxes and a submit button and fire off an AJAX to remove the selected items but I think only the computers (not phone/tablet/etc) use AJAX. What's annoying is the AJAX request even has an array for the devices to unlink... It just passes up a single id.
It's funny because the apps linked section below that works exactly like it should, the request goes over ajax and then the DOM is updated without a full page refresh. I wonder if the different UX was an oversight or intentional...
Can we leave the toolkit evangelism to a different thread? The subject is behavior which was routinely implemented better in the mid-90s without using JavaScript at all.
I agree with the first part of your statement, but I am curious how AJAX behavior was implemented without JavaScript? Are you talking about Java? CGI? I have no idea.
Sorry if that was confusing, I wasn't trying to say AJAX-like behaviour happened without JavaScript but simply echoing mintplant's concluding observation that a 1995-style <table> with a bunch of checkboxes and a remove button would work just as well as the fancier tech stack.
(That said, I'm certainly not saying that JavaScript doesn't allow much richer UIs, only that as an industry we're often prone to assuming that the cooler tech automatically implies benefits to users – e.g. ask anyone who's had to reload a simple form UI because the AJAX logic failed to handle network / server errors, out of order dispatch, etc. in a non-confusing manner – or everyone should love your favorite tool without asking whether it has actual benefits for what they need to do.)
> we learned about an old set of Dropbox user credentials (email addresses plus hashed and salted passwords) that we believe were obtained in 2012. Our analysis suggests that the credentials relate to an incident we disclosed around that time.
There's a link to a page about that "incident", which says:
> * usernames and passwords recently stolen from other websites were used to sign in to a small number of Dropbox accounts.* [...] A stolen password was also used to access an employee Dropbox account containing a project document with user email addresses.
This doesn't add up, does it? I mean, their account of the incident in 2012 is usernames and passwords were stolen from other accounts; this got the attackers into a Dropbox employee's Dropbox account; that contained "a project document with user email addresses".
But now they're saying that "email addresses plus hashed and salted passwords" went astray. It seems to me that there's an important distinction between losing "a project document with user email addresses" and losing one with user email addresses plus password hashes.
> Our security teams are always watching out for new threats to our users. As part of these ongoing efforts, we learned about an old set of Dropbox user credentials (email addresses plus hashed and salted passwords) that we believe were obtained in 2012. Our analysis suggests that the credentials relate to an incident we disclosed around that time.
Sounds reasonable. I wouldn't be surprised if hashing techniques have changed since then, and this would be another way of upgrading users to the stronger scheme.
This line of reasoning always confused me. To upgrade to a stronger scheme, couldn't a service just rehash the prior hashes subsequently with a stronger scheme?
So for those users you'd have newScheme(oldScheme(password)). Then you could do a one-time migration of users with older scheme to increase the security to the new one.
That's a waste of resources, because each subsequent time a user logs in you have to hash the password twice with two different hashing schemes to verify their password.
The normal way of doing this is when the next time the user logs in, you use the old hashing scheme to check that the passwords match, if they do, you hash the password with the new hashing scheme and overwrite the old one with the new one. This is often coupled with invalidating all session tokens to force all users to login again (in order to speed up the process of migrating active users to the new hashing scheme).
The problem comes with the users that hasn't logged in for years, they still have their password hashed with the old scheme, but normally you would invalidate those hashes. That means getting rid of them completely so if a data breach would occur, their accounts doesn't have any hashes that could be attacked (UPDATE users SET password=null WHERE hashing_scheme='old'). From the users perspective, this would force them to reset (it's actually set now, not reset) their password via their email.
> each subsequent time a user logs in you have to hash the password twice with two different hashing schemes
The first time such a user logs in, you can upgrade their hash to the latest scheme, so there's no extra work on later logins. Django, e.g., does just this, automatically.
Sorry, I was trying to point out that you can have it both ways. As pixelcort suggested, do a one-time upgrade of all (weak) hashes to newScheme(oldScheme(password). But then as users login, you can upgrade them to just newScheme(password). No need to force a reset just because people haven't logged in recently.
I'm familiar with Django, and they happen to have some nice docs on both parts of the process: bulk upgrade to stronger scheme by wrapping [1] and individual upgrade on login [2]. But the technique isn't unique to Django.
Alright, I understand now. A bit hard to figure that out from your original comment though, but thank you for clarifying!
I'm curious about using two different algorithms for hashing at the same time would affect entropy. It could be that the original plain-text password has better entropy than the SHA1 hash (if that was your old hashing scheme) of the original password has.
> (UPDATE users SET password=null WHERE hashing_scheme='old')
Except you did this while the world was on fire, late on a Friday night, after a few beers, with management screaming down the phone. And you didn't check to make sure it didn't allow anyone to log into all effected users accounts with a null/empty password. Oooops...
(Been there, done that, made similarly stupid mistakes...)
An empty string hash does not equal the empty string (if you are on Oracle) and does certainly not equal null.
This will make it impossible for those users to login. Also, if you are luck it won't take the rest of the service down with them, making it impossible for the other users to login too.
This works, but if you've previously leaked a copy of the old hashes, then old passwords which are still in use are still only as secure as the old hashing mechanism. They won't be running old hashes against Dropbox's live service, they'll be dropping guessed passwords against Dropbox's live service. It doesn't matter if that password is now secured by bcrypt-with-a-hefty-cost-factor wrapped around MD5, improving its security versus being done in just MD5 -- if the password is right then the attacker will get through.
I'm only on two OSes (Windows, Linux) and predominantly two browsers (FF, Chrome), but Keepass (Works in Windows and Linux - pretty sure Mac too) + KeepassHttp plugin + PassIFox [1] + ChromeIPass [2] works for me.
I find it also nicer than LastPass as it combines with the native password saving of FF/Chrome rather than the highjacking and restyling of input boxes that look like user/passwords done by LastPass.
It's probably fine so long as both your 'client' and 'server' are on localhost, but it'll probably never be secure if the server is exposed to the internet.
I regularly switch between a MacBook for work, Linux desktop at work, Windows 10 home machine, iMac home machine, iPad, and iPhone, using at least two browsers on each (Chrome/Safari or Chrome/Edge) and often two Chrome profiles.
I use 1Password with the encrypted vault synced to Dropbox and it works wonderfully well. 1Password has native apps / browser extensions for all of those platforms (except Linux local app where they support and recommend using Wine).
I use KeePass with Keepass2Android (which has Dropbox integration), and Firefox Sync. You can log in to Firefox Sync and all your passwords will be there with you, but the canonical storage is KeePass. If I'm at a resetting computer, I just type it by hand from the mobile phone. It's not quite as convenient as using one password for everything, but it's a little bit less convenience for orders of magnitude more security.
Not unless you make sure you backup your password file somewhere other than dropbox. It doesn't even have to be very often, just whenever you update your Dropbox password (for example).
Isn't the point that the old hashes are out there somewhere and if cracked would reveal the plaintext password? This would then allow the attacker to access the compromised account since the password itself has not changed even if hashes are updated by doing newScheme(oldHash).
If your db has already been breached, it's too late to upgrade security on those hashes, true.
But if you're trying to proactively strengthen your password hashes to make them more resistant in case of a future breach, this lets you do that with no inconvenience to your users.
Genuinely curious about the risks to upgrading password algorithms by wrapping the old hashes. (Because at least one major framework seems to suggest this approach.) Is this an absolute cryptographic disaster, or a tradeoff to weigh against other concerns, or ...?
The alternatives seem to be never upgrading your hash algorithms/iterations (which leaves old, weak hashes in your db -- clearly problematic in the event of a breach), or forcing userbase-wide password resets every time you upgrade (which could be a major inconvenience for the users, making it a reason to avoid or delay strengthening your password hashing -- also problematic).
[Just to be clear: I'm leaving all of this to my framework--I do know enough not to try to roll my own security. But I'd like to try to understand the decisions the framework maintainers make, and their potential ramifications.]
That's better for the _next_ time your site is breached and you newScheme hashes get exposed.
Doesn't help if $attacker has a list of breached oldScheme(password) hashes, and can crack useful numbers of passwords from you old weak oldScheme hash. They can still log into migrated accounts if they can reverse oldScheme into the characters of password.
If you're preemptively upgrading your password hashing aglo with the assumption that you have not (yet) been breached, that works (if your assumption is good). Once the oldScheme hashes are out there though, it's too late.
One would hope your hashing scheme involves a salt and maybe even a work factor, and when you start including all the parameters, it's not so simple as A(B(C(P))).
@pixelcort is correct here, it is possible to do it that way:
If a DB has an old hash, call it V1 obtained as H1(password), one can apply a newer hashing scheme H2(V1) and save V2. To avoid having two classes of users forever one can always apply H2(H1(password)) for new users.
It appears though, that this is not what dropbox did, when they changed the scheme to H2 in 2012, applying H2(password) for new users instead.
One reason could be to not let spam reports on dropboxmail.com affect the primary domain's reputation (which is also used for corporate communication). If for any reason, the reputation of dropboxmail.com is compromised, they can move on to dropboxmail-1.com etc.
I began investigating DNS records to determine if there was some way there to conclusively ascertain that dropboxmail.com was legitimately owned by Dropbox. I could not find a way to determine this through DNS.
Next, I went to dropboxmail.com in my web browser, which redirected me to a page on dropbox.com [0] assuring me that dropboxmail.com was owned by dropbox.com.
> We are prompting a password update purely as a preventive measure. We have no indication your account was improperly accessed.
Preventative of what? In case they were compromised and don't know it? I have zero reason to suspect my own password file has been compromised, so there's no reason on my side to change it.
"We learned about an old set of Dropbox user credentials (email addresses plus hashed and salted passwords) that we believe were obtained in 2012. Our analysis suggests that the credentials relate to an incident we disclosed around that time."
that's a shitty thing to do imo. they first lure their users into a false sense of security with "This is purely a preventative measure (...)" and only provide an explanation if you go through the linked article.
they screwed up. yes, it was 4 years ago but they did. they should acknowledge it in the most simple manner.
Maybe they changed their password hashing scheme at some point around 2012, so they're trying to get everything aligned? No idea really, just a thought I had reading that same sentence.
Or they have an issue they don't want to talk about and this is one way to get it resolved...
> I received the email about this, but haven’t been prompted to update my password—what should I do?
> If you received the email but were not prompted to update your password, then you do not need to do so. This means that you did not meet the criteria. We’re prompting the update for users who haven’t changed their Dropbox password since mid-2012[1].
This is strange. I thought I'd changed my password in that time, but received the email. However, I'm not prompted to change my password when I log in. Now it's unclear to me if they think I should do this manually or not. Anyone else see this?
Ah, right, I took the section above to imply that they only send the e-mail to the affected users (which would make sense...). It doesn't specifically say that though.
Just curious, what happens if someone doesn't visit dropbox.com and login to the account? Do all devices connected to Dropbox with app lose connectivity?
https://www.dropbox.com/account/security
I had a bunch of old devices in that list and removing each one triggered a full page refresh, which took longer than normal thanks to the JS-driven single-page design of the dashboard. The removal request itself went over AJAX, so I guess someone figured it was easier to throw away the page state every click than to remove an element from the list's DOM. Made the whole thing much more tedious than it needed to be; a form with a series of checkboxes and a single "remove" button at the bottom would have done fine.