Skip to content
This repository has been archived by the owner on Jun 4, 2018. It is now read-only.

Feedback - Security concerns #12

Open
faejr opened this issue Sep 20, 2017 · 32 comments
Open

Feedback - Security concerns #12

faejr opened this issue Sep 20, 2017 · 32 comments

Comments

@faejr
Copy link

faejr commented Sep 20, 2017

After having gone through several password managers, looking through sources to see if anything is feasible I came across this application that quite frankly is the most insecure out of all the bunch I have seen.

You should never send a plain text passwords over the internet as you are currently and all encryption and decryption of passwords should happen on the client-side, where the server should not have any knowledge of the master password as this completely breaks the security. You're not safe from this issue simply because you're using HTTPS as that could still easily be compromised.

Encrypt function example /src/PASSY/Passwords.php Line #41

Contains a regular post form: /page/page_password_list.inc.php

Therefor no one who cares about there passwords should be using this, and if they do, or have, they should consider all their passwords leaked and change them immediately.

The simplest way to store passwords in this scenario would be:

  1. Client encrypts password with their master key (possibly even username/url/etc as to not leak any information)
  2. Client sends encrypted data to server
  3. Server encrypts clients data with their own secret key
  4. Server stores data in database

For retrieving passwords you do the same in reverse

  1. Client requests passwords
  2. Server decrypts password with own secret
  3. Server sends clients encrypted data to client
  4. Client decrypts using master key locally

For encryption and decryption on the client side this library is a good start:
https://github.com/ricmoo/aes-js

The use of AES256 is definitely encouraged as you're currently using an un-auditied encryption library that could be very unsafe and may not have a JS implementation.


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

@liz3
Copy link
Member

liz3 commented Sep 20, 2017

First: Are you kidding, client side encryption could easily be forbidden etc.
Second: I made a version where the Password is not saved into database.
third: tell me how to access the session by remote?

A master key should be safer on the client side?????? LOL
Regards
Liz3

@codecat
Copy link

codecat commented Sep 20, 2017

Yes, of course. You don't want to transfer any such data over the network, even if the data is encrypted. Anyone who is in control of your webserver will be in control of all of your passwords if you log in. You can avoid this by performing all the crypto on the client.

@liz3
Copy link
Member

liz3 commented Sep 20, 2017

The client side on a website can be manipulated in any ways....

@Scrumplex
Copy link
Collaborator

Scrumplex commented Sep 20, 2017

If TLS is broken, you have more serious problems than someone capturing traffic from / to a password manager.

@codecat
Copy link

codecat commented Sep 20, 2017

@liz3 So? It's a password manager. I'm not sure what kind of "manipulation" you're talking about that would make it insecure.

Look at it this way; what do you trust more, the device you are physically touching, or the server that is likely unsupervised by human means?

@Scrumplex Sure, if your webserver is compromised you do have a lot of problems. But I'd argue that as a result of that, compromising your entire password database is kind of a bigger problem.

@Scrumplex Scrumplex changed the title Feedback - This password manager is unsafe Feedback - Security concerns Sep 20, 2017
@faejr
Copy link
Author

faejr commented Sep 20, 2017

As @codecat stated you should trust your own device more than a server. Prefer local and offline over online. At the current state of this project it prefers online over offline, which is not ideal for something as confidential as a password. If you would run this in your own local intranet and never access it outside of this scope, then sure it could most definitely work out fine. But if you're expecting to use it anywhere such as on a public wifi, at your friends house etc. Then you're extremely likely to be leaking your passwords everywhere unfortunately.

Thanks for changing the title by the way, I did not intend to come of harsh, merely voice concern.

@liz3
Copy link
Member

liz3 commented Sep 20, 2017

in a open wifi over https, right? Leaking passwords everywhere.

I get it, but please tell me exactly how will you encrypt the masterpassword(On the client side) on a login try and save this in the browser

@liz3
Copy link
Member

liz3 commented Sep 20, 2017

If the wifi is behind some kind of http proxy, the open wifi could easily capture the js files and guess how the pasword has been encrypted, to decrypt it and perform a easy login

@codecat
Copy link

codecat commented Sep 20, 2017

You're right, if you are transferring passwords over the network in encrypted streams (TLS), that's not the root of the security concern here. The real concern is that if someone has access to your webserver/php files, they can easily sniff out your data outside of the streams. In which case, you can't trust the server.

If you're in a state where you can fully trust the server (eg. in a local business network if the machine is not connected to the internet for example), this configuration is probably fine.

Concerning the masterpassword, you don't need to know the password if you have compromised the webserver, since you can just sniff it out from the data the client sends.

