node-keytar icon indicating copy to clipboard operation
node-keytar copied to clipboard

why is it secure if i can access it from any apps?

Open jf3096 opened this issue 7 years ago • 31 comments

As long as I install this tools, I can get password or even search password any time I want. How can I ensure the security? Is there any theory or docs I can refer to?

jf3096 avatar Dec 01 '17 21:12 jf3096

You might want to start from here https://developer.apple.com/library/content/documentation/Security/Conceptual/keychainServConcepts/02concepts/concepts.html + this https://github.com/atom/node-keytar/blob/master/src/keytar_mac.cc

vladimiry avatar Dec 08 '17 21:12 vladimiry

I'm still confused by this. I'm using Windows, and have an Electron app. If I build / install my Electron app so it has it's own executable, then save some credentials. Then I have a completely separate Electron app - this can still access the credentials. I don't get it - surely this renders the whole thing pointless? I'm obviously missing something though - so if anyone can help me understand, that would be greatly appreciated :)

dracan avatar Feb 13 '18 13:02 dracan

@dracan keytar is about leveraging the OS for managing credentials associated with your apps, rather than rolling your own credential storage. If you want to isolate your applications credentials from everything else then I'd recommend using something else.

shiftkey avatar Feb 13 '18 22:02 shiftkey

Thanks @shiftkey. I still don't understand what use-case this would have if any old app can access the app's credentials.

"keytar is about leveraging the OS for managing credentials associated with your apps, rather than rolling your own credential storage."

I don't want to roll my own credential storage - and I do want to leverage the OS for managing credentials associated with my app. I just don't want any old app to be able to access those credentials.

Reading some other issues in this repository - it sounds like other apps shouldn't be able to access my credentials - but when testing this doesn't seem to be the case.

dracan avatar Feb 14 '18 09:02 dracan

@dracan

I just don't want any old app to be able to access those credentials.

The credential stores in the OS haven't been designed with that in mind (at least for macOS and Windows, I'm not that familiar with libsecret) - they let the user view and edit the credentials associated with their account arbitrarily.

Think of keytar as an interface on top of that.

shiftkey avatar Feb 14 '18 09:02 shiftkey

@shiftkey Ah I see - so it's a user-level thing, rather than an app-level thing. Okay - thank you for your help and quick replies :)

dracan avatar Feb 14 '18 09:02 dracan

