1Password inter-process communication: a discussion

Recently, security researcher Luyi Xing of Indiana University at Bloomington and his co-authors released the details of their research revealing security vulnerabilities in Apple’s Mac OS X and iOS that allow “a malicious app to gain unauthorised access to other apps’ sensitive data such as passwords and tokens for iCloud, Mail app and all web passwords stored by Google Chrome.”  It has since been described in the technology press, including an article in the Register with a somewhat hyperbolic title. I should point out that even in the worst case, the attack described does not get at data you have stored in 1Password.

The fact of the matter is that specialized malware can capture some of the information sent by the 1Password browser extension and 1Password mini on the Mac under certain circumstances.  But roughly speaking, such malware can do no more (and actually considerably less) than what a malicious browser extension could do in your browser.

For 1Password, the difficulty is in fully authenticating the communication between the 1Password browser extension and 1Password mini; however, this problem is not unique to 1Password. The difficulty of securing inter-process communication on the operating system is a problem system-wide. A recent paper, “Unauthorized Cross-App Resource Access on MAC OS X and iOS” (PDF),  by Luyi Xing (Li) and his colleagues shows just how difficult securing such communication can be. Since November 2014, we’ve been engaged in discussion with Li about what, if anything, we can do about such attacks. He and his team have been excellent at providing us with details and information upfront.

As always, we are limited in what we can do in the face of malware running on the local machine. It may be useful to quote at length the introduction of that article

I have said it before, and I’ll say it again: 1Password […] cannot provide complete protection against a compromised operating system. There is a saying […] “Once an attacker has broken into your computer […], it is no longer your computer.” So in principle, there is nothing that 1Password can do to protect you if your computer is compromised.

In practice, however, there are steps we can and do take which dramatically reduce the chances that some malware running on your computer [could obtain your 1Password data].

That was written more specifically about  keystroke loggers, and there are some things that set the new attack apart. Like superficial keystroke loggers it doesn’t require “admin” or “root” access, but they were able to sneak a proof of concept past Apple reviewers.

The threat

The threat is that a malicious Mac app can pretend to be 1Password mini as far as the 1Password browser extension is concerned if it gets the timing right. In these cases, the malicious app can collect Login details sent from the 1Password browser extension to the fake 1Password mini. The researchers have demonstrated that it is possible to install a malicious app that might be able to put itself in a position to capture passwords sent from the browser to 1Password.

Note that their attack does not gain full access to your 1Password data but only to those passwords being sent from the browser to 1Password mini. In this sense, it is getting the same sort of information that a malicious browser extension might get if you weren’t using 1Password.


1Password provides its own security. What I mean by this is that for the bulk of what we do, we don’t generally rely upon security mechanisms like sandboxing or iOS Keychain. So it doesn’t matter whether those sorts of security measures provided by the operating system fail.

The careful reader will note, however, that I used phrases like “for the bulk of what we do” and “don’t generally rely upon” in the previous paragraph. There are some features and aspects for which some of 1Password’s security makes use of those mechanisms, and so vulnerabilities in those mechanisms can allow for harm to us and our customers.

1Password mini listens to the extension

Application sandboxing is a good thing for security. But it limits how the 1Password browser extension can actually exchange data with 1Password itself. Indeed, the extension (correctly) has no direct access to your data. Keeping your data out of the browser (a relatively hostile environment) is one of our security design choices. But this does mean that the 1Password browser extension needs to find a way to talk to something that does actually manage your data. 1Password mini (originally the 1Password Helper) was invented for this purpose.

One of the few ways that a browser extension can communicate locally is through a websocket. Browser extensions are free to talk to the Internet as a whole, but we certainly don’t want our browser extension doing that; we only want it talking to 1Password locally. So we restrict the browser extension to only talking to 1Password mini via a local websocket.

Mutual authentication

Obviously we would want 1Password mini and the browser extension to only talk to bona fide versions of each other, so this becomes a problem of mutual authentication. There should be some way for 1Password mini to prove to the extension that it is the real one, and there should be a way for the browser extension to prove to 1Password mini that it is a real 1Password browser extension.

The difficulty that we face is that we have no completely reliable mechanism for that mutual authentication. Instead, we employ a number of separate mechanisms of authentication, but each has its own limitations. We have no way to guarantee that when the browser extension reaches out to 1Password mini it is really talking to the genuine one.

There are a number of checks that we can (and do) perform to see if everyone is talking to who they think they are talking to, but those checks are not perfect. As a result, malware running on your Mac under your username can sometimes defeat those checks. In this case, it can pretend to be 1Password mini when talking to the browser extension and thus capture any information sent from the 1Password browser extension that is intended for the mini.

What can be done

Neither we nor Luyi Xing and his team have been able to figure out a completely reliable way to solve this problem. We thank them for their help and suggestions during these discussions. But, although there is no perfect solution, there are things that can be done to make such attacks more difficult.

What you can do

