jpgoldberg
Joined 14 years ago
Joined 14 years ago
A it more than a year ago we had
- 1Password for Mac and iOS written in Objective-C and Swift - 1Password for Android, written in Java - 1Password for Windows, written in C# - 1Password CLI, written in Go - 1Password web-app, in Typescript - Browser extension in Typescript
Introducing new features was an ever more difficult task. Even getting the behavior of things like password strength meters or generators behaving the same across these platforms was increasingly difficult. (Hint, they didn’t behave the same.)
So we have been taking the time to develop a common core of code that can be used everywhere. And this does take time. Writing the common modules is often relatively easy, but we have to get them to work with the platform specific code
Late 2019 was our first successful deployment of any such function, and that was the TOTP calculator. It was largely transparent to users, except for settling on which sorts of TOTP “quirks” we were going to follow. (TOTP standards are a mess, and different Authenticator apps deal with special cases differently. At least 1Password is now fully consistent with itself)
Over the past year, we’ve been plugging more such things into the apps. And it allows us to fix bugs more quickly as well ashen they are in the common code.
1Paaword for Linux is built on all the new/common code. So while it doesn’t have everything that the others do, it is also where you will see the née stuff that is coming.
This has been a huge effort, and the transition has some rough spots, but once we get there we will be able to move much more quickly in developing and refining features and behaviors.
But it's only for parsing the data. What gets down with it after parsing can still be buggy.
But getting developers to use parser generators has been a struggle because I'm finding it hard to give dev team tools they can use and integrate into their build systems. It also doesn't help that most developers have forgotten anything they learned about formal language theory, so it's hard to communicate the value of using parser generators.
But we are getting there. Slowly, but there is progress.
I'd like to elaborate on the two points made by @epistasis
1. Ability to deliver of a malicious client does not depend on where your encrypted data lives. If you sync over your own private network or if your encrypted data is held by us, it is just as difficult (or hard) to get away with delivering a malicious client.
2. There is a lot of security value to openness and having the source available, but it is only a defense against deliberately malicious software if you compile the software yourself. Otherwise, there is a very weak trust chain between the code that has been reviewed and the binary you are running.
For the first point, a malicious client wouldn't need to exfiltrate all of your encrypted data. It would only need to exfiltrate the credentials needed to obtain your encrypted data. (As well as exfiltrating keys, etc). So for the overwhelming portion of people there is no significant difference with respect to us having your encrypted data or it living some place else.
As for the second point, tools for deterministic builds are improving, but there are still practical impediments. In theory there are ways to ensure a good trust chain between the reviewed source and the binaries that people run. But these are far from ready for our target users: everybody.
So if you, say, recommend KeePass for this sort of reason, are you also recommending it to people who will check the signatures on the source and then build from that? (I have enormous respect for both KeePass and for those who use it that way. But I have less respect for those who would recommend that to everyone. I hope that we are past the bad old days of "some people don't deserve security.")
While we can't completely rule out the possibility of delivering a malicious client (through us turning evil, external compulsion, or an insider attack), there are things that we can do to make it harder for that to go undetected.
You will find that where we can we have made it easy to run 1Password attached to a debugger. People with sufficient skills can see that it behaves as we say it does. This makes it far more likely that a widely distributed malicious client wouldn't go undetected.
Also to support this (and try to gain some of the security benefits of openness), we've gone into gory detail about how 1Password works. Sure there are holes in some of the documentation, but we are slowly filling in those.
I'll also mention the third claim that a "single employee" could cause the distribution of a malicious client. Again, there is no way to completely rule that out, but it would be hard for any single or small group of people do that without running a significant risk of this being detected internally. So it would have to be a fairly large conspiracy. And as we know, the plausibility of any conspiracy diminishes rapidly with the number of people who have to keep the secret. There are many eyes on the source, many eyes on the build and distribution process, and very few hands on the code signing keys.
Several times I've mentioned "significant chance of getting caught". Consider the risks to anyone trying to do evil this way. What are the consequences to them if they are caught, and so how big of a risk will they accept? So even though we can't make it impossible for someone to get away with it, we do what we can to make it hard to get away undetected.
None of this is perfect. And you have to weigh your own choices. But when you do so, make a fair comparison with the realistic alternatives instead of against an ideal.
Thanks. I (as you'd expect) agree with both points.
The second one is particularly challenging. Deterministic builds are possible for some categories of software, but it will be a long time in coming. And for software that is updated frequently, it is even harder for people to practically check that what they are running is the reviewed code. But the technology is improving for this to be more practical. On the other hand, app stores move things further away from having the ability to distribute determinist builds.
This is not an excuse to not seek openness, but it does point out that there are lots of things to do that most people don't to get the benefits of that kind of inspection.
1. Crypto delivered to the browser over HTTPS depends on the integrity of HTTPS.
2. A browser is a very hostile environment (injected JS, other browser extensions, etc.)
3. JavaScript may not be the best language for coding certain things (e.g., it is hard to remove strings from memory)
Depending on your use, some of these might be larger concerns than others. For us, 1Password.com, (1) is the biggest concern for those using the web-app. Our approach is to be very strict about TLS (TLS 1.2 only, HSTS, etc) and to encourage use of the native clients over the web-app.
We try to be very clear and open about the choices that we've made in our security design, why we made them, and what the implications for users are.
To pair it once would mean that a long term secret would need to be stored. Now we consider ourselves experts at storing long term secrets, but this one would need to be available to 1Password Mini and/or the browser extension even when 1Password is locked. So it would need to be stored on the local machine in a way that is not protected by 1Password.
So an attacker with root privileges (as needed for the loopback sniffing) would be able to get that key. And as I've said in various places throughout this conversation, "encrypting" something with a key that is available to the attacker is merely obfuscation.
I really really don't like talking about how our competitors might do things. (I work for AgileBits, the makers of 1Password). But I can talk about why we picked one security design over a plausible alternative. So here goes.
One way such a system could work is that the browser extension could talk to a process on the provider’s server. Because the server is remote, the TLS secret key would be stored on that remote server, and so would not be accessible to a root process running on the user’s system. This would, indeed, solve the IPC issue as there wouldn’t be any IPC.
There are a few reasons why we don’t operate that way. To operate that we we would end up knowing when and where our customers log into things. But we don’t want to be in a position to learn our customer’s shopping habits or whether they log into ISecretlyLoveNickelback.org. But with the client server model of that way of doing such things, we would be getting lots of that kind of information and holding on to some of it unencrypted.
Similarly, we don’t want to store any information that if stolen from us would enable such a thief to try to make cracking attempts at people’s Master Passwords. Sure PBKDF2 is good, but it only provides temporary protection should the data be stolen. We also don’t want “big” secrets in the browser. Our browser extension never sees your Master Password and only ever has the password for site it is filling for (or learning from). We see the browser as a very hostile environment.
Now there are certain ways around some of those things. And again, I’m not making any claim about how any other product does things. I’m only discussing how a service with the properties you describe might work.
Different security designs expose different sorts of threats. Nobody can really defend against an attacker running as root on their own system, but our more obvious exposure to to running on a rooted machine in this particular scenario is something that we think is worth the security and privacy benefits of our design.
[Note: I have plagiarized myself from https://medium.com/@jpgoldberg/ross-regarding-your-makes-you... as I'm being asked the same questions in different locations]
Obfuscation would mean that we wouldn't have to have this conversation as often as we do. But it would not make our customers more secure.
Officially our view is "if a malicious process with user privileges is running on the users machine when they use 1Password, there is little we can do".
But sometimes we try to do better. The example I raise is the steps we take to make things harder for keystroke loggers. We won't go to extraordinary measures to enter a battle that we can't win, but when there are simple things that we can do to make things harder for malware, we will.
See the first three paragraphs of https://blog.agilebits.com/2014/08/21/watch-what-you-type-1p... for some sort of attempt to clarify our vagueness about this threat model.
Hmm. I'm fairly sure we thought through that option, but at moment I can't see see/recall why we rejected it.
Plays with crypto, works for AgileBits (but don't speak for them, blah blah). Has done sysadm stuff.
keybase.io proof: [ my public key: https://keybase.io/jpgoldberg; my proof: https://keybase.io/jpgoldberg/sigs/zvE012tQcwlLb_hCw1HwgbGQyUQHlCJ6vUfkHvUUhaE ]