Hi @shiftkey. Sorry to pester you again :) But If this is at a user-level, not an app-level - then I can't think of any use-case that this could possibly fulfil? What's this library for then? Also, looking at some of the other issues (eg. #50, and a few others) - it seems like other people also assume that this is for app-level credentials too. Then there's blog post like this, which also seem to think the same thing. I'm just a bit confused, as there's seems to be a lot of misunderstanding around this library.

dracan avatar Feb 14 '18 14:02 dracan

I'm just a bit confused, as there's seems to be a lot of misunderstanding around this library.

@dracan it's clearly described in readme that this module interacts with the system's keychain. So before using it, the next step would be to figure out what is the system keychain in order to determine how it's suitable for your needs.

vladimiry avatar Feb 14 '18 14:02 vladimiry

@vladimiry Understood. However, as it's clear that I'm not the only one confused by this - and people are most likely using this library blindly, and haven't gone to the effort that I did of creating another Electron app to test that the other app can't access the credentials - then I would strongly recommend updating the readme with a brief explanation of when this library should and shouldn't be used. Otherwise, it's doing more harm than good. I came to this library from the above-mentioned blog post - so I perhaps wrongly assumed what the library did from the get-go. I'm clearly not the only one though.

dracan avatar Feb 14 '18 14:02 dracan

I agree here with @dracan -- a short explanation would be nice on how each of these systems store credentials, how they're encrypted, and what the access control is like for retrieving credentials. If not that, maybe at least links to read about that.

Unfortunately, the Windows Credential Manager is sort of a joke in terms of security but it seems to be what is recommended for apps to use.

ccnokes avatar Feb 20 '18 18:02 ccnokes

So if this isn't the solution to secure passwords and privateKeys, etc, what is a better option?

kinoli avatar Mar 04 '18 01:03 kinoli

@dracan aside from the issue you have raised, in your Electron app js code, if you have keytar.addPassword('KeytarTest', 'AccountName', 'secret');; It is still not secure because one can unobfusticate your code to get to those values.

6zz avatar May 31 '18 17:05 6zz

@6zz Yep, the secret isn't a literal string stored in code though. It's something the user enters in the UI.

dracan avatar Jun 01 '18 05:06 dracan

Since macOS is asking for the keychain password this concept seems to be fine for me. What really bothers me is that window does not - would it be possible to add the prompt on windows as well?

DEDaniel avatar Jun 14 '18 05:06 DEDaniel

I don't know the technical details, but I don't see how an additional prompt could be anything but a security theater - any DPAPI-using app can access the secret store, so requiring an extra prompt (like Chrome does) would probably only serve to deter people attempting to steal passwords by hand, it won't prevent from other applications being able to snoop on the stored passwords in any way.

I think the only way to programatically protect from apps seeing other apps' passwords would be to use DPAPI and then have additional app-specific password to encrypt/decrypt would goes in and out of DPAPI, but then again you need to also think about other apps accessing your apps' memory space, so you would probably have to use SecureString throughout to minimize the risk, but this again falls short of sending the credential over the network anyway, because any app can do like Fiddler does and unpack that traffic to get the password.

The only real protection here would be to run your app underneath a different user account I think - so a different logon password and then different DPAPI derived key. (I obviously don't advocate for this, I say this to illustrate that these logon-password based frameworks are designed not to protect from other apps of the same user but from other users/HW tampering).

TomasHubelbauer avatar Jun 14 '18 08:06 TomasHubelbauer

Given recent widespread compromises via transitive dependencies within the npm ecosystem, the fact that when this is used in a Node process to store secrets any other Node process can trivially access those secrets is something that should be deeply troubling to project owners.

From the perspective of a malicious actor distributing code through npm, these credentials may as well be stored in plain text on the user's desktop. The only difference is that when a user stores their passwords in plain text on the desktop, they do not assume that data is secure.

If for some reason this isn't a concern in your view, there should a huge neon banner at the top of this project README that explains your envisioned use-case for this utility and the security risks incurred by off-label use. Because right now the delta between how this utility behaves and what users expect is potentially pretty dangerous territory.

esimons avatar Nov 30 '18 15:11 esimons

The credential stores in the OS haven't been designed with that in mind (at least for macOS and Windows, I'm not that familiar with libsecret)

Actually, on macOS you can control which apps have access to a particular keychain item. It's all in the official docs:

When an app attempts to access a keychain item for a particular purpose—like using a private key to sign a document—the system looks for an entry in the item’s ACL containing the operation. If there’s no entry that lists the operation, then the system denies access and it’s up to the calling app to try something else or to notify the user.

stanmots avatar Mar 15 '19 22:03 stanmots

Given recent widespread compromises via transitive dependencies within the npm ecosystem, the fact that when this is used in a Node process to store secrets any other Node process can trivially access those secrets is something that should be deeply troubling to project owners.

From the perspective of a malicious actor distributing code through npm, these credentials may as well be stored in plain text on the user's desktop. The only difference is that when a user stores their passwords in plain text on the desktop, they do not assume that data is secure.

If for some reason this isn't a concern in your view, there should a huge neon banner at the top of this project README that explains your envisioned use-case for this utility and the security risks incurred by off-label use. Because right now the delta between how this utility behaves and what users expect is potentially pretty dangerous territory.

https://chromium.googlesource.com/chromium/src/+/master/docs/security/faq.md#Why-arent-physically_local-attacks-in-Chromes-threat-model explains why Chrome don't care about your concerns. Password encryption is to protect against other users accessing your data.

nerd2 avatar Sep 18 '19 08:09 nerd2

I've made changes to src/keytar_mac.cc to remove Node as a trusted app as soon as the password is added . You can find the link here. The issue at this point is that there is no easy way to search using both the credential and account name .So if you have multiple accounts, doing a find using credentials means typing in the keychain password as many times.

icemanreddy avatar Apr 11 '20 07:04 icemanreddy

@shiftkey As @stanmots posted, the macOS Keychain does have the API to limit credential access to the app that created the credential. Do you think Keytar can leverage this API?

msafi avatar May 18 '20 20:05 msafi

I've read it all but I am still confused. Can someone make a conclusion, please?

ftzi avatar Jun 06 '20 23:06 ftzi

Echoing @kinoli: So if this isn't the solution to secure passwords and privateKeys, etc, what is a better option?

Could the README be modified to explicitly state what can and cannot access these secrets? Possible use-cases too?

CatalanCabbage avatar Jun 12 '20 12:06 CatalanCabbage

@nerd2 this issue is not about physically-local attacks in general like the FAQ from chromium explains. The point is that any app that has access to the keychain can read all credentials. So the computer does not need to be hacked, a completely valid installation of any app can just read your credentials and do whatever with it. Restricting those credentials to app level (as chrome/chromium just has by design) would solve that problem.

ThomasStubbe avatar Jun 22 '20 11:06 ThomasStubbe

I've read it all but I am still confused. Can someone make a conclusion, please?

This library is just an interface for your OS credentials manager, and that's it. People are concerned that other installed apps can also access this information, which is frankly out of scope (again this library is only a keychain interface).

Here's some interesting reads on why defending against local attacks is not very effective:

  • https://chromium.googlesource.com/chromium/src/+/master/docs/security/faq.md#Why-arent-physically_local-attacks-in-Chromes-threat-model
  • https://web.archive.org/web/20160311224620/https://technet.microsoft.com/en-us/library/hh278941.aspx (Law 1)

Q: What if I want more security?

If you want more security, you can :

  • Create a credentials file
  • Ask your users for a master password and encrypt this file with it
  • Ask your users for the password each time the app starts (to decrypt the credentials file)

This is roughly the flow that password managers, wallets and browsers use to store secrets.

If that's too complicated, you can use localStorage - It's not as robust as the solution above, but least other installed apps won't be able to access the credentials directly.

That being said, if you have malware in your computer (e.g: a compromised dependency)... nothing would stop this malware from from recording your keystrokes, sending your files to a remote server, etc. The key is to only install trustworthy software/packages and keep any dependencies up to date.

hodgef avatar Jul 17 '20 00:07 hodgef

I may be mistaken, but the issue isn't that ANY other app can access a password created with this... but instead that ANY node process can?

At least on OSX, I know you get prompted when trying to access a keychain item for the first time.

When you package the electron app, does that make the prompt specific to the app itself, or does it remain as the generic "node" process?

ChuckJonas avatar Sep 19 '20 06:09 ChuckJonas

I feel like the readme should include a note about how Keytar is not secure. I feel like many users will be assume that it's secure just because it uses the keychain, however infact it's less secure than using localStorage, as mentioned by hodgef.

foxt avatar Sep 06 '21 19:09 foxt

If I understand Chrome's implementation correctly, on most OSs they only store an encryption key in the OS's password store which is then used to encrypt/decrypt a Chrome password file. This seems to have been done just for technical reasons but has the added advantage that if malware is designed to steal all a user's passwords from the OS store and send them to the attacker, they only end up with a useless Chrome encryption key but not the password's file.

If that's correct, it's probably worth considering that Chrome (which probably stores way more sensitive passwords than Electron app xyz) uses an approach similar to this module. And it's also probably worth following their approach and only storing a single encryption key using this module in case a malicious app does decide to steal the whole contents of the OS password store.

That would then at least limit the risk to malware that is directly designed to attack your app, rather than any general one that just steals the password store (or alternatively steals the user's config dir but not the password store).

shadow-light avatar Oct 09 '21 00:10 shadow-light

What about using Electron's safeStorage module.

According to the description:

This module protects data stored on disk from being accessed by other applications or users with full disk access.

Needless to say, I would avoid relying on any solution that stores a secret on the client side. But if you absolutely must, this could be a better solution.

ncortines avatar Sep 15 '22 16:09 ncortines

@ncortines How exactly would an app authenticate with a server without 1) storing the auth token client-side or 2) prompting for username+password at startup/on each request? Keeping in mind the latter option is a very poor UX.

nathan815 avatar Oct 31 '22 05:10 nathan815

however infact it's less secure than using localStorage, as mentioned by hodgef.

No. Granted I did this check a few years ago so things could have changed but Chromium stores localStorage data to disk unencrypted and any other app could open it and read its contents. Just use safeStorage now.

ccnokes avatar Nov 17 '22 00:11 ccnokes