blacs30 / bitwarden-alfred-workflow

Simple Bitwarden Workflow for Alfred
MIT License
447 stars 32 forks source link

Feature Request: Bio unlock with PIN fallback #72

Open timcappalli opened 3 years ago

timcappalli commented 3 years ago

Hi - would it be possible to add biometric unlock (Touch ID) with a fallback to PIN, similar to how Bitwarden mobile apps work? It can then require master password after new OS logins.

blacs30 commented 3 years ago

I like this idea. However I’m lacking a Mac with that capability to test, still using an older model. Therefore I think it might be not implemented in the near future.

M-Whitaker commented 2 years ago

Hi, I also love the idea of this as I'm a bit wary putting my password in once and then leaving my vault open all the time. However on the other hand having to enter my long password in all the time (after the timeout) is a headache when I want to use it. I'm not too well versed in go however have used apple's touchID authentication before (LocalAuthentication/LocalAuthention.h) however the only way to call this I can see is though an NSApplication so the bitwarden-auth-flow.js would need porting to an NSApplication from my research. I'd love to help with this if you have any preferred way that it's implemented (i.e when you want to use LocalAuthentication vs authenticating with bw) I will have a go and submit a pull request.

blacs30 commented 2 years ago

@M-Whitaker I'd appreciate your contribution. Do it the way you feel is comfortable for you and secure. I could imagine another "bio-unlock" keyword in the workflow which can execute a separate script might be easier than integrating it into the go code. I'm not sure how the implementation would look like though. Isn't it typically used for logging in to the mac? Can it store other passwords? It seems the bw cli doesn't support touchId, only the Bitwarden desktop app. I might be wrong though. Curious to hear more.

M-Whitaker commented 2 years ago

So, local auth, although can be used to access the keychain can literally have no connection to bw at all. It is you authenticating on your local computer basically to get past an if(authenticated) statement (which is why you have to put your password into Bitwarden first). This basically means you keep the authentication saved from Bitwarden how you do currently and just use local auth if people want to have extra security when the vault times out. In terms of how Bitwarden desktop does it so you can always use Touch ID I suppose they store the Bitwarden password in keychain and access it thought Touch ID however given this is third party I there are security questions to be had with keeping your Bitwarden password in a keychain associated with a third party application as it gives us full control over the password in non volatile storage.

In terms of the way this works with scripts, it seems that you have to create a Cocoa Signed Binary in order for the windowing system to work etc. The way I have it currently is a small ObjC cocoa app with one window laid out much the same as your apple script just using ObjC rather than JS.

Hope this helps paint a picture of how it works. The main takeaway is the call for auth needs to be done in a cocoa application and the authentication is fully local so there is no storing of secrets(above what you do currently)

safakgur commented 2 years ago

I'm not sure how the implementation would look like though. Isn't it typically used for logging in to the mac? Can it store other passwords? It seems the bw cli doesn't support touchId, only the Bitwarden desktop app. I might be wrong though. Curious to hear more.

I too expected the APIs used to prompt for bio auth to provide more granularity (more specifically, I expected to be able to retrieve a hash that represents the finger) but turns out we only get a true or false for the question "does the fingerprint match with one of the prints registered in the settings?", and that's all.

Which kinda makes sense considering apps already have access to Keychain and the OS guarantees that no other app can access our app's items in it (at least unless we want to). This means (though I can be wrong), it should be safe to store the user's email and master password (or client ID and secret) in Keychain, and use those values to log them in automatically on successful bio auth.

When it comes to the user experience, I'd love if I didn't have to call an unlock workflow manually for accessing my items. It would be amazing if I get the prompt automatically when I hit space after .bw, so if the workflow is unlocked, I'd just see my items as usual and if it's locked, I'd get a prompt, touch the sensor, and continue typing my item's name to search.

For the check itself, I found a very simple Go package that prompts for Touch ID: lox/go-touchid. It seems to do what it says on the tin (tried it on my machine) - here's the README:

Authenticating with TouchID

package main

import (
  "log"

  touchid "github.com/lox/go-touchid"
)

func main() {
  ok, err := touchid.Authenticate("access llamas")
  if err != nil {
    log.Fatal(err)
  }

  if ok {
    log.Printf("Authenticated")
  } else {
    log.Fatal("Failed to authenticate")
  }
}

Screenshot

I can't contribute more as I have zero experience in Go (I only installed the SDK today to check how that Touch ID package works) and also no experience in writing Alfred workflows. But I do own a MacBook with Touch ID and I'd be more than happy to test what you implement.

blacs30 commented 2 years ago

Thanks for your input and user experience expectation. Sounds like a nice thing to do. For a while now I also have a Mac with touch sensor, though I've not used it yet.

The idea of it sounds good. I would need to dig more into this part

Which kinda makes sense considering apps already have access to Keychain and the OS guarantees that no other app can access our app's items in it (at least unless we want to). This means (though I can be wrong), it should be safe to store the user's email and master password (or client ID and secret) in Keychain, and use those values to log them in automatically on successful bio auth.

It seems like a weakness to me save the master password and email next to each other.

Currently

safakgur commented 2 years ago

It seems like a weakness to me save the master password and email next to each other.

I understand; that's why I originally expected the Touch ID API to return a hash-like value that’s unique to the fingerprint. I was hoping we could encrypt the master password (or client secret) with a key derived from it, so the password would never be stored on the disk unencrypted. We would read the encrypted password at the time of touch, unencrypt it in memory, run login/unlock to get the session key and save only the session key to Keychain (so the unencrypted password is never persisted).

But after I read more about Keychain and Touch ID, I now think that might’ve been a bit overkill as Keychain seems to be safe enough to contain the password as-is, and the Touch ID API seems only to return a yes or no.

Anyway, I'm sure you'll come up with a solution that's both safe and convenient when you find some time to dig deeper, and thanks for the greatest Alfred workflow!

M-Whitaker commented 2 years ago

It seems like a weakness to me save the master password and email next to each other.

I understand; that's why I originally expected the Touch ID API to return a hash-like value that’s unique to the fingerprint. I was hoping we could encrypt the master password (or client secret) with a key derived from it, so the password would never be stored on the disk unencrypted. We would read the encrypted password at the time of touch, unencrypt it in memory, run login/unlock to get the session key and save only the session key to Keychain (so the unencrypted password is never persisted).

But after I read more about Keychain and Touch ID, I now think that might’ve been a bit overkill as Keychain seems to be safe enough to contain the password as-is, and the Touch ID API seems only to return a yes or no.

Anyway, I'm sure you'll come up with a solution that's both safe and convenient when you find some time to dig deeper, and thanks for the greatest Alfred workflow!

This was my takeaway, unfortunately, I didn't have much time to work on it but I built a simple go wrapper using GoC and this all worked in principle so you can just code in objC as you would a coca application using keychain.