Bicycle Attacks: Quantifying the Damage of Widespread Password Length Leakage
arxiv.org
arxiv.org
Basically it's a reference to how a (tightly) wrapped bike is still recognizable as being a bike.
4 bits is not nothing, and it makes most cracking attacks 16 times easier, but it's hopefully never going to be the difference between good security and bad.
True, though there's plenty of bad out there.
Combined with dumb password rules, knowing the exact length could make things pretty easy. Like the US Global Entry password rules: https://raw.githubusercontent.com/dumb-password-rules/dumb-p...
8-12 chars with so many rules that already reduce the search space.
The problem with overly restrictive password rules is not generally a lack of entropy. It's that people can't remember their passwords, which might be a bug or a feature.
Let's say the alphabet is 93 characters (lower case, upper case, numbers, and the 31 special characters listed). So consider a random 8- to 12-character string in that alphabet.
1% of the strings have fewer than 12 characters. Lots of them will be legal, but let's eliminate them all to be conservative.
31/93 of the strings start with an illegal character, so that eliminates 33% of the strings.
About 10 * 1/97 * 1/97 will have three consecutive occurrences of the same character. That eliminates another 0.1%.
(83/93) to the power of 11 will have no numbers. That eliminates 28% of the remainder, or 18% of the total.
By the same logic, 1% will have no special symbol. A negligible amount have no letter.
One password in a million might contain the user's ID (supposing the IDs are 7-digit strings - either way, it will be negligible). Likewise there aren't many random passwords which will be the user's previous password or contain his name.
That eliminated 53% of random passwords, leaving 47% for a loss of very close to one bit of entropy. This analysis wasn't completely rigorous as some of the requirements overlap, but if you try it through simulation I'm sure the result will be between 0.7 and 1.7 bits lost.
The chosen password must:
- Be at least 10 (ten) characters long (and must not be longer than 127 characters)
- Contain at least 8 (eight) different characters, each of which is used only ONCE
- Contain at least 2 letters (case sensitive)
- Contain at least 2 numbers
- Contain at least 2 of the symbols !”#$%&’()*+,-/:;<=>?@[\]^_`{}~¦
The chosen password must not:
- Contain a £ (Pound) character
- Have 3 of any repeating character next to each other
- Spell a word of 4 letters or more listed in a common dictionary (Most 4 letter combinations)
- Be an abbreviation associated with the company
- Be based on your user name
Unsurprisingly, almost everyone just memorises the initial random password given out, since it's provided on a nice piece of paper when you start. Thankfully there isn't also an expiry policy. The max length is large but that's basically meaningless when you actually need to remember it and it takes a while to come up with even a random password that fulfills these requirements.Fantastic awareness training material you have here (in the section "see, others have it worse than we do")
A sad part is that it is virtually impossible to use a password manager to generate a new password.
When I used it last year, US Global Entry had changed over to the login.gov authentication service. The new rules are “It must be at least 12 characters long and not be a commonly used password. That’s it!” https://login.gov/assets/img/help/4-choose-a-password.png
(Login.gov implements the relatively recent NIST 800-63 standard, which prohibits a lot of the earlier password absurdity.)
Supposing MSS is 1500 for a link, how much longer can it conceivably take to send say 1500 bytes including 120 bytes of padding versus 1380 bytes?
One potential pitfall is that an unfortunate number of networks still have poor path MTU detection, so padding that makes the packets larger than any previously sent packet in the stream may result in a packet too large to transit the network. Then you're at the mercy of ICMP delivery or path MTU blackhole detection, which tends to be slow and isn't enabled on Android (!).
Yes if the MTU is bogus and causes fragmentation or dropped packets that's bad, but I'm comfortable it also happened to every other packet sent, I'm only making things go from terrible to slightly more terrible, not from good to bad, and only for people who've got problems.
Certainly, this would only affect people who have problems, which is low, but if you're always padding all requests up to the full MTU, it has the potential to make things go from almost always working, to never working.
Looking at tcpdump with a real browser to one of my sites, firefox is only sending pretty short packets, everything is less than 512 bytes. But if you pad out to the full MTU, and the network is broken, those large packets may all be dropped, and the ICMPs either supressed filtered or so rate limited that they never get seen. Users on these networks with this padding would not be able to make https requests to most servers, but would be able to make connections to services where they have taken special effort to avoid MTU problems.
Special efforts like: Google and Facebook clamp the maximum MSS they send to 1380 and 1400 for IPv4; FreeBSD used to return the client MSS in SYN+ACK if it was smaller than the locally configured MSS, but that was removed with this commit: https://github.com/freebsd/freebsd/commit/e1f9aeedee0bae9281...
I think that protocol would solve lots of basic problems in password security. But the most important thing is that it would serve as a proof that the server is not saving your password in plain text, because the plain text never gets there, only it's hash.
Server -> User : blinding factor
User -> Server: H(password || blinding factor)
Server: stores/checks what?
(Maybe some sort of global blinding factor could work, and generate it deterministically?)
Server saves more data, but has the benefit that the rounds is computed in the client, so server's hash verification could be faster. (EDIT: To reduce rounds in server is probably not a good idea)
I'm no nearly an expert in this stuff, so take it with a kilogram of salt.
Server stores H(pw || bFixed)
Server sends bFixed, bOnce
Client sends H(H(pw || bFixed) || bOnce)
The server can be trusted to not save the actual password if setup/change is already sending H(pw || bFixed) instead of the password itself. But then bFixed becomes public knowledge knowledge and a leaked H(pw || bFixed) would be enough to do a malicious login.What I had in mind is this:
Server stores H(H(pw || bFixedPub) || bFixedPriv) , bFixedPub , bFixedPriv
Server sends bFixedPub
Client sends H(pw || bFixedPub)
bFixedPub and bFixedPriv are unique per password.So treat it like a password, salt it, do X rounds, and stores/checks result
If I intercept H(password || blinding factor) and send it to the server (hashed with any other single use blinding factor), it will be accepted, even though I never knew the original password used to derive it.
So, this doesn't really achieve the goal that the server never stores your password in plain text, since the "plain text" of the password is exactly H(password||blinding factor).
It does mean the server may not know the original text you typed in to derive this password - but this is not needed to log in to the server.
But it does serves as a proof for the user, that no matter however the server is storing the password, it won't be linkable to other's server way of storing the password, in case of reusing passwords.
And no matter how bad practice reusing a password is, people still do that, and I don't forsee a solution to that in the near future
Oh but there is, you can just try logging in with it (either for real or by running the login protocol on a dump/leak).
Sure, but that leak must have been from the same source.
Imagine you are a password-reuser, and you have registered with the same password in www.nottrustworthypage.com and www.yetanothernottrustworthypage.com
If they are using a would-be browser's built-in password protocol (which doesn't exist today, but this is what I'm suggesting and I sketched it in this comment https://news.ycombinator.com/item?id=22257502), and you know that if they are not colliding by using the same salt, and as long as your password is strong so it's not easily crackable, then you can have a pretty high confidence that whichever gets leaked, is very unlikely to damage your others site security.
Colliding salts require lots of efforts by the servers, and most of the damages produced by leaks, are because of lazyness
The problem of your site's password best practice handling is that it does nothing to harden your users against other site's bad password handling. Hence FIDO.
It doesn't prove that the server isn't just storing the derived password in plain text (which is all that is needed to log in to this server).
And it still doesn't mean that the original password can't be recovered if the password db is compromised.
Totally agree on the first 2 points
> And it still doesn't mean that the original password can't be recovered if the password db is compromised.
Why is that?
> Why is that?
Because if I have the password db and the blinding value, I can just run a password cracker like hashcat over it to recover the original password with a reasonable probability.
Modern password cracking rigs with multiple GPUs can try out billions of hashes a second. If you know the salt or blinding factor, you can often recover the password.
Isn't that what the rounds protects from?
If it's not, then it probably won't be implementing your protocol either!
I agree that the current methods could be massively improved.
Now that I'm thinking about it, I don't know how practical it is to do the rounds on a low-spec device like a cheap android
https://blog.cryptographyengineering.com/2018/10/19/lets-tal...
But what I'm suggesting is that whatever it is, it should be integrated with the browser's, so that when I am typing my password in a special password-input-field (which doesn't exist today), no javascript is allowed to read it's plain text, until the user manually unlocks it and the page is able to read it's H(pw || bFixedPub) or whatever protocol is apropiate.
That special password field, should appear outside the pageview, to prove that the page is not in control of it, or it's not allowed to phish it, only the browser has control, and when it's done, it sends to the page the resulting hash
Which ends up with one of the parties writing this: https://palant.de/2018/10/25/should-your-next-web-based-logi...
The blog in the last link argues against the usefulness with the built-in browser implementation.
The arguments are pretty useful, even though I disagree with he's conclusions. I think the fact that if a compromised server has to revert from the secure browser-built-in password form, to a "regular login form" in order to learn your password, then that's a win for me
Don't try to roll your own. But basically there's no appetite at this point to retrofit SRP or any PAKE to "normal" user login on the web.
Avoid passwords altogether. If you must have passwords, have the very fewest possible (Buying more than one "single sign on" solution ought to be automatic grounds for firing the head of IT at a firm) and focus effort on getting rid of them not on trying to have better ones.
> Avoid passwords altogether...
I understand your point of view and you are right, securing passwords is hard.
I only see not-using-passwords feasible using hardware keys like yubikeys, which still might need a master password, but I don't see it becoming mainstream anytime soon
the redundancy of the plaintext HTTP headers included in each and every request can be exploited in order to reveal the length of particular components
... so randomly change the HTTP header length by adding random sometimes-compressible data. X-whatever, or just change the ordering of header lines, or add randomness to the UA string.