1. Check “Always Keep 1Password Mini Running” in Preferences > General

In the specific attack that Luyi Xing demonstrates, the malicious malware needs to be launched before the genuine 1Password mini is launched. By setting 1Password mini to always run, you reduce the opportunity for that particular attack.

keep mini running



2. Keep using the 1Password browser extension

Although what is described is an attack against the communication between 1Password mini and the browser extension through specialized malware, using the 1Password browser extension protects you from a more typical malware attack of pasteboard/clipboard sniffers. Likewise, the 1Password extension helps fend off phishing attacks because it will refuse to fill into pages that don’t match the domain for your saved Logins.

Quite simply, the 1Password extension not only makes life easier for you, but it is an important safety feature on its own.

3. Pay attention to what you install

As always be careful about what software you run and install on your system. On your Mac, open System Preferences > Security & Privacy > General. You’ll see an Allow apps downloaded from: setting there. We strongly recommend confirming that this setting is configured so that only apps from trusted sources can be opened. You can read more about the setting and its options on Apple’s support site.

Now Xing and his team point out that this isn’t a guaranteed way to prevent malware being installed. They were able to get a malicious app approved by the Mac App Store review process. However, I think it is reasonable to assume that now that Apple reviewers know what to look for, it will be much harder for that specific kind of malware to get through.

What we can do

There are additional (defeasible) mechanisms that we can add to our attempts at mutual authentication between the extension and 1Password mini. I will briefly mention a few that we’ve considered over the years.

Encryption with an obfuscated key

One option is to have a shared obfuscated key in both 1Password mini and the extension. (Remember that the browser extension never sees your Master Password so any secret it stores for authentication cannot be protected by your Master Password.)

Obfuscation only makes things harder for attackers until someone breaks the obfuscation, and every system designer should assume that obfuscation will be broken. See our discussion of Kerckhoffs’ Principle in our article, “You have secrets; we don’t,” for some background on why we tend to be reluctant to use obfuscation. Of course, it may be warranted in the absence of a more effective alternative, so this remains under consideration.

In anticipation of a likely suggestion, I should point out that even the magic of public key encryption wouldn’t save us from having to rely on obfuscation here; but I will save that discussion for our forums.

Using the OS X keychain

Another option would be to store authentication secrets in the OS X keychain, so that both our browser extension and 1Password mini would have access to it. This could be made to work for authenticating 1Password mini to the extension for those browsers that allow easy use of the OS X keychain.

This might solve half the problem for some browsers, but to date we’ve been focusing on solutions that work across all of the browsers we support.

An extreme solution

In the extreme case, we could have some explicit pairing (sort of like Bluetooth) between 1Password mini and the extension.  That is, the browser extension may display some number that you have to type into 1Password mini (or the other way around).  With this user intervention we can provide solid mutual authentication, but that user action would need to be done every time either the browser or 1Password mini is launched.

Quite frankly, there is no really good solution for this. To date, our approach has been to put in those authentication checks that we have and keep an eye out for any hints of malware that exploits the known limitations of what we do.

Is 1Password for iOS affected?

The research paper isn’t limited to discussing inter-process communication (IPC) that is done through websockets, but covers a wide range of mechanisms used on Apple systems. This includes some mechanisms that we may use for some features in 1Password for iOS.

Shared data security

1Password for iOS shares some of its data with the 1Password app extension. As most of that data is encrypted with your Master Password, it is not a substantial problem if that data becomes available to attackers. The exception, of course, is the TouchID secret.

As yet, we have not had a chance to test whether there is any exposure there, but watch this space for updates.


We truly are grateful for the active security community, including Luyi Xing and his team, who take the time to test existing security measures and challenge us to do better. Our analysis of the researchers’ findings will continue and we will post an update if further action is necessary.

