Options for Password Hashing?

So after tons of searching, we can not effectively encrypt passwords on Cloudflare Workers with the common bcypt and argon2.

So I guess my main question is how would you go about handling this on cloudflare workers, if you were looking to store passwords.

Option 1: Run your identity service outside of cloudflare workers.
Option 2: Rely on the fact Cloudflare Worker KV, encrypts data at rest and decrypts at the process level.
Option 3?

go w/ option 2:

  • use webcrypto API
  • store sessions and user credentials on KV and Global variables.

The more I think about it, Workers KV, doesn’t seem to make sense for this use case, unless I’m mistaken.

Given all endpoints reside within Workers.

A successful request to reset the password may hit one server, but the subsequent Login Request with an updated credential payload may hit a server that has outdated data. Therefore not being able to login, until they’re able to hit an ambiguous server that can read the newest version of the data. :confused:

From what I know, KV is updated across the network within “a few” seconds. Docs say sixty.

Right, I recall one of their talks mentioned, it was very very fast, and the “60” seconds was just cushion.

However fast, the eventually correct nature of KV means the situation could happen, however rare.

Am I overthinking the problem?

KV is really cool, so it’d be nice to be able to apply the usecase, confidently.
I might just house user credentials in a database outside cloudflare, but I’ll continue to dig through the docs to solidify my understanding.

If you do an await on the KV-write, then it will cache that data on that data-center. So you will be able to immediately read that value. So for a user-model, it works just fine, actually exactly as it would with a CouchDB setup.

I’ve done very large multi-user tests on this, at 50 000 users. So I know it works reliably even in a distributed setup.

About hashing, I’d suggest creating an external API for that. Workers don’t have enough CPU-time for securely hashing passwords.

While Cloudflare’s KV is great, I personally wouldn’t use it to store sensitive data such as credentials, especially with a recent KV incident at which a discovery was made that anyone could access the contents of a KV namespace if they knew the ID (see The KV vulnerability).

Don’t get me wrong, I love CF workers and the KV feature, but I would first wait for Workers/KV to mature a bit more before I would really trust it with sensitive info. I can’t wait to see what’s planned in 2020 :grinning:

That’s like saying, don’t run Linux because it has had kernel vulnerabilities recently, might want to wait until it matures a bit… Was the KV-bug embarrassing to Cloudflare, yeah, I bet it was - but it’s been addressed, mistakes happen and developers are only human.

To be fair, that’s the only “vulnerability” I’ve seen so far working on CF workers exclusively for more than a year.

I’m late to the party here, but you can bcrypt in a CF Worker using the bcrypt.js package: https://github.com/dcodeIO/bcrypt.js

Include it in your Worker, and user the “Browser” documentation instead of Node.

1 Like

It cannot, no “secure” hashing methods work for passwords, no Bcrypt and no Argon2.
There is simply too little CPU-time, no matter what you do (Unless you use workers unbound).

To make these work in workers bundled, you need an external server or several.

I’m a bit confused. I currently have a worker with the bcrypt.js included, and am able to use it to hash and store passwords.

I am also able to use it to compare a provided password to the hash.

Is the argument that bcrypt.js isn’t actually as secure as other implementations? Or is it something else?

Because, again, I have this working in a Worker right now.

If you check your workers statistics, you can see that it consumes several hundred milliseconds of CPU-time, this is because workers provide a buffer on startup. However, in production use you’re only allowed 50ms max in the “bundled” workers plan. If you do some small load-testing on the worker, it will stop functioning and throw a CPU-time error.

More details in this very lengthy thread:

Ah, thank you very much, @thomas4! That’s quite helpful.

I should add that doing any of these supported WebCrypto features work just fine, unless you’re doing too many rounds or too large chunks of text (Like a HTML body won’t work).