True, but in this case if you can write an invalid hash into a database, you can likewise write a valid one, and as such this doesn't really enable anything.
The one thing this does get you is that the original password would still work (technically any password would still work) so it may make it harder to detect since the user wouldn't "suddenly be locked out"...
> PHP. This is a known weakness in PHP's bcrypt implementation. From Wikipedia, "Many implementations of bcrypt truncate the password to the first 72 bytes." I would hope that they're using a competent implementation that either supports longer passwords or throws an error if it's asked to hash a longer password.
Actually, it's a known weakness in BCRYPT. PHP did not implement bcrypt, it was ported in via crypt(3). Meaning that ALL versions of bcrypt have this issue.
Some implementations error on > 72 bytes, but NONE of them accept longer passwords.
> I don't think we know enough to conclude that they were definitely doing it wrong, but it would be nice to know more details about the algorithm, though.
Given what has been shared so far, there's enough signs pointing that the chances are pretty high they did something wrong. 40 byte salt? Bcrypt only supports a 128 bit salt. So either they did something silly custom (at which point it's no longer bcrypt), they aren't actually using bcrypt, or they did something silly like concatenate the salt + pepper + password and pass it to the password field.
> I would recommend that the author read up on NFAs and DFAs -- they are a formalism better suited to lexers than tries.
Author here. The actual regex implementation uses a NFA. The start of it used a Trie, but it moved away.
The majority of what I wanted to get across here was the use of a minimal structure (single-character).
The next step was using a maximal radix implementation (as long of a prefix as possible). Then finally, throwing all of it away and going straight to parsing using a state machine.
The #1 password out of 3.3 million was 123456, which was used 20,000 times.
So extrapolating that for your 2 million hashes, we'd expect the top password to appear roughly 12,000 times.
Running those numbers, we'd expect each guess to have a 1/12000 chance of matching. Or more specifically, a 1988000/2000000 of not matching.
With some quick running of those numbers, we'd expect a 50% chance of finding a match after trying just 115 random usernames.
I'm not saying it isn't an interesting approach, I just don't think it's nearly as effective as if you encrypt the hash directly (which has no attack vector unless you can get the key).
As an attacker, I get SQL access to your DB (meaning no access to the encryption key). I then download the user names, and the hashes. I then attack the hashes offline. I recover only the weakest few percent (since you're using bcrypt). But since the weakest few are those most likely to be re-used (both by different users and by a single user across sites), they are going to be both more valuable to me and easier for the next steps:
Then, I take the highest frequency passwords and the user table, and I start validating them online in your system. Now if I do that too quickly, you'll notice and I'll be shut down. And if I do that all from the same IP, I'll be shut down.
But what if I had a botnet that I could distribute the load across. What if I kept my request rate small enough to stay under the radar of even a moderate scale system.
I would expect to start seeing meaningful results within days.
If you had 1000 users, then I could surmise that you don't have much traffic, and hence keep the request rate down to perhaps 100 per day. In 10 days I'd have at least a few u/p combinations that I know for a fact worked.
If you had 1000000 users, I could ramp it up quite a bit higher, to perhaps 1000 or 10000 per day.
And since they all came from separate IP addresses, it could be rather difficult for you to tell an attack was going on unless you were looking specifically for it.
Does that mean you should stop immediately? No. It's not that bad of a scheme. But be aware that it doesn't give you (or your users) the level of protection that it may look like on the surface.
> A properly implemented, simple pepper can only help password security and can't hurt it.
Well, yes. But what is the definition of "properly"? There are definitely constructions of "pepper" that look simple, but drastically hurt overall security:
It's sort of like the difference between birth control and counting based contraceptive methods (Standard Days Method). Executed perfectly, they are equally as effective. But with a slight error, one stays roughly as effective (losing maybe 5 to 10% effectiveness overall) while the other drops drastically (down to 10 to 20% effectiveness).
Considering using encryption is as effective as using a pepper, and it's less prone to weakening the core password hash, I suggest using encryption instead of peppers.
> Having the caller do it seems quite pointless when the recipient is anyway doing it.
Actually, I disagree. The caller is the only one who has semantic information about what the variable (and hence its value) means. All the callee (recipient) can do is blind cast it. The caller on the other hand can interpret it because it knows the meaning (talking about the developer, not the engine).
> You don't hire 10x just people who make other people 10x? Then that person you just hired is 10x.
The point was more that I value a person's ability to lift those around them much higher than their abilities to outperform them. It's hard to scale one person. But one person who can help scale an entire team is infinitely more valuable.
> In simple business terms you have a guy who'll get you sued for 1 million but will make you 10 million.
He's not a liability because of potential lawsuits. He's a liability because he brings the team down (antics like this do have a huge impact on the rest of the team).
Why did we tolerate it? Because we weren't given the tools to do anything about it. We couldn't kick or ban people. We couldn't moderate our own room. All we (as owners) could do was move messages or flag. We got yelled at every time we flagged something, so we learned to live with it. The only other option we had was to leave (which many users did, even leaders).
Today, we have the ability to kick-ban. Awesome. But he's also calmed down a lot. And is seen as a resource.
It's gotten a lot better over the years, but there is still work to be done in there. But now we're starting to get the tools to handle it. Which is awesome.
That's definitely valid. However, in the vast majority of cases where someone complains about CV-PLS in my experience, it's because they had their question closed.
Look in this very thread. You have people saying it's a horrible practice. Yet nobody really saying what should be done instead.
The fact of the matter is that there is a huge problem on SO of under-moderation. Over 11,000 questions have >=1 closevote right now. CV-PLS is one technique that the community has found effective in keeping the site searchable and with good content.
The people who are against it, I'd love to hear ideas on other effective methods. But to say it should be forbidden is a bit short-sighted.
How do you solve the torrent of duplicates and low quality questions then? The review queue is backed up all the time (currently 11900 questions with 1+ close-vote).
Ignoring the problem does not make it go away. If you think one of the ways people are trying to solve it should be forbidden, that's fine. Please share an effective alternative.
Basically, there's nothing wrong with the concept, unless it's used incorrectly. So if someone closes something incorrectly (you can point to a definite reason it's incorrectly closed), then re-open it or raise a meta post.
If you want to remove the ability for the people helping moderate a community to moderate, then how do you expect it to be moderated?
The big issue is that there are a LOT of low quality questions being asked. Duplicates. Many times literally copy/pasting the the question title into Google will give you the answer. Should these questions remain open because you want to repwhore? Should they remain open and further reduce the ability for Google to take you to a good canonical answer?
Or should they be closed and point to the good canonical answer? That way people can find their way to good content, rather than littering the site with duplication and poor copies of other answers.
The meaning of the CV reasons has changed over time as the community matures and figures out what works and what doesn't.
I do disagree with closing questions about particular framework (unless there's a dedicated SE site for it).
But bitching doesn't help. Raise a question on Meta. Step into the chat rooms and have a discussion. Get involved and help us fix things.
All bitching does is make the people who are putting time and effort into the community feel like they are doing something bad. Which is the fastest way to kill a community.
The one thing this does get you is that the original password would still work (technically any password would still work) so it may make it harder to detect since the user wouldn't "suddenly be locked out"...