How to securely store password in local storage - javascript

I realize that there are other posts on Stack Overflow asking similar questions, and the answer is to NOT to store passwords in local storage, but I need to. If there is a better approach, please let me know.
I am building a password manager. I am trying to develop it to work mostly offline. The way it works is that the user stores their "vault" on my golang web server. The server is only ever accessed when the client or server needs to be updated. So: the user logs in, the vault is sent from the webserver to the client, each time a password entry (username, password, name, etc) is created, each aspect of the entry is encrypted using the user's "master password". Since I would like the webapp to be able to work offline, I need to store some version of this master password in local storage or as a cookie (preferably as a cookie). I would like it to work similarly to other password managers, so if anyone can provide some insight on how they approach this problem, please do.
What is the best way for me to store the master password locally? I would like my approach to be as secure as possible. If there is a different approach I can take, I would love to know. My main thing is that I need the webapp to be able to work offline.
Please note that I am not using node. If I can provide any additional information, please ask.
Thank you!

The best way is to (as everyone is saying) NOT save data locally. That is a huge security issue. Other thing is that a Website can not be offline (unless its a PWA), so running the website offline is never gonna happen (Unless you create a PWA).
My Suggestion is that if you want to make it work offline you can create Chrome extension and use chrome.storage API for storing Encrypted password ( storing plain password is not recommended ). Even with web extension, it is not advisable to store password locally.
You can make it work offline if user is logged in and but not connected to internet anymore and browser is still running. Every time user open browser after closing it, you should (always) authenticate user again.
1). Since you are encrypting vault using plain master password, you can use any encryption/decryption method to encrypt master password ( which will be stored using api ) and to decrypt the stored encrypted password ( decryption is required as you will need plain master password for verification ).
Hashing algorithm is not a good option here, since hashing is one way encryption and depending on which algorithm you use you can have different hashes for same string.
2). Yes, you can check storage.local browser compatibility here

Electron can help you to develop what you want. With Electron you can develop offline app's to any S.O.
And you only need to know about HTML, JavaScript and CSS.
Take a look at official website
Today a lot of apps are made using Electron, like VS Code, Slack and a bunch more, look at this link: App in Electron
And if you really want to test, do a simple app following this Tutorial.
To store your password locally you can do a encrypted key and concatenate the machine info to make part of the password.
For example:
You can get programmatically machine MAC Address +
And do a simple and less secure MD5 encryption, and you will get something like this: e99cde2308fb2ff5612f801c76b18f6c
In the world exists a lot of encryption manners.
Good luck.

Related

How to use Web Crypto API (or something similar) just to store data that can't be easily transferred?

My requirement is to store UUID-like on client's web browser to identify user's machine (web browser copy in this case). Let's say, if IT guy comes to fix a laptop of HR manager, they could easily view username/password saved in web browser and use that credential on his PC later. My idea is to simply save an UUID in web browser's local storage and send it to verify at backend server. If username or password or UUID does not match, deny access. The problem is local storage can be viewed and re-created by IT guy easily.
After Google, I believe that Web Cryto API is the way to go. It can be used to store encrypted object in IndexedDB with extracable = false, but can read via JavaScript, I hope. Unfortunately, most of online article are talking about encrypting/decrypting data which is too much for me. I just want to store data that can't be transferred to another machine easily, but can read with JavaScript. That's it.
Can anyone provide sample code or blog post to achieve this? Thank you.
PS 1) I know about web browser fingerprint concept, but it's not a solution since fingerprint value keeps changing from time to time.
PS 2) My JavaScript on production environment will be obfuscated and/or webpacked and/or made-confused by my own algorithm. Yes, it can be reverted-engineering by webapp developer, but not by most of users in the organization, I think.

Electron SQL security

I have a rather noob question that I can't seem to find the answer for. So I've heard that all electron apps can be turned into source code and then manipulated. So that leads me to my next question. If I'm connecting to a SQL database then what is keeping people from viewing source code, going in and doing whatever they want to the db? I mean once they see the source code the username and password are right there...Sorry if this is a silly question but I'm thinking of making something on electron that needs decent security. I've also heard php cannot be used. So... Any suggestions would be appreciated. I'm just wondering because Discord, whatsapp and such seem to do it somehow, but how?
Thanks!
Well, any information in any application can be reverse engineered, so I would suggest to not hardcode database passwords or any other critical credentials.
I assume Slack, Discord and others don't hardcode their DB passwords in app. Their desktop app don't "talk" directly to database, it's talking with some server-side application. You as a user have to provide credentials to your account. Communication is done through API which implies various restrictions based on your user privileges. This server-side application decides what you can and what you cannot do and translates your requests into DB operations.
So using those apps you don't go even near to their DB passwords.
If you want to do client application which should be able to do some operations on DB, I would suggest the same, split this application into two parts: ClientApp and ServerApp.

Security flaws of keeping sensitive information inside javascript code

