I am working on a patch which replaces SHA1 hash with more safe bcrypt. This algorithm was designed for passwords, it has a “cost” complexity setting which can be increased as computers gets faster. Recommended cost value by 2018 is number of 10, but that adds about 60 ms of processing time for login action and for session-less API calls compared to SHA1. From my testing on my CPU from 2017 (AMD Ryzen 1700) cost values 6, 7, 8 and 9 add 4ms, 7ms, 15ms and 30ms.
As part of my PR, I am adding new “calibrating” seed code. Everytime rake db:seed is performed, cost value (Global setting) is recalculated to highest possible number which can be calculated below specified threshold.
Now, the question is what to set as the threshold, therefore default cost value. In my current proposal, I suggest 5 ms which is cost 6 on my CPU today. It is below recommened value for today’s CPUs which is 10 but it is still safer (slower) than SHA1 which can be calculated in less than 0.4 ms.
This is all about the tradeoff - better security by default vs slower performance of login attempt (possible DDoS attack) and session-less API. So here comes a poll and feel free to comment on the topic.
One solution would be to add new flag to user table called “API user” or something like that. When checked, hashing algorithm would be SHA1 for fastest possible session-less API performance. But it is a bit clunky.
I think if the result is that we are actually using a weaker hashing due to this change compared to SHA1, then there is no point in making the change. If I understand correctly, anything under 10 isn’t considered secure at all today. (I couldn’t find a comparison of what cost gives similar security to SHA1)
If the result is that to get stronger hashing we need to make all api calls take an extra 100ms+ I would be be against this - scripts such as ansible inventory can make thousands of calls to the API, so this will add multiple minutes to the runtime.
But that’s not the case, bcrypt with cost 1 is still stronger than SHA1. We are using incorrect hash for the purpose, SHA was designed to be fast, bcrypt was designed to be as slow as you want.
So in short, bcrypt is designed to be slow but you can set how slow you want it to be. That’s the key point. I did terrible job in explaining this, let me post few links:
It seems to me that if it’s really important to lock down Foreman passwords, users would use LDAP other than our self-baked authentication, right? This kind of means that Foreman passwords should be reasonably secure but not Fort Knox secure.
Could we allow users to choose the cost with a sensible default? The cost value could be per user and thus enable admins to choose how difficult a certain user’s password is to brute-force.
That’s exactly what the patch does. Cost is set to value not longer that 5 ms to perform hashing on initial seed and user can change it to any cost value using Administer - Setting later on.
Since most of the voters are for slower performance but increased password security by default, I propose to add new flag to user model: “Fast password hash” with explanation that this boolean can be used for session-less API users. This would keep the possibility to use SHA (opt-in only).
Because lots of users are using hammer -u admin -p change and this command is sessionless AFAIK. Password hash is verified each request. You can use hammer login to create a session but that’s not what users always do I guess.
Guys, results are rather vague, we have no clear winner. But I can still read some result: most of you want cost 10-12 while I was leaning towards cost 6 and since cost 10 is recommended on wikipedia as of today, I am rebasing the PR so the calibration sets default cost to burn at least 50ms which is cost 10 on my modern CPU from 2017.
Let’s just merge this and if we will have anybody complaining about slow session-less API, workarounds are trivial (use a session or change password via Rake Console with lower cost).