(Also, an open unsecured wifi you still wouldn't be able to sniff data if the traffic is sent over a secure encrypted socket [with a trusted certificate], but that is not relevant for these concerns.)

@faejr
Copy link
Author

faejr commented Sep 20, 2017

It was merely an example that everything will be leaked, whereas nothing other than encrypted data should be leaked even then.

It's not about the attacker finding out HOW it is encrypted, that's easy to figure out and should preferably be public data so the user of a password manager are aware of which technologies are in use.

Just because I know HOW it is encrypted, doesn't mean that I know your master password, which would be required to successfully decrypt the data that I happened to catch from you.

So the scenario would be that I would need to brute-force the data putting a great deal of strain and taking time that could possibly result in no result for the attacker.

Keepass is open source and we all know how their database is encrypted, however we do not know any of the users master passwords or have their key, hence I can't just decrypt a random database that I found on the street.

As @codecat mentioned the attacker can't get the password through a request seeing as you don't send the key, and only enter it locally for encryption and decryption of data, not to send it to an external party.

@codecat
Copy link

codecat commented Sep 20, 2017

As a short conclusion, for this to be a truly secure password manager, you need:

  • The server to never be aware of the master password.
  • The server should never be able to decrypt your passwords.

There's a few other concerns here too besides just a compromised webserver, take for example the old Heartbleed bug, which dumped random memory to clients. What if someone's master password is still in memory? Or their passwords?

@liz3
Copy link
Member

liz3 commented Sep 20, 2017

Yeah i get it, but again, how exactly would you generate the server side key and client side key, how is the server going to check the data encrypted with it?

@liz3
Copy link
Member

liz3 commented Sep 20, 2017

Though i made the first step by at least not saving the masterpass in db see branch alternative login

@faejr
Copy link
Author

faejr commented Sep 20, 2017

The server key (as in the servers key to encrypt/decrypt the clients data) could be any key you would generate for your particular instance of passy. Every instance should of course have their own and it should not be saved in GitHub as that would be a security issue.

As for the clients key that would be entirely created by the client and only available to the client and the server should have no idea what it could be.

The client sends encrypted data to server, the server encrypts that data and saves in the database.
Upon request the server will then decrypt the requested data and send the clients encrypted data to the client.

In the end this would mean that the server have no idea what data it received or what it could possibly mean, other than it was created by the client.

I suggest reading up on this article to learn more: https://en.wikipedia.org/wiki/Public-key_cryptography

@Scrumplex
Copy link
Collaborator

Scrumplex commented Sep 20, 2017

I can understand @LiljebergXYZ`s concerns about the security of PASSY. PASSY is a password manager intended to be used on trusted servers. You can easily set PASSY up on a Raspberry Pi, where the webserver is bound to your local network and uses a TLS certificate, signed by your own CA. This password manager just has a different approach than most other managers: Convenience.
You can use the password manager from your phone or any other connected device, without syncing password databases across devices.
You can't have Security at 10/10 while having Convenience at 10/10. You need to balance between convenience and security. I like to have convenience. Security gets important, if there is a third party. But me using PASSY on my own server, which is monitored with a software firewall, uses port knocking and allows SSH from just one IP. I trust myself and my skill to secure my server and use https://app.passy.pw.
The price, one pays for convenience, is security.

@codecat
Copy link

codecat commented Sep 20, 2017

You might feel like your self-housed server is super secure, up until the point when an exploit like Heartbleed suddenly gets released into the public.. :)

I think Lastpass is doing a good compromise of convenience and security. (They've had some security issues in the past, but they still have a shared encrypted convenient password container.) It's not impossible.

I'd also argue that if you only use this in a local network you're essentially nullifying the convenience since you won't be able to use it when you're on the road. (Your readme also says this is a password manager to "to serve you over the internet", so that kinda goes against your own brand, imo.)

@liz3
Copy link
Member

liz3 commented Sep 20, 2017

OMG slowly its annoying me, a am pretty sure, the version of openSSL the server is running, does not have the heartbleed issue, buffer overflow is getting much rarer, due to random addressing etc.

For the last time i am ASKING, how will the server verify the login without knowing what data it has?

@Scrumplex
Copy link
Collaborator

@codecat I once hosted something similar to PASSY on my raspberrypi and used a VPN to connect to my home network. Was still pretty convenient.

@Scrumplex
Copy link
Collaborator

Scrumplex commented Sep 20, 2017

@codecat @LiljebergXYZ We just have different security concerns. I think that a client device is unsafe (OS exploits, malware, spyware). You both think, that a server is unsafe (OpenSSL exploits, bad protection against threads, ...). There are / were way more security issues with client devices than with OpenSSL.

@codecat
Copy link

codecat commented Sep 20, 2017

@liz3 Check out the link that @LiljebergXYZ pasted.

@Scrumplex If you're fine with using this security model, I'm not stopping you. These concerns are still valid concerns however.

I am curious why you think a client device is unsafe when it comes to a password manager though?

@Scrumplex
Copy link
Collaborator

@codecat just edited the above post. :D

@codecat
Copy link

codecat commented Sep 20, 2017

I'm not sure how your server-side encryption model helps against clientside malware such as keyloggers/etc.

@Scrumplex
Copy link
Collaborator

@codecat
@liz3 does not understand, how to authenticate a user with your suggestion.

@Scrumplex
Copy link
Collaborator

@codecat client side also does not protect against malware and keyloggers etc.

@codecat
Copy link

codecat commented Sep 20, 2017

No, but it does protect against all the other things I mentioned which are also equally as common.

@faejr
Copy link
Author

faejr commented Sep 20, 2017

@liz3 The way 1Password has solved authentication (and me personally in my own project) is by using a secondary account key. So you have regular username/password authentication and then the user also has to enter their master password in order to decrypt the blob they were able to retrieve through their username/password combination. Another option (although I doubt it would be secure) would be to encrypt the username (or a random string such as "success") with the master password so you're able to check those blobs against each other for authentication. It's not the most safe, but it would easily work for authentication.

@Scrumplex The issue is that currently you have 2 points of failure (where in this case you would like to have as few as possible) by having it easily available on the server and client, where you could lower it to a single point of failure by only having the client be aware of the master password for decryption. Should the client have a key logger or malware, then all is lost either way.

@Scrumplex
Copy link
Collaborator

@LiljebergXYZ I would say nothing against making PASSY more secure. I just don't know how I should migrate anything from the current system to a new one with client side crypto. I build PASSY as backwards compatible as possible.

@svenmasuhr
Copy link

svenmasuhr commented Sep 23, 2017

@Scrumplex At some point backwards compatibility is no longer possible. Even popular web/self-hosted applications need to cut this compatibility line sometime.

Like @LiljebergXYZ mentioned a Client-Side encryption would be a better idea to secure PASSY, because the way how it currently works is quite strange in terms of security, and talking about "what if the client has a virus?" is not an excuse for saying "how it currently works is fine", because there is still a major difference that the Server should not know anything about the users password.

As an alternative to backwards compatibility, what about a migration utility to move Passwords from the "old PASSY" then to the "newer one"?

@liz3
Copy link
Member

liz3 commented Sep 28, 2017

You can import/export passwords easy

@Lawri-van-Buel
Copy link

Applying Security in depth to something like a password manager would mean that you employ different techniques to minimize the risk.

  • NEVER EVER run a Password Manager on a machine you do not Own / control fully (e.a. you have physical access to the machine and you know who else!)
  • You should allow the use of a HSM or SMARTCARD for storing secret information (or help to store this on disc), Think stuff like the Yukikey or NitroKey. This is especially true for the data at rest.
  • Employ Public Key pinning, Strict Transport Security (HTST).
  • Consider supporting Client side Certificates for a full TLS security chain.
  • Employ Subresource Integrity to protect against modified scripts.
  • Something like JWT should be used to transfer the secrets, with a session based key (and key exchange) with (Perfect) forward secrecy.
  • Something like Hashicorp's Vault could be a good storage solution for this type of applications (and use PASSY as the delivery mechanism).

Concerns I've seen in this page that are not really relevant (and why):

  • Client can have a virus/keylogger/hack. If a client is compromised All information on it should be considered leaked. A password manager does not add to this.
  • Encrypting 'Username/token'. This is a waste of computing power, it does not offer any additional security while requiring a big amount of processing. Use a secure hash for password / user comparison. Something like bcrypt.

Additional tips:

  • Protecting a home server from a plurality of attacks on accounts is pretty hard and takes a lot of effort. It is often easier and more secure to delegate that task to a major corporation that already does this well. To this end I would recommend you use an oauth2 openid connect consumer as your login provider. Something like Google's login or facebook's login would be ideal. (which one depands on your target audience and what they already use.) These Login providers actively screen out attackers and other abusers without you having to worry about it yourself.

@Scrumplex
Copy link
Collaborator

@Lawri-van-Buel Thank you for sharing your extensive knowledge of data security.
Initially, while planning this project, I though about using KeePass as the backend, so everything can be encrypted by the user. Instead of Vault I would probably use KeePass. As I stated earlier this post, I have concerns about backwards compatibility. And thus can't switch backends so easily without sacrificing an upgrade route.
But I would still like your opinion of: decrypting passwords on server vs. decrypting passwords on client.
There are neither KeePass parsers, or Vault parsers for JS (just for Node.js).

@Lawri-van-Buel
Copy link

Well you need to construct a threatmodel so you can identify the different threats to which you than can implode the mitigations.

For example to mitigate the threat of reading the passwords of someone else you can implement a user / password system, this would mitigate the threat.

Secrets that you store and wish to reiterate when requested has several inherent threats, such as:

  • interception/ duplication of the secret in transit.
  • interception/ duplication of the secret in rest (either at the server or at the client).
  • interception/ duplication of the secret in memory.
  • manipulation/ interception/ duplication of the secret due to side channel attacks.

Upgrade paths can be enforced through required client update and server side migration.

As to your question. It is my opinion to implement a multitude of layers to mitigate the different threats.
First I would implement an encryption layer to protect the data at rest (on the server).
Secondly I would implement TLS 1.2 with a modern cipher suite and all recommended security headers.
Thirdly I would implement a security envelop for transmission of the data to the client.(JWT with encryption).
Fourthly I would implement client side certificates.
Lastly I would implement a client side decryption with integrity checks on all recourses.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants