What technical reasons are there to have low maximum password lengths?
security.stackexchange.com
security.stackexchange.com
I am reminded of Egor Homakov and his various exploits, especially in the Rails community. Someone points out a problem and the community collectively decided to ignore him.
That is, if I take a lesson from a story about an experiment that never happened, I'm acting like the hapless chimpanzees that merely learn to fear the ladder. So I must choose to not model other people as cartoon chimpanzees.
Needless to say, I found that to be even more disconcerting than the existence of the character limit.
Because the developer is storing passwords in plaintext, and he wants to save database space.
Now, this is not a good reason, but it is a reason nevertheless. Please note that you should never, ever, ever, ever store passwords in plaintext.
This seem far fetched, not sure what thought process would lead anyone to come to this conclusion. Even if you have a million users, you have ~8MB worth of passwords. I'd imagine even developers who are not competent in cryptography realise that.
For those who don't know, for varchar(1) through varchar(256) the internal database representation in sensible databases is one byte to say how long the varchar is, followed by the actual data. There is therefore absolutely no difference between the representation of varchar(30) and varchar(256) - it is just an arbitrary restriction on what data is allowed to fit in there. But databases that support varchar(257) need 2 bytes in front for it.
Is this true in most modern DBs? (I'm thinking MySQL and Postgres particularly).
http://www.postgresql.org/docs/9.2/static/datatype-character...
Don't use MySQL.
So, there actually is a reasonable limit for the length of passwords, email addresses, and most other user-editable fields that end up either being hashed, or shoved through to the database. That limit is just probably somewhere around 100KB to 1MB, not "eight". ;)
More importantly, that limit is an infrastructure concern, not a business-domain concern; it's best enforced by something like nginx spitting out a 400, not the model-validation logic in your app server.
Also please correct me if I'm wrong.
hash(saltFromServer + hash(password))
And then the server would do hash(user.salt + clientHash)
I'm not sure, but this seems reasonable to me.I would expect the image of MD5 on its codomain is almost a bijection (would love to be demonstrated wrong here, if anyone knows of a paper that studies this, but it seems reasonable that any good hash would have this property).
This doesn't really protect against a dictionary attack, but to guarantee a collision, an attacker would still need to try approximately 2^128 passwords for each password in the database, which is already the worst case for the attacker, so no strength is really lost.
SSL is just indispensable nowadays for authentication.
However, my bank uses X.509 certificates to authenticate users over Internet. Out of curiosity, I've asked bank employee once and was told that most users do manage their certificates just fine, without any issues. Obviously, bank provides short and simple manuals, which explain how to generate a certificate request, obtain a signed certificate (by visiting bank in person), authenticate and renew expiring certs.
(My bank's not using in-browser PKI due to legal reasons and provides a small piece of software wrapping around the browser, but that doesn't really matter.)
Your problem: clientHash is "password-like" and Eve can use it to log in.
One solution: use the HTTPS auth methods. Unfortunately, this is not the standard in the industry because the GUI is ugly.
The reason why this is an even bigger problem than you might think: what does the login method do? It probably sets a "remember me!" cookie, which is also "password-like" for just about every purpose. Eve sniffs the cookie and can use it to compromise the account in the future.
Also the 'remember me' cookie is probably stored in the clear in the database. So much for that, eh?
What you really want is a system based on digital signatures: whenever I make a request I digitally sign it. But the core problem is that I don't want to type in my password for every damn request, so this is being cached between requests and between page views. Depending on how it's cached, there are vulnerabiities -- especially if you just have your browser automatically fill in the password blanks, but also if you carry these "password-like" login cookies. A system of delegation and revocation can be done, but you come dangerously close to reinventing a public key infrastructure if you go too far down this road.
HTTPS auth methods can help out quite a bit, but can be hard to set up with a custom backend and hard to test against that sort of "downgrade attack" I mentioned in my first paragraph. The best of these ideas is to give your users client certificates and thus be safe forever, but nobody has found it useful enough to actually do this.
The only real alternative has been to remind the customers to always look for the s in the "https:// in the location bar. This is stupid and now there are some proposals for browsers to ship with lists which are "Expected to be secure", to avoid it, but yeah, we never really outgrew it.
So sitting here trying to think about a way to solve that problem, what I come up with is essentially PKI. But if the attacker has the ability to inject code, they can always break this entirely by stealing my private key.
This feels to me like URLs are fundamentally broken, in that a user might try to go to http://mybank.com. Is there any secure way to get their browser to redirect to https://mybank.com? It seems like there might be something that could be done with dnssec, but that feels brittle too. Gross.
Say the URL is: https://mybank.com, but I go to http://mybank.com, and I haven't been there yet, so the STS rule isn't in my browser. How can a user reliably be switched to https without risk of having the connection hijacked by someone injecting code to the user?
Protecting against a DoS attack this way is done in the webserver, which doesn't care about individual fields. Sure this means there's an implicit password length limit, but not in any application-level sense.
(I really, really hope people realize that is a joke. Otherwise this might be the worst piece of advice I have ever given on the internet)
They also require two factor authentication for all actual money transactions via a chip-and-pin card reader they ship to all customers. You only authorise one transaction for a specific amount/destination at a time.
They don't allow you only log in with two characters from your password like that, you also need a passcode or a one time pad generated with a chip and pin reader, and for transfers to accounts you haven't previously transferred money to and indicated you want to save for future use, you also need to enter your pin, amount and target account into the reader to get a code to enter into online banking to do the transfer.
Barclays for example allows you to log in with this plus a separate pass code, but you can't do much damage without using a chip and pin reader that will give you an 8 digit one time pad too (alternatively they now let you use a mobile app to generate the one time pads)
E.g. you can't do transfers to recipients you haven't specifically saved for future payments, for example, without entering your pin, the account number and amount into your key generator and entering the resulting code into online banking.
I am not a security expert, and realize that this may not be the right thing, and the implementation might be horrible, but if there is a reason to limit password to 8, this was a good enough reason to do so :)
I believe they have some legitimate reasons for doing that (like the example quotes)
Another reason for specifying a length/limits is that you may need to type it using another device (like an ATM) and keeping it apart from other passwords (if you allow everything, you'll just use your gmail password or something)
Now, to be honest, if you break into a bank db, why are you going to bother with passwords?
Yes, if the machine is compromised the attacker could do it as well but the point was to prevent keyloggers specifically.
You are presented with
* * [ ] * [ ] * * [ ]
and you are supposed to submit
* * [3] * [5] * * [8]
so neither side would have enough information to reconstruct the full password based on the user's input alone.
And yeah, like in many things, these are done to give a false sense of security to the user and some minimal deterrent to the attacker.
Even sniffing just one login gives a completely practical attack to gain access to your account, even though the attacker doesn't have the full password. They might not be able to do everything the full password would let them do, but its still not exactly acceptable.
[1]http://en.wikipedia.org/wiki/CICS
[2] http://pic.dhe.ibm.com/infocenter/cicsts/v4r2/index.jsp?topi...
The hash output of bcrypt stops changing after 72 characters but almost all bcrypt documentation mentions a 55 character limit. I'm not quite sure what that is about, can anyone clarify?
check string length
if longer than 55, remove first 55 or less characters up to end of string, store in array
repeat until string is empty
encrypt each item in the array, append them all on to each other as such
EncryptedText[0] . EncryptedText[1]... etc
Seems like a simple way to handle this. You could impose your own restrictions to stop a server DDoS by encryption requests on long strings, but to be honest if you're allowing a 100,000 character password, you're doing it all wrong.
The simple answer is just to hash+salt and then to limit the input length to some large value to prevent blowing HTTP POST or process vm limits.
1) Legacy systems not supporting special characters, 2) The desire to keep support overhead down, and use of the system up, by keeping users' passwords actually rememberable. In other words, if you let users make and use paswords they can't remember, they will, and as a result they'll either annoy you about it or stop using the site due to the hassle, and 3) Developers not wanting to have to worry about parsing special characters from untrusted users, which could potentially be dangerous.
In the past the top reason was probably the lack of ability to support the passwords (#1), and today it's probably the lack of desire to support them--mostly from #2, but partially from #3.
With that said, the rest is just my own guess. Banks are slow moving. They're built on these old systems that run well, but would be prohibitively expensive to rebuild from scratch with modern principals. We see the edges of these systems when it comes to things like passwords.
90s though? I think you need to go further back a couple of decades. Royal Bank of Scotland still has COBOL/IMS powering their core system [0].
[0] http://ovum.com/2012/06/27/rbss-core-system-meltdown-assessi...
This is usually something like a fixed width database or file field that works with code written a long time ago...
Does it suck? Yes. In nearly all cases, Authentication, Authorization, and Access should be separated in ways where they don't interact/overlap other than at an absolute minimum.
Thus, the column would be the right size for the hash always and would be completely unrelated to the user's inputted password.
Not sure I interpreted your message correctly, but either way, the DB field should be unrelated to the length or limit of length put on the user password. It should only be correlated to the length of the hash produced. (Truncating seems like it would narrow the space for collisions, those bits are there in the hash for a reason).
Funny that the experiment was mentioned many times in different occasions, and it's not clear if it was ever conducted. Still Bears around the Internet believed it and just kept repeating it in every opportunity ;)
-my bank's tech support
"Because we estimate the added costs of supporting users will increase by X due to more users forgetting their password due to length"
Additionally, banks invest in a variety of security mechanisms that ordinary companies, even major ones, do not invest in. Passwords are only one part of their overall security. I think all of this outrage over banks having poor password practices, while sometimes valid, is made by people not fully informed. It's like complaining that the bank vault has weak points that could be attacked. That's not all that's keeping your money secured.
My bank uses 2 stage auth to login which works really well. However, they have a sort of shortcut service where you can activate and pick a password and then use that password to do quick stuff online or in their mobile app. The quick stuff still let's you transfer away all your money to someone else so it's basically a gaping hole.
That password has the wildest restrictions I've seen. It allows only a-zA-Z0-9 and it must consist of exactly 6 characters. No restriction on containing at least one digit or anything like that.
I've e-mailed them several times about this but their response is that this particular service has been out sourced to one of the many companies they out source things to, so they have no control at all over it.
And it's rather funny because you can tell that when you use this service, you're taken to a completely different server farm than the rest of the internet site. Fucking scary is what I call it.
Unless the bank doesn't care about their image, of course.
I've spent the whole day thinking about this and now I've been looking up ways to write a PoC. Because I don't think a blog post without a proper PoC will do much good.
So first of all assembling a wordlist was easy using Python. The hard part will without a doubt be interacting with one of the entry points to their service.
It's a flash application, with a login form.
I've discovered Selenium for this purpose, and theoretically Selenium can act as a browser, clicking input fields in the flash form relative to where the element is created on the page. And then I can take a picture of the current page after each operation and compare it to how the page should look at login, or at failed login.
Jesus did you just ruin my weekend. ;) (in a good way)
Edit: Found sikuli and was amazed by how simple it is. Jython script that let's you essentially use images from your screen as conditional expressions in Jython. So you can do
if exists(screenshot of bank login form.jpg):
click(screenshot of first input field.jpg)
type('bla')
And so forth. Very powerful stuff! Sikuli scripts can then be called by external programs such as CPython Popen for example, and passed arguments.(I wonder if they got any other people besides me bothering them because of that rule...)
Also, I just did some Googling and it wasn't until 2009 that HP/UX supported passwords >8 characters!
Though to be fair, when's the last time you heard about a bank's password database getting stolen?
Which gets us to the strange part. Who hacks a bank's service to steal a password DB in hopes of using the passwords against some other target? I'm thinking nobody. If you managed to compromise a bank's web service to that extent, you'd be trying to transfer all of the money from all of the user's accounts to one you control, not trying to crack their passwords.
That means that your bank's password storage method and complexity is not very important. What is important is that, whatever password you use, you never use that password on any other site. And that you use a bank that requires real 2-factor authentication, via text or mobile app or something like that, not with "security questions".
If an attacker got hold of a large number of bank account user logins, I'm not sure what they'd do. My bank doesn't provide a feature to quickly transfer cash from the website... Several hundred large billpay changes would show up and be easy to cancel... Perhaps they'd just gather personal info useful to a social engineering attack...