69 replies
Newer Comments »
  1. Achyut Kamat
    Achyut Kamat says:

    So would another option be to simply remove the Safari 1Password extension, and not have 1Password mini running at all – i.e. simply open 1Password and copy/paste passwords – until Apple fixes this?

    • Khad Young
      Khad Young says:


      I believe it is much easier for malware to grab data from your clipboard than to exploit the issue discussed here. It is much safer to use the extension than to be shuttling passwords on your clipboard all the time.

      Also, keep in mind that if a malicious app gets installed, it could just replace 1Password to steal your master password and data more directly. There is no need for all the song and dance.

      The best thing to do is remain vigilant when installing software from trusted sources and trusted developers.

  2. The Final Monster (@thefinalmonster)
    The Final Monster (@thefinalmonster) says:

    I had the same question. As a matter of fact I never use the browser extension. I open the full 1Password app when I need to look up a password. OS X does a good job saving my web passwords with iCloud Keychain.
    Jeff you mention good browsers / bad browsers. Which is which?
    I think in the interest of security it would be fine to break up with bad browsers.

  3. Enrique
    Enrique says:

    Can you explain better how much of our data is exposed in the iOS app and what security measures can we adopt to mitigate the problem, if any?

    • Jeff
      Jeff says:

      At the moment we don’t think that any data is exposed on iOS. But until we’ve tested more carefully, I didn’t want to make such a declaration.

  4. john welch
    john welch says:

    One thing in the demo in the ars article, is that it looks like the data going between the extension and the mini app is in clear text. looks like, but that could easily be mistaken.

    • Jeff
      Jeff says:

      You are correct. We could encrypt it, but the encryption keys would need to be stored unencrypted on the system. So really, we could only “obfuscate” that traffic.

    • John C. Welch
      John C. Welch says:

      well, you could get very complicated and embed the keys in each component, but that would then make updating one component, or adding a component later extremely difficult if not impossible. That’s always been a problem of interprocess communication that ironically isn’t as much of a problem for intermachine communication.

      I genuinely feel for the folks trying to solve it, it’s one hell of a problem.

    • Jeff
      Jeff says:

      Typically, you would embed a long term key in each component and then used that to generate “session keys”. But the embedded key is still just obfuscated. And yes, when (not if) it gets discovered, we would have to change all of the components.

    • John C. Welch
      John C. Welch says:

      So question: in this specific case, the browser extension, have you tracked a lot of off-line use cases? That is where people need to use the browser extension when the machine is not connected to an external network?

  5. Dirk Roorda
    Dirk Roorda says:

    I never use the browser extensions. Whenever I need a pwd, I call up the mini by its shortcut, copy the pwd, and paste it where it needs to be. To me, that is user-friendly eenough. I guess that leaves me immune to this particular trick.

    • Jeff
      Jeff says:

      Sure, but it leaves you vulnerable to malware that is reading your copy/paste pasteboard. In general, browser integration is more secure.

    • Dirk Roorda
      Dirk Roorda says:

      In most cases I need the password in the Terminal, not in the browser. If malware reads my clipboard I’m in deep trouble indeed!

  6. Temptin
    Temptin says:

    Jeff, are you overthinking this like an engineer again? ;)

    I think the real, true 31337 solution to 1Password’s very minor issue is to do this:

    ..on start
    ....if port 6263 in use
    ......display dialog "oh no! hackers are using the port! don't input any passwords on the web!"

    Remember that Mini launches on every system startup by default and would detect if the TCP port was already bound. Therefore this is a flawless solution.

    Just make 1Password & 1Password mini verify that only the real Mini is the app currently binding TCP port 6263, and give a big fat warning if it isn’t.

    • Jeff
      Jeff says:

      That’s pretty nice!

      I was looking at cooking up a stand-alone script to see what is listening on mini’s ports and report if any of them are not mini. But this can be built into mini itself.

    • Temptin
      Temptin says:

      lsof -n -i4TCP:6263 | grep LISTEN


      The 1st column is the app name (“2BUA8C4S2”), 2nd column is the PID. With the PID we can verify that the process is the legitimate Mini process.

      If you can figure out what API lsof uses, you can build this check into Mini.

    • brenty
      brenty says:

      If only! Randomizing port would prevent people using firewalls or antivirus from being able to make an exception i most cases.

      A secure browser extension that doesn’t work is not particularly useful, unfortunately. :/

    • john welch
      john welch says:

      Given that the communications are internal only as I understand it, external firewalls shouldn’t care about what port app a is using to talk to extension b. The internal firewall should be able to deal with this for the same reason. It’s not leaving the machine.

      As far as AV goes, a whitelist of apps allowed to open websockets should alleviate that issue. The browser extension is filling in forms locally and that data is sent to the site by the browser/human, not the extension.

    • Temptin
      Temptin says:

      Was reminded of this topic when I woke up and had a tiny “eureka” moment. In addition to the port-check I proposed above, the following scheme might be a good way to ensure that the browser extension is talking to the real mini and vice versa:

      on every 1Password vault unlock (via mini or full app):
      ..if database table doesn't already contain "handshake key" details, generate one:
      ....generate a random public/private cryptographic key pair the encryption key pair in the 1P database, call it "handshake keys"

      first time the extension connects to 1P mini (initial handshake):
      ..extension sends a request to port 6263 for permission to connect to Mini
      ..Mini checks the PID of the app connecting to it and checks if it's one of the allowed browsers, and checks "codesign -v" on it to make sure it's got a valid code signature; if it's a tampered browser, Mini displays a warning and refuses to handshake with the extension
      ..if the connecting browser passed the code signature check, Mini pops up a dialog: "[appname/Safari] is trying to connect to 1Password, type this code into the browser extension: 28493"
      ..the user types the code into the browser extension GUI
      ..the extension sends the 28493 code to Mini
      ..Mini accepts the connection since the code was valid
      ..the Mini app asks the user to unlock the 1Password database
      ..the Mini app loads the public/private "handshake keys"
      ..the Mini app now takes a KNOWN PLAINTEXT (the string "1Password mini") AND the browser's bundle identifier ( in this case), concatenates them to the string "1Password" (thus guaranteeing that the encrypted string is different for every browser that connects), and encrypts it using the private key, and then saves the app bundle identifier and encrypted string in the 1P database as something like "handshake.apps[0] = ['','9032hd3092289dhdhaiuauhd2iaudh2akdhajrha3kjrh']"
      ..(sidenote: Provide a GUI in the 1P Preferences to REVOKE the permissions granted to each individual browser...)
      ..the Mini app sends the encrypted "9032hd3092289dhdhaiuauhd2iaudh2akdhajrha3kjrh" string to the browser extension
      ..the extension saves the encrypted string in its internal settings storage; that's the future "handshake" AND "verify" string

      continued handshake, and used for all subsequent re-connections between Mini and the browser:
      ..the browser extension loads the encrypted string from its internal settings storage
      ..the browser extension sends a "Hello,[9032hd3092289dhdhaiuauhd2iaudh2akdhajrha3kjrh]" to Mini
      ..the Mini app asks the user to unlock the 1Password database
      ..the Mini app checks the app bundle identifier of the connected browser, checks the browser app's code signature, and finally checks if the [encrypted string] matches the one in the database for that browser, thus knowing that the browser extension has permission to talk to 1P Mini...
      ..that takes care of part 1 of the handshake; Mini now knows for SURE that it's still talking to the real browser (app bundle ID still matches, app bundle code signature still valid, and the extension provided the right handshake key to prove it's the real extension). onto part 2 of the handshake; letting the browser extension verify that it's still talking to the real Mini:
      ..the extension now asks Mini for the public key from the public/private "handshake key" pair
      ..Mini sends the public key to the browser (and that key is NEVER stored in the browser; since that would defeat the purpose of letting the extension know that Mini knows a valid secret too!)
      ..the extension now takes its known SHARED handshake-secret ("9032hd3092289dhdhaiuauhd2iaudh2akdhajrha3kjrh") AND the public key it just received from Mini
      ..the extension decrypts the string and gets "1Password". The trailing bit is not interesting YET, but it will be soon.
      ..the extension SPLITS the string on the "+" sign into two parts: "1Password mini" and ""
      ..the extension checks that part 1 == "1Password mini" and is now sure that the public key was valid (and wasn't just random gibberish), but it is NOT YET FULLY SURE that it's talking to the REAL Mini, since a fake Mini could have stolen the public key, to verify that it's talking to the real Mini, the EXTENSION now takes the current timestamp, and a random number (new Date(), Math.floor(Math.random() * 1000000000)) AND concatenates it with part 2 of the verification string, giving us "timestamp_random+bundleid", meaning something like "", which we'll call "ghostbusterString" (because I've run out of variable names)
      ..the extension sends "verify,[ghostbusterString]" to Mini and waits for a response
      ..Mini takes the incoming string, splits it on "+", verifies that part 2 is STILL ""
      ..Mini then takes the PRIVATE key and encrypts the WHOLE string, so "" becomes something like "di23jd23jdioq3djoajdaio3jd3irh4iuh5iuh2iur2hdiu2hd33"
      ..Mini sends the encrypted response back to the extension
      ..the extension decrypts the response using the public key (which it has previously validated to be the correct public key since it was able to decrypt the mutually saved handshake string)
      ..the extension checks if the decrypted string == ghostbusterString; if so, it knows that the Mini it is talking to signed the verify-handshake using the correct private key
      ..the extension now knows that whatever it's talking to KNOWS the private key; and that's ONLY going to be the real Mini, since an impersonator would not have decrypted the 1P database to see the stored internal keys (because if it had been able to do THAT, it would have NO NEED to impersonate Mini, it would ALREADY be IN ;)). the extension now knows it's talking to the real Mini, and Mini knows it's talking to what SEEMS to be the real extension, and that it's contained in a REAL, codesigned browser, which is good-enough (because if the user has installed a malicious extension impersonating 1Password Extension, then the user has mental problems, and that's not a flaw with 1Password itself)
      ..since both of them have now verified each other, they need ONE LAST THING before they can stop using encryption; they need a SESSION KEY, it's time to clear up some memory! Mini clears the private and public key from RAM since they're no longer needed (note: this is even safer on El Capitan, since apps can't read the RAM of other apps anyway). the extension clears the public key variable by setting it to an empty string so that it'll be garbage collected, since we'll no longer need it; although since it's just a public key, it doesn't matter if it stays in RAM.
      ..Mini generates a random string such as "13904u0948"; this is now the SERVER SESSION KEY
      ..Mini sends the SERVER SESSION KEY to the extension
      ..the extension generates a random strung such as "o23kdop2k2d"; this is now the CLIENT SESSION KEY
      ..the extension sends the CLIENT SESSION KEY to Mini
      ..Mini stores the SERVER SESSION KEY, CLIENT SESSION KEY and the PID and BUNDLE ID of the connecting browser in RAM (so something like "13904u0948", "o23kdop2k2d", "314" and "", respectively)
      ..the extension saves the SERVER SESSION KEY and CLIENT SESSION KEY in a temporary variable that's cleared on browser shutdown
      ..extension and Mini breathe sighs of relief, and hug each other one last time... they've finally navigated the minefield safely and have verified each other!

      now, for all subsequent communication between the extension and Mini:
      ..the extension connects to Mini
      ..Mini checks what app connected to it, verifies the PID and BUNDLE ID of the connecting browser to make sure it's in the "SESSION" table, and then verifies the browser app code signature as well... if it's all good, Mini knows it SEEMS to be the browser re-connecting to it, the extension sends the CLIENT SESSION KEY to Mini ("o23kdop2k2d")
      ..Mini verifies that "o23kdop2k2d" is the correct CLIENT SESSION KEY for that app's BUNDLE ID/PID.
      ..if wrong, Mini shows a big fat error box on the screen and refuses the connection
      ..if correct, Mini knows it's talking to the real browser extension
      ..Mini now sends the SERVER SESSION KEY to the extension ("13904u0948")
      ..the extension verifies that "13904u0948" is the correct SERVER SESSION KEY for the Mini it's been talking to on port 6263
      ..if wrong, the extension shows a big fat error box on the screen and refuses the connection
      ..if correct, the extension knows it's talking to the real Mini
      ..from here on out, all communication is validated both ways

      this authentication scheme only requires 1P Mini to unlock the database TWICE in each session to retrieve the private keys: Once during the first "[appname/Safari] is trying to connect to 1Password, type this code into the browser extension: 28493", and once for each subsequent restart of the web browser or Mini. It's a maximum of security for a minimum of inconvenience

      however, since the authentication hinges on never losing the private key (and you shouldn't be able to, since it's stored in the REAL password vault behind the master key; if the evil guys have the private key they are already inside the vault and you have bigger problems), it MIGHT also be worth to have a key rotation scheme so that Mini changes public/private key pair every day or something. it can be built into the handshake protocol so that a two-way authenticated extension/Mini pair can replace the key; all that Mini would have to do is store the outdated keys in the database until all browsers have been updated. One way to make that slicker would be if Mini stored per-browser/app bundle ID "handshake key" public/private key pairs; that way each browser has a unique public/private key pair. it's not more secure, though, since the rest of this handshake protocol is already secure. but it would simplify per-browser key swapping.

      Well, have fun implementing this, Jeff! Sounds like some fun programming! (I’m serious).

    • Temptin
      Temptin says:

      Actually, I have to revise a statement: “Mini must be unlocked once for each subsequent restart of the web browser or Mini” – this is not entirely true. Simply DON’T send the two-way authentication handshake on INITIAL browser startup. ONLY establish the authenticated connection it if the user tries to USE the extension.

      So browser startup would work like this:
      ..browser starts up, extension loads
      ..extension checks if port 6263 is connectable; if yes, it knows SOMETHING (probably Mini) is on the port validation is required, since you're not using the extension yet
      ..but as soon as the user tries to use the extension, you would simply make Mini draw a dialog that says "The 1Password extension for Safari wants to access your vault. Enter your master password:"
      ..from there on, the 2-way public/private key handshake is performed

      There we go; a maximum of security and a TRUE minimum of inconvenience. Because the user’s attempt to use the extension would ALREADY trigger a “you must now unlock your vault” message with the way 1P works TODAY. So this changes NOTHING about the user-convenience, and adds EXTREMELY good two-way authentication. ;)

      And thanks to the fact that each browser/app has their own token, you are protected against malicious apps impersonating the extension. You can also revoke access per-browser (as discussed earlier), and you can display a “date last used” for each paired browser in the 1P preferences, along with a “if a paired browser X has not been used in [30/whatever] days, automatically unpair it” security feature. :)

    • Jeff
      Jeff says:

      We would need to go through this handshake (with user activity) every time either mini or the browser relaunches. (Or store these keys obfuscated on disk.)

    • Temptin
      Temptin says:

      @Jeff I thought so too, but then I made a followup reply which you may not have seen (above your reply), which outlines a way to avoid that entirely and make 1Password visibly act the same way as it does today, with zero extra inconveniences for the user.

      Basically: Don’t do the handshake until communication is actually needed by the extension.

      At browser startup: The extension will simply check that port 6263 is available, but won’t verify it. So no login is necessary. At this point, the extension still treats the port as untrusted, since no handshake has taken place.

      If clicking the 1P toolbar button, or the extension detects a new login: Now the extension actually talks to Mini. If the database is locked on Mini’s side, the real Mini, in turn, will display the interface to ask the user to unlock the database. If the database is still unlocked, Mini can do its part of the handshake without user interaction. Either way, the private key is retrieved and the extension and Mini do the 2-way handshake, and sets up the client+server session-tokens, which are then valid for the remainder of the browser session (as long as the PID stays the same).

      So in this scheme, the user only has to unlock Mini a single time, and it’s at the exact same time that it would have happened today with how 1P works right now: When vault access is actually needed (for saving a login or for retrieving a login). The secure handshake would therefore be transparent to the user, and there’s no need to store obfuscated keys on disk.

      The whole point of the scheme I outlined is that the extension only needs a single, permanent handshake/verification token (for the initial connection each session) which is only valid for that exact app bundle ID and therefore doesn’t matter if it leaks; and it only needs a temporary client+server session token for quick re-authentication, and neither of these secrets matter if they get out, since only the REAL Mini has the hidden private key for finishing the handshake. And if an evil guy has the private key, you’re boned anyway. Thus this is as good as 2-way authentication on a local machine can get. None of the secrets matter if they get out; and that’s a pretty damn good design. No obfuscation needed. Heck, you can publish the whole handshake protocol and the browser’s handshake token and a bad guy would still be unable to do anything with it. Security through good practices instead of obscurity.

      Next, you might object “Well, if we only re-do the handshake when the user wants to use 1Password; we’ll still be inconveniencing them by asking for the master password whenever they re-start the browser and the PID changes.” But nope, as long as 1Password Mini is still unlocked, it can instantly retrieve the private key and do its part of the handshake with zero need for user interaction. And if 1Password Mini is locked, then it would have required re-login even with how 1Password works today. So again, zero change to the user experience.

      So, with one simple change, we can ensure that all this extra security is totally transparent to the user (well, apart from giving them a cool new Preferences tab with a list of all apps that have been authenticated and which ones were last used, and a way to revoke their access, etc!).

      Simply make it so that the master password authentication is only required when the user clicks the toolbar button or tries to save a new login. That means all of this extra security is transparent and visibly acts the same as the current 1Password.

      And it goes without saying that the neither the extension, nor Mini, will do any data transfer between each other until the handshake is complete, obviously.

    • Temptin
      Temptin says:

      Oh and remember to set this up in addition to the on-startup “Port 6263 in use? Warn if it’s malicious!” code suggestion, so that Mini itself (which is set to start on bootup by default) will be the first-line defense against anything bad using the port.

      The coolest part of all this is that the user would experience no extra inconveniences, and would get full control over what apps are allowed to talk to port 6263, along with a fun new interface for revoking browser permissions, with potential extra security features like “automatically revoke permissions for browsers that have not been used in the last [30/whatever] days.” (To detect abandoned browsers in which case it would be nonsensical to keep them authenticated.)

    • Temptin
      Temptin says:

      One more improvement would be possible, in order to prevent an attack where the enemy somehow grabs the SERVER SESSION TOKEN + CLIENT SESSION TOKEN, kills 1Password mini, takes its place, and is therefore able to impersonate the abbreviated (less secure) re-connection handshake using the “SERVER SESSION TOKEN”.

      That improvement would be to always perform the full two-way public/private crypto handshake whenever the extension re-connects to Mini. That way the extension always makes sure that whatever “Mini” it’s talking to knows the private key.

      But I worry that browser extensions can’t have persistent websocket connections (since they work by injecting code into the current page, as far as I know?), so maybe the full handshake on every attempt to invoke 1Password would be overkill?

      An in-between solution (and the one I would go for if I was implementing this security scheme) would be to still use the quick&slick server/client session tokens proposed, but to expire them every 5 minutes so that if the user clicks the 1Password toolbar button/tries to save a new login, it will do the super-quick token handshake most of the time, but will do a full re-handshake if too much time has passed and the tokens have expired.

      This practically kills the “take the unprotected tokens, kill Mini and impersonate it”, by adding a timing element: If they kill Mini, they also have to get the user to try to save a new website password within 5 minutes, because after those five minutes are up, the extension will do a new handshake (and vice versa: The real Mini will not accept expired tokens either).

      All of this sounds good to me, since literally every piece of this handshake protocol can be out in the public, including the shared secrets. Only the private key needs to remain private, and that’s easy to ensure: It’s stored in the real 1P vault, so only the real 1P Mini knows it.

    • Jeff
      Jeff says:

      Yep. And then we can actually check the code signature of the PID that is listening. But this isn’t something we can actually do within the browser extension.

      One thing we can try to do is put this in mini and the main application. So each can try to alert the user to processes listening on the ports that 1P mini likes to use. Of course these aren’t reserved or registered ports, so something listening there may very well be legitimate.

    • Temptin
      Temptin says:

      Yep, the only weak part of this chain is that the 1P extension can’t be 100% sure it’s talking to the real mini, since extensions can’t check the PID/bundle ID of the port’s listener. That’s why there’s all this extra jazz with a private key, etc. It’s the closest we can get to authenticating Mini towards the browser.

      It doesn’t stop an attacker from starting a fake Mini that displays a “please unlock your vault” screen and grabs the private key; but then again… at that point, they’ve got the private key, so who cares about emulating the handshake at that point? That’s a different attack vector entirely! And it’s a vector we pretty much stop by making sure the autostarting 1P Mini warns if “bad” is listening to 6263.

      We could make this even more secure by making 1P mini into a LaunchAgent with a “relaunch” property so it stays active at all times, thus even if an evil program could kill 1P Mini, it would immediately be relaunched, detect the bad guy binding the port, and warn the user. This kind of launch-protection would be pretty damn secure on its own, but coupled with the 2-way cryptographic handshake it would pretty much kill the vulnerability for good.

      Also see my 3 followup comments just posted above, where I cover some great improvements to the protocol: No longer requiring authentication as soon as the browser relaunches or if the vault is still unlocked in Mini (thus not annoying users with a “please unlock your vault” at every browser launch), and an improvement securing the re-use of the session tokens. It’s important to be able to re-establish the connection without constantly doing the heavy handshake, but it’s also important to ensure that a leak of the session tokens doesn’t compromise a whole session; thus, we time-limit the tokens, so that an attacker has a super tiny 5 minute window to use them, after which they can no longer talk to the extension anymore. ;)

    • Anonymous
      Anonymous says:

      Not perfect though. What if your Mini is somehow unknowingly killed (admittedly malware without elevated privilege won’t be able to actively kill it, but what if it does), and then a bogus one is spawned? You won’t get a notification in that case.

    • Temptin
      Temptin says:

      If the real Mini died, you’d see no more Mini in the Mac menu bar near the clock. You wouldn’t be able to log into existing sites since your browser extension wouldn’t be talking to the real password vault. You wouldn’t be able to open the 1Password menu by clicking the browser toolbar button, since the actual menu is drawn by Mini. Trust me, you’d know if Mini was not running. ;)

      And soon El Capitan is here and makes it impossible for malware to touch other processes or their memory, and everything has to be code signed and valid at all times. Lovely days are coming our way.

      ..but I don’t think anyone is going to try to impersonate Mini, since they would be detected so easily. It’s much better for malware to just install a Safari extension (without a toolbar button) which reads all submitted form data and sends it to the evil author, that way they get all passwords. But that risk affects LastPass too, and the malware author would have to get past the browser’s “do you want to install this evil extension?” warning somehow before this could be a real attack. Probably going to be impossible in El Capitan since Safari will require that all extensions are signed by Apple and are downloaded from the Safari Extension Gallery instead of 3rd parties.

  7. John Graybosch
    John Graybosch says:

    “One option is to have a shared obfuscated key in both 1Password mini and the extension. […] Obfuscation only makes things harder for attackers until someone breaks the obfuscation”

    But for this particular attack, the malware was only intercepting interprocess communication, right? If you’re referring to obfuscating an encryption key at rest, that’s outside of the scope of this attack, no?

    What if at install time you generate a symmetric encryption key. Going forward, you use that key to communicate? True, malware could de-obfuscate the key on disk, but perhaps it adds one more hurdle to jump through. In this case, it seems that the sandboxing prevented the malware from reading the data at rest, but not in transit (on the local system). So if the interprocess communication was encrypted with a key generated unique to the install, this malware would only be able to grab encrypted messages. This, along with HMAC would ensure the data isn’t tampered with either, possibly in an attempt to break the communication or leak data. Ultimately, the attacker could still siphon off the encrypted passwords and the user wouldn’t know. But wouldn’t that be better than plaintext?

    What do you think?

  8. Scott D.
    Scott D. says:

    My primary concern is with the iOS app. If I only use the full 1Password app to manually look up my passwords and then manually type them into an iOS banking app or a web site’s login screen, would I still be exposed to these problems?

    My main use case for 1P is just storing (and visually retrieving) my passwords using the app. I rarely, if ever, use the 1P extension on my iPhone or iPad. So am I safe from these XARA vulnerabilities?

    • Andrew Costen
      Andrew Costen says:

      It’s actually safer to use the 1Password extension in Safari on iOS because 1Password for iOS doesn’t have a WebSocket-connected-helper the way it does on OS X and isn’t vulnerable to any of the XARA vulnerabilities that we’re aware of. A copy/pasted password can theoretically be read by other apps if the password isn’t cleared from the clipboard before the theoretically “malicious” app is opened, so it’s less recommended (although sometimes necessary, such as in apps that don’t use the 1Password extension). We do recommend setting the clipboard to be cleared after a set amount of time (under “Settings > Security > Clear Clipboard”) to make this less of a risk.

    • Andrew Costen
      Andrew Costen says:

      That said, typing passwords in manually the way you mentioned is certainly safe enough, except in the sense that a password you can enter manually might mean it’s a password that can be remembered, and hence might not actually be a very strong password.

  9. Jim
    Jim says:

    I’ve been fiddling around with this since reading the original paper. It’s possible to use lsof to look at port connections on a system (lsof -i). Would it also be possible to make a determination if there’s a malicious eavesdropper on port 6263 by checking the lsof output periodically to see what’s using that port? It should be just 1Password Mini and your browser, yes?

  10. jb510
    jb510 says:

    Nice writeup. I greatly appreciate clear, thorough but concise write ups like this that steer clear of the FUD. Worth noting that you, understandably, are focused here on the websockets / scheme hijacking vulnerability, but that XARA vulnerability means the OS X Keychain is vulnerable directly… so storing keys there would be like storing the chickens in crate with a dog door…

    Hopefully Apple will get keychain / sandboxing fixed promptly, because I feel very naked at the moment.

    It’s easy to say “install apps from trusted sources” but most of us DO have apps installed that auto-update in the background and right now any one of them could auto-update into password thief…

  11. Chris Upjohn
    Chris Upjohn says:

    Personally I’d prefer an extreme method where my phone is used in the authentication process. I already use it for a number of 2-step logins so it wouldn’t impede my workflow at all.

  12. Arend Abel
    Arend Abel says:

    To what extent, if any, is there a similar vulnerability in the Windows world (where I live). Also, I was not 100% clear on whether this vulnerability affects the iPhone, as well as Mac and IPad. I thought (erroneously perhaps) that the iPhone version of Safari didn’t have an option to use 1Password extensions (which of course means that I’ve been using cut and paste, which I assume carries the vulnerabilities you mention).

  13. Nate M
    Nate M says:

    I feel I must be missing something here, else the solution seems rather straightforward. I admit in advance I have no deep knowledge of how 1Password mini or extension operate.

    This particular attack is predicated on the idea that a malicious app gains control of the websocket before 1Password can. If that’s true, wouldn’t that also mean that 1Password is no longer listening on that websocket? Assuming thats the case, and this is not a man-in-the middle style attack (it was not clear in the paper) via the websocket protocol, then why not simply add a second handshake?

    1) Websocket handshake opens channel
    2) Etension requests permission to talk to mini (sends signed ID?)
    3) Mini checks to see if it knows the ID (from the install)?
    4) Mini returns randomly generated session token (used for encryption for a limited period)
    5) Etension does its magic

    If the attacker hijacked the port, the handshake would fail because mini is not there to answer
    If the attack is a man-in-the-middle, then it will witness the handshake, but this is where public key encryption could come in handy to protect the exchange.

    So. Go ahead and tell me. What am I missing?

  14. Fernando
    Fernando says:

    Why not establish a secure TLS connection on the websocket using a certificate for authentication? Yes, it would require an Internet connection to validate the certificate but if the browser extension is being used, chances are a connection is available. At worst the user types in the password manually if no connection is available and a small latency is introduced if it is available.

    • john welch
      john welch says:

      That’s what I was thinking. Since the browser extension is rarely, if ever going to be used in an offline situation, using an external secure validation mechanism would seem to be a way to deal with this. For cases where having a third party auth isn’t an option, 1P could build (and sell) a component that would tie into internal systems, ala AD that could be used in the same way.

      If there’s a situation where the server-side key might be broached, invalidate it and have people download new versions of the affected components.

  15. Richard Liu (@ulyssesric)
    Richard Liu (@ulyssesric) says:

    Actually that’s two problems, bogus 1P mini, and bogus 1P extension. For the second part I’ve no solution except for encryption; malware could even mimic itself as faked browser, and send faked WebSocket request with correct bundle ID. In fact I’d claim it as an EBKAC and ignore that if it’s up to me. But for the first part, I’ve some idea.

    The problem is that extension will send “raw” web form and password to “some process” that occupied specified port. So the solution is quite simple: DON’T send content value of ‘type=password’ field to 1P mini during a save request.

    When 1P mini get the request, it should fetch web content from given URL within 1P mini process, parse HTML, identify the target form, fill the rest field, and ask user to type password again with a modal dialog. This password is directly input into 1P mini, thus eliminate any possibility of IPC hijacking.

    In other word, when users are trying to save login directly from web with 1P extension, they’ll have to re-enter the password again.

    It’s not a perfect solution but I’d accept that, since no one will create new logins so frequently.

  16. edward
    edward says:

    And this is why you should employ two factor on everything important.

    Assuming of course the malicious software can’t get access the the underlying generator identifier

    • Edward
      Edward says:

      If someone steals your password but doesn’t have your decaying key you’re really not in so much trouble.

    • Edward
      Edward says:

      Sorry to clarify. If they grab s one time Passover stay code is good for 30 decided if they have access to the underlying code of the authenticate to replicate the token production

    • Edward
      Edward says:

      I’m a huge fan of how one password has implemented authenticator into their software on both the Apple Watch and how convenient it is to access from with in Safari on iOS

Newer Comments »

Leave a Reply

Want to join the discussion?
Feel free to contribute!

What's on your mind?