Everybody knows that you shouldn't keep sensitiveInfo variable at your js code. The better way is to put it inside local storage. Could you pls explain vulnerabilities of the first approach with help of my example?
Example:
You use bundler, which bundle all your js files together. sensitiveInfo isn't global, but stored inside YourStorage.js. To access file which keeps it you do:
import YourStorage from 'somepath/YourStorage';
YourStorage.sensitiveInfo = newValue; // QUESTION: can you steal this value? Is it accessible from console?
Questions:
Is sensitiveInfo variable accessible from console?
Could you please describe mechanism how someone can steal sensitiveInfo?
If someone can steal it from my code, why he couldn't from local storage?
UPDATE: (whom I'm trying to protect from?) I'm writing mobile web app, where users can spend real money. I want to protect them from all kinds of attack where they can loose their money (i.e. locally installed viruses)
Anything put in javaScript that is downloadable can be easily seen on the users device. The most common method of securing sensitive information that must be passed back and forth to a client is to:
First, use SSL to encrypt the information over the 'wire'.
Second, if the data is of a very sensitive nature - such as a token used to process credit card information (do not store the card number in this token!) - that data should be encrypted itself, using a seed/key that is securely stored on the application server.
Often you would write the application to require both the identify of the user AND the device be verified. After this verification, you would then decrypt the token - using a key stored only on, and only available from, the server-side of your application.
Using this practice you can reasonably assume the user and device are whom they say there are. Of course, such applications need proper authentication themselves - with said credentials not being stored on the device - to prevent stolen devices from easily being used to access the application account/data. Do not simply rely on a devices screen lock for security.

How to store a password as securely in Chrome Extension?

I'm writing an Chrome extension right now which autofills credentials similar to Chrome's autofill (in which case Chrome's autofill fails).
Is there a secure way to store the username/password in localstorage (all client-side)? If I encrypt the password, won't the key be locally stored as well effectively making the encryption useless?
Effectively, I want the user's credentials to be as secure as they would be if Chrome itself was storing the credentials in its password manager.
EDIT: is storing the encrypted password in localstorage and the key in a text file within the extension directory a safe idea?
This is a lightning-rod issue. See http://blog.elliottkember.com/chromes-insane-password-security-strategy for more. The position most consistent with Chrome's would be to encourage your users to use whole-disk encryption and to lock their screen when away from a logged-in machine. It's difficult for userland code like an extension (or a browser, for that matter) to properly implement secure storage, where "properly" means "resistant to a password-recovery utility that anyone can download from the internet."
You should file a feature request. It might be possible to expose a system-level API that does provide similar security to the underlying OS's keychain.
If I encrypt the password, won't the key be locally stored as well effectively making the encryption useless?
Yes, it would and yes, all client-side "encryption" is visible to the user or anyone who has access to the machine and therefore pretty much useless. Except perhaps for the purpose of obfuscation -- anyone with a copy of your hard drive won't immediately be able to tell the password in plain text. This may or may not be an advantage, f.ex. if using device-specific data to generate a key for encryption such as hardware UIDs, someone who gets the encrypted data won't be able to decode it right away without knowing the UID. Generally though you'd assume someone with access to the "encrypted" password would also have access to the machine in some way so all in all, again, user-side encryption doesn't really make a lot of sense when performed in the browser.
As far as i know, local storage is not a secure place for storing the password, or other sensitive details. Check out the link below, one of the person has commented of using the javascript 64 bit encoding and deocding scheme but i dont how far that method will prove to be useful for what you are trying to achieve.
https://getsatisfaction.com/apperyio/topics/how_to_save_account_password_securely_on_local_storage
Hope this helps!

User authentication in offline web apps

I'm building a web app that needs to work offline. The system is built to capture sales transactions. The bulk of the "offline" part is fairly straightforward -- I just need to store data locally and sync it when I'm back on the network. So far, so good.
The problem is with authentication. The app will run on a shared machine with a single OS user account. If I'm offline, how do I authenticate the user?
Users themselves do not have any private data that I will need to segregate (i.e., I don't have to protect them from each other on the client). I need to be able to validate their password so I can let different users login throughout the day even if the connection is down.
One approach I'm thinking of involves caching the password hashes on the client-side in an IndexedDB. Only a limited set of users will be allowed to log in from a specific shared machine, so I won't need to cache my whole password database locally. Assuming that I have a good password policy (complexity and expiry requirements) in place and the hashes themselves are secure (bcrypt), just how horrible of an idea is this?
Do I have any other options?
This is effectively how Windows (and other systems) work when the machine is not able to reach the domain controller (e.g., you take your work laptop onto the airplane and need to log into your laptop w/o connectivity). Your machine has written down a cache of your username|password pair and will let you in via those credentials even if it's offline.
I think generally speaking storing the username|password hashes is pretty safe, assuming you're hashing them reasonably (e.g., using a salt, using an IV, etc). One exposure you'll want to think through is having the hash file "escape." If this is sensitive data you'll want to be exceedingly careful -- and this may not even be acceptable, but if it's not super sensitive data then you're probably OK: with good hashing I think you should be reasonably (but certainly not completely) safe.
Maybe this is little unrelated, but I use this approach in my nodejs project.
When a user is authenticated by username and password, he/she is assigned a unique API key used only for this particular session.
Each user can have only one API key.
This API key is added to any request done to server, to authenticate the user.
When the user logs out, the API key is deleted. Also the API key can be purged on the server, that makes the user authenticate on the server one more time.
I can provide links to nodejs open source programs that use this approach if you interested.

Categories

Resources