3

currently we're working on a small application where we store a bunch of JSON data coming from a JS-based graphing editor (think of a spiced-up version of this) in a Rails-based backend. We want to allow users to store the data encrypted (AES, RSA, whatever), where we as the application maintainers have no possibility of decrypting what's lying in our DB - given a strong password of course. There's no user account management, nothing. People are only able to create and edit their graphs via a secret link, nothing more nothing less.

The password would then be needed to encrypt / decrypt the graph coming and going to the DB before editing or saving the current state. Now, the conceptual questions we're facing right now are the following:

  1. Do we store the password throughout the session? If not the user would have to enter the password every time he refreshes the browser or wants to save the current state of his graph into the DB. Uncomfortable...

  2. If - from a software engineering perspective - this is applicable: Where does this kind of information gets stored in general? What options apart from cookies do we have?

  3. If so - would we have to store the plain password or is there a way to somehow encrypt the password so that in case of a stolen cookie an attacker would face a more difficult game getting the password?

A. Neumann
  • 488
  • 2
  • 15
  • 1
    Don't store passwords if possible. Instead store an auth token. Do a search for password security, or better yet, use a trusted third-party for auth. – evolutionxbox Mar 21 '18 at 12:32
  • Hey evolutionxbox, since we do not have an accounting system it's not about authenticating. It's about storing the passphrase used for encrypting/decrypting the content. – A. Neumann Mar 21 '18 at 14:12
  • 1
    Accounting system? Of course it's about authenticating, that is what a password is. I would recommend you look up the basics of safe authentication on the web. i.e. _don't store passwords_ – evolutionxbox Mar 21 '18 at 14:16

1 Answers1

2

Many times, security is a balance, and this is one such case.

Considering your requirements (webapp with no user mgmt backend), I think you have two options:

  • You don't store the password, but then user experience is worse. As you said, any refresh will need the password again from the user.

  • You store the password client-side (see below how), one reasonable place would be SessionStorage. This way it is comfortable and would work as any user would expect: it 'just works' until the user closes the browser, but not afterwards. Obviously this has the very real risk of the password being present in the browser in some form. It is available to any Javascript (consider xss) and you can't prevent it from being cached to disk (no matter what you do, consider hibernating the pc, etc). In general, this is an antipattern, but it's not that simple. Security decisions should be risk based.

This is a decision you have to make based on risks specific to your usecase. What is the data, what is the likelihood of an attack (what did you do to attain reasonable assurance that your code is secure), what is the impact (what will you lose if the password is lost, including things like loss of reputation too). Also would your users really hate the product if they had to enter the password all the time? Only you can anseer these questions.

Encrypting the password on the client doesn't make sense, thr attacker would have everything to decrypt it. However, there might be a benefit to hashing it, and it might be a bit surprising at first. If you don't actually store the password but some kind of a transformation, then whatever you store will be the password, so seemingly it doesn't make sense. The reason it still does is because people tend to reuse passwords, so if you derive a key from the password with say PBKDF2 and store that as the key, it is better, an attacker can't have the actual password from the browser (but they can still access the data if there is a compromise, say xss).

So if (and only if) you accept the risk of storage explained above and also the risk associated with javascript crypto, you should

  • derive a key from user password with a proper key derivation function like pbkdf2
  • store that key as the encryption key in SessionStorage
Gabor Lengyel
  • 14,129
  • 4
  • 32
  • 59