Caring what characters are in the password heavily implies that the site is not hashing the plaintext password in any way, and scarier still, may just be storing the plaintext password as plain text.
Why: Because if they were (at least) hashing it the output from the hash would be a binary string in which case they would have to be 8-bit clean through to the DB column where the hash output resided, and then there would be no reason to care what character was in the input.
Caring specifically about a + in a password also implies that their authentication might be setup internally as a http endpoint with URL encoding of a "password=" form variable (because + is used as the escape for hex encoded characters in URL encoding).
Both, of course, imply a lack of proper secure design in their password handling.
> Caring what characters are in the password heavily implies that the site is not hashing the plaintext password in any way, and scarier still, may just be storing the plaintext password as plain text.
I don't think that is true at all.
I may very well want to put a few simple rules I validate serverside, such as
1) No username in password
2) No email in password
3) No list of 100 most common passwords in password
All of which require me to look at the text for your password, none of which mean I am storing it in plaintext.
I've run into a couple of sites that reject passwords containing ', %, and other special characters that suggest there may be some truth to it.
If you're scrubbing input as if it's about to be insert into a database via SQL, then there's really only two possibilities. Either a) you're running legacy code that still does the check and does blind escaping (which has its own set of implications) or b) you really truly are storing passwords as plain text.
Hah, good point. Although I do have to wonder: When does it turn into filtering by force of habit? After all the legacy cruft has long been forgotten and is no longer maintained?
Because the other monkeys will chew you out if you start doing it differently all of a sudden. Nobody knows exactly why we're doing it the way we are doing it, but it is complex, and changing it might break something.
Let's use the "filtering chars from password" example above. You can't put some special chars in password field, and you want to change that so it's doing normal hashing where special chars don't matter.
In a larger org, even changing a practice like that so that it "makes more sense" can have a big ripple effect.
You have to
* explain to someone else on the team who came up with the original process that it's flawed (and why)
* explain to other dept that they need to update their testing process (and why)
* get support dept to change their language/process
* change outbound messaging in all affected places (perhaps with code you can't touch, involving other teams)
* possibly have a flag that deals with 2 versions of data
Even if your change brings you in to line with normal/safe practices, you may have to fight multiple inane battles, spend loads of time and political capital, and at the end of the day, you'll be able to also accept a !"@+'$ in a password field? Most people will not grasp the bigger issue at play.
At a small business convincing colleagues isn't that hard. At a larger corporation, getting the rest of the team on-board is the job of whoever is in charge of defining security policies and such. Not allowing characters present on all keyboards and input devices (!"@+'$) statistically increases the risk of people picking weaker passwords then possible, and he/she will guide that change through the proper processes, for example to make sure that any client software interacting with the backend is aware of the upcoming change. Same as with any security issue (e.g., the deprecation of SSLv3 ciphers in favour of newer TLS versions).
If a business can't handle a change like this, something is really broken in the development pipeline. Granted, that describes a lot of medium sized companies…
Take that one 'request' - possibly initiated by a jr-mid level developer - and stack it up against the 500 other todo items in the pipeline. You can make those arguments about "statistically increases the risk of people picking weaker passwords " - unless this increases a bottom line or comes out of someone else's budget, this sort of 'bug' is going to be really low down on the totem pole for all the reasons I mentioned, and a few others.
You can says "the process is broken" but it's also that same process that got people where they are, puts food on their table, pays for the lifestyle, and precious few people are willing to ever rock the boat at any company for anything.
Which gets back to some of the cargo cult thing too. It's not uncommon in a large enterprise to smack up against things like "Years ago we paid a highly trained Security Consultant a large amount of money to develop our Security Guidelines, who are you and where are your security credentials to tell us to do things differently?"
Even worse when that "Security Consultant" is still a retained coworker with a fiefdom to maintain by war at all costs, a wizened old greybeard whose seniority will always trump yours, and/or your boss.
There's a related issue that I've seen in some banks, which prevents you from using passwords LONGER than a certain number of characters (usually 8 or 10). The only reason I can think this is happening is because they don't hash them and they need to fit in their database column. I took my money out of that bank the next day.
Could just as likely be some process that still needs to pass the password around in a fixed-length file format to some ancient backend process written in COBOL living in the cthulian abyss deep in the bowels of the bank that no one dares rewrite from fear that it would destroy the bank from inside.
All of those checks can easily be done client-side, though. Of course this means you can't guarantee that none of these rules are violated, but I suspect that the users capable of bypassing this aren't the ones you're concerned about anyways.
The server does have to have access to the plain text password in memory, you know. I don't see why you think it's worth sacrificing guarantees of password strength to uphold some kind of taboo.
so you just replaced the password with another secret, the hashed password. An attacker would now not need to gain access to the original password, but needs the hashed password - which will be logged just like the PW.
The only security benefit is that it offers a bit of support for those that are reusing passwords since it doesn't expose the plain text.
Isn't that what SSL does? And if the SSL between you and the destination is compromised, you don't even know if the hashing algorithm you asked the client to use is actually the one they used.
Yep. And importantly, SSL is securing more than just the password - if you just salt + hash client side, then anyone watching gets to do a replay on that value instead of the original.
> You can perform the first pass of salted hashing on the client-side.
Not really. JavaScript crypto is fundamentally broken: an attacker, malicious server or disgruntled employee can replace server-side JavaScript and remove the client-side hashing at any time. This is, notably, why Firefox Accounts are completely and totally insecure (and hence why Sync is unsuitable for storing any private data at all).
Can you reassure me about the worst horror I've seen?
That is: a listed-and-enforced ban on obscenities in passwords. Is there any world in which that company isn't butchering their security in some serious way? (It's Time Warner, so not a small-time deal here).
Or, they submit the password over HTTPS, validate server side, then hash and store in the DB?
There is no reason to assume rejecting of a + means they don't hash, and browsers escape the password for you in POST/GET etc. The fact that + is used for space really isn't relevant.
(That said, I think it's pretty stupid to "validate" passwords beyond checking for "12345", "password", a min length, and other public info. e.g. your password should not be your name or date of birth. Anything any password generator spits out, so long as it meets the min length criteria, should be accepted).
> Anything any password generator spits out, so long as it meets the min length criteria, should be accepted
It annoys me to no end when I have to hand-craft a password to stay within the silly rules of some service.
Be vocal about this! Keep complaining to the services you use that don't accept such valid passwords. Banks for example are notorious in insisting on short passwords and arcane limits on which characters to use (ING in the Netherlands limits you to 20 characters, and nobody there seems to be able to explain why).
Société Générale uses the client ID and a 6 digit passnumber (sent via physical mail) with a digital numpad (you have to click) where each number is randomly placed.
So secure.
And they force a change every 3 months. As if a new 6 digit pass was more secure than the last 6 digit pass.
Sadly at some places it's intentional so your password matches existing PIN systems or is "easy to remember" so you're not as easily locked out of your account. I wish in those cases there was a check box that says, "I know what I'm doing, leave me alone."
Speaking of annoying validations, my name has a hyphen in it but you'd be surprised how often that's rejected with the familiar, "Please enter a valid last name." Sigh.
Because of code style (I do not mean spaces or tabs, it is beyond that). Different developers have different ideas of how a function should behave, where it literally has no effect on how the rest of the system works.
As much as I agree that most artificial limits on the passwords are silly, there's a reason for at least limiting to latin1 charset - or maybe even a bit stricter. How sure are you that strings are always unified the same way between the browser and hashing? Have you tested that you can login from a browser which prefers CJK encodings and each of the UTFs? From all browsers? Maybe it works, maybe your framework deals with this without issues. But if not, do you really want to chase those mysteries in the future?
Btw, almost nobody is actually storing hashes as binary blobs. Pretty much every framework I know stores either base64, or direct hex encoding of the value.
We reject Unicode control characters, surrogates, private use code points etc. Passwords are sent in a UTF-8 encoded JSON over TLS. They are normalized using NFC.
For more fun, try putting a "--" (two consecutive hyphens) in many fields in the AWS console. Not allowed, I guess because they're passing it to shell commands somewhere along the line?!
> Scarier still is when it's a server-side response that rejects my password for its contents...
Why? Assuming that you have established a secure connection with that server (i.e., HTTPS by means of TLS), then it is perfectly fine for the server to check, at the time you are setting the password, if your password confirms to the rules established. And when the password turns out to be suitable, it is okay for the password to be sent to the server as-is.
Now it goes without saying that as soon as you have picked a suitable new password, that the server will store only a (proper) hash — by using BCrypt for example. At no time is the plain text password stored anywhere, and any proper HTTP API will send the password via POST to prevent it from being logged in the server's access logs (which is where it could end up if sent as parameter via a GET request).
There are plenty of services that screw up and try to apply nonsensical rules (such as limiting the length of the password to anything less than, say, 256 characters), but in general this is done to prevent weak passwords. You can't exclusively do this client-side, because in security terms, the client cannot be trusted to actually apply the validation and to generate a proper hash; the client can be bypassed. Of course the client can and should validate any input before the server gets to it, so ideally the server need not even come into it during validation, but the server has the final word.
As user though, you have the responsibility of not reusing passwords anywhere (and you don't, because you sensibly use a password generator as you mention). Don't assume that any service handles security well.
And you should; you have no way of knowing if any service is practising proper security or not beyond what you can see (e.g., exclusive use of HTTPS with valid certificates), so assume the worst. It is best to see a password as a shared secret; something you share with a specific service. That means no reuse of passwords if you care about the consequences of that password getting out.
My bank limits passwords at 15 characters. The best thing? There is no verification, it just cuts off. Have fun figuring out why you can not login anymore.
Here is a fun one. My credit union limits passwords to 32 characters and since I use lastpass for my passwords I had it generate a 32 character password when registering at the website.
Next day I get around to downloading and setting up their mobile app. Login and get a prompt that since it is my first time using the mobile app. They have sent me an email with a 4 digit code I need to enter before proceeding in the app. The email with the code arrives quickly and I enter the code. Proceed to get an error message "Error 400: This service is not available at this time." Ok, they must be down I'll try again later. The code is good for 24 hours. Next morning find time to try again and get the same error message except this time it also informs me that my account has been locked. Call up customer service and with scarily little information get them to unlock my account. Explain what is happening with the app and the CS rep puts me on hold. Comes back and tells me the IT folks thought it must be a problem because of my email address. "Do you have a normal email address like from Gmail, Yahoo or hotmail?" I release a great sigh and give in to the stupidity I'm about to have to navigate. I provide a gmail address. They change the email associated with my account on their end and tell me I should try again in 24 hours. I do with the same results. Call back again and the CS person puts me on hold again while she reaches out to IT. This time whoever she talks to knows the issue right away.
Turns out that when you login to the mobile app for the first time and submit the code it is actually appended to the end of your password and submits it as your password. Which if you have a password with more than 28 characters means you are exceeding the 32 character password max which causes them to return the informative, "Error 400: This service it not available at this time.", message.
Fun fact PayPal (used to?) silently cut off passwords when signing up, but not when logging in. And the password rules are of course not shown on the login screen. So good luck remember what length they cut your password down to when your password manager has stored the longer version.
A previous place I worked did almost the same thing. There was an internal website they had built that everyone used for time entry. It authenticated via LDAP, so you didn't need a separate login for it. However, the password box on the page only permitted passwords of up to 10 characters, but it wouldn't notify you it would just truncate whatever you typed in. So if you had a Windows password longer than 10 characters, you couldn't enter your time.
Comcast has the same issue. I changed the password for a user on my account using a password manager, it accepted a 20 character password with no errors, but then I was unable to login with that account. Changing to a 12 character password finally worked.
Have you ever heard any reasoning behind why they do this? The "best" excuse I've heard is so that customers don't forget. As if they don't have a "Forgot password?" link right there.
When I forget my banks password, I have to go to the closest client centre. Ironically, the only time I've had to do that is when my password was truncated.
I remember Starbucks was doing it for their mobile app about two years ago, sacrificing security for a "better"/faster UX. It's one of those things that you think "No one would be dumb enough to do this", only to be surprised by the fact that a big player has been doing it for a while.
> Scarier still is when it's a server-side response that rejects my password for its contents...
A friend's project decided to disallow umlauts, combined characters like ´e (can't type the correct e with accent mark), the pipe symbol and a couple more in new passwords.
Not due to plaintext storage or so, but because of customer service issues - people were bugging support all the time because they were e.g. abroad and couldn't enter umlauts or on a Mac and couldn't find the pipe symbol (it isn't written on the keyboard!)... of course, a quick direction to the Zeichentabelle in Windows helped, but what for Mac users? At least it did take a huge load off the customer service guys.
I'm looking forward to the date when some clueless user will input a UTF8 emoji as a password, given that Android and iOS keyboards now include these on special keyboards...
I'm looking forward to the date when some clueless user will input a UTF8 emoji as a password, given that Android and iOS keyboards now include these on special keyboards...
Looking forward? That happened a year ago and caused problems because the OS X Yosemite login screen had no way to input emoji:
It's worth playing around with the option key when pressing letters on OS X. You're able to enter a ton of common (western) characters with that alone, without ever opening the "special characters" (ugh) palette.
Also the default configuration for a couple versions now (which I hate, but I know it benefits others) is if you hold a commonly (western) accented character, it'll suggest accents for it.
Even Linux tools like GNOME Archive Manager in Linux Mint 18 rejected my RAR password containing a $ as the incorrect password, even though it was the correct password for the RAR file I was trying to extract. I then used the command-line unrar utility with the exact same password, and it extracted successfully.
Now, why would you preemptively (and explicitly) throw out a candidate password string based on its characters?
At least make the validation consistent.
I also had trouble with connecting to a wifi network with a WPA password containing an ampersand in Arch Linux using the Arch Wiki's recommended command line network manager utility (netctl, if my memory serves me correctly), and I tried all sorts of ways of escaping it and quoting it in the configuration file.
The Arch devs on IRC just told me to change my AP settings so that the wifi network doesn't use a password containing an ampersand character. Well, that would have been a good idea, but it wasn't my network, so I didn't have the ability to change its WPA password.
I'm guessing both are because the are calling command line tools. One of my pet peeves with linux is that many of these tools are only callable via text and don't expose an API for other programs.
"callable via text"? What does that even mean? The command line is an API, isn't it? If people don't manage to pass an ampersand to another program via the command line, that's really no different than people failing to pass an ampersand as a URI parameter to an HTTP resource: Failure to encode properly. There is absolutely nothing that prevents you from passing an ampersand (or any other characters) to a program via its command line.
It means you have to execute commands through a shell. A real API would be something you could include in your program, execute a method against and get a list of objects back. Instead all these basic command are replicated in every framework.
As far as encoding properly, you're preaching to the choir, but out in the real world there is still injection attacks everywhere.
Word-splitting, escape character interpretation and so forth is done by the shell. The shell is only invoked if you use the system() call to run said tool.
Which you shouldn't. execve (and friends) will let you pass an explicit array of flags, and you should always use one of those functions if you're calling another program. No interpretation.
On a Unix system, a console application is effectively just a vararg function taking a bunch of const char* arguments. There's no limitation on what characters you can pass as those arguments, so that doesn't sound like a valid excuse.
(There are some characters that are treated specially by shells, and require escaping - but you don't normally spawn child processes via a shell.)
This very heavily implies that the database column which stores "passwords" is typed as "char(12)" and that the site is storing unhashed plaintext passwords in that column.
Why: Because if they were (at least) hashing the password, then the output of the hash would be a fixed size token unrelated to the length of the input plaintext password, and no such arbitrary short limit would be necessary on the plaintext password itself.
Ha! If only! Probably more than 50% of the sites I visit that have a maximum length that my password manager exceeds... give me an unrelated error message. Some times they tell me I haven't met the minimum length (100 chars, really?), sometimes they tell me that I've not met complexity requirements (I use upper/lower/numbers/special chars), etc.
It's as though the developer only ever thought of how people wouldn't meet their minimum requirements, wrapped it all in a case or switch and let the default be whatever they hadn't checked in previous conditions.... not thinking that anyone would exceed their requirements.
You default to 100 character passwords? Doesn't that make it extremely inconvenient on the rare occasions when you need to type a password out? I figure 14 characters is going to be effectively unbreakable, but still possible to manually copy in under a minute.
Yeah, basically this. In theory every time I need a password I can copy and paste.
In reality, sometimes I'm on someone else's computer or something else comes up that I need to open my database up on my phone and type it in by hand.
For instance, I can't imagine trying to enter a 100 character password with a PS3 controller to log myself back into Netflix...
If I'm already at "it's going to take 100 quintillion years to break this hash, even if they're only using MD5", then I really don't see any security benefit to using a longer password... But there's a definite loss of usability.
It depends on your needs. Clearly in my case: nope, not a problem. Otherwise I would have changed. And I think your use of the word "default" is appropriate; what I do most of the time is not what I do 100% of the time... there are exceptions.
In those cases where I might need to manually enter a passphrase and I can't rely on the password manager functionality, I use a pass-sentence that is both long and includes some random characters thrown in. That can still get me to 100 characters pretty easily. But those cases a fairly rare for me. I'm also only very, very rarely using a device that I don't own (ok, I do access systems I don't own frequently, but using my device... ssh, etc).
Most of the time my 100 character default doesn't give me any greater security than your 14 characters (assuming they're well constructed or random passwords) and things like multi-factor auth are often times much more important anyway. There are some times it can be useful; sometimes I can remember a 14 character password just by looking at it, even if it's random and not mine. 100 characters I can't. Since password managers can rely on things like cut and paste, rarely, but occasionally, I might accidentally paste a password somewhere I don't mean to: at 14 characters I might not notice, but at 100 I more likely will (or overrun the field and lose a piece of it anyway). At the end of the day, I have a password manager and I'm going to turn it to 11 and let it run. My personal practices are not necessarily my recommendations in this area, but they suit my needs.
Either way, my point still stands: if you build software that takes passwords and you limit the length (or can't take longer passwords), provide meaningful feedback if your requirements are exceeded... makes me wonder what else I might be able to do if you didn't expect me to exceed your password length and respond properly.
Depends on where you have to type it, but usually, if people have long "passwords", it's because they use passphrases, which tend to actually be easier to type on real keyboards, but which are long because of the low entropy per character.
My guess is that when you call them on the phone, they ask for your password to validate your identity. Which means it's stored in plain text in their database so that customer service can verify what you said is correct. Maybe they don't want their employees to have to be cursed at by customers.
I can't think of a good way for a business that has an online interface and frequently handles phone calls from customers to validate that they're talking to the correct person. Asking for other personal information can be used by an attacker to compromise multiple accounts via social engineering: http://www.wired.com/2012/08/apple-amazon-mat-honan-hacking/
Someone else in this thread mentioned a company that has customer service type in your password to open your account. So that would be a non-plaintext reason to insist on non-obscene passwords. But it's still terrible, because why the hell is customer service typing in your password.
Pretty much all organizations that allow phone authentication seem to be at risk of engineering attacks. The only ones that manage it send you something verifiable they can ask about like a credit card, and people who really care like the government just send an actual human to your house.
I'd prefer to have an obscenity in my password if a customer service representative is seeing it. That would help communicate my frustration with their system. Saves me from having to voice that same obscenity, most likely.
It doesn't have to be stored in plain text to validate it is correct. The phone operator could enter it into an authentication form to verify it is correct.
The concern isn't that there's no way to do it, it's that there's no reason to do it unless the plaintext is going to matter again in the future.
The best guess I've seen is that they might be hashing, but also having people read passwords to customer service reps. That would justify caring about rude plaintext, but it's also a terrible system.
Heh, to be fair, we are talking about a company with millions of customers that is consistently rated as "most hated" by consumers. I'd be surprised if a decent percentage of attempted passwords weren't "fuck time warner"...
Hah. I can see some poor support rep getting a dozen calls a day with insulting passwords, actually - maybe it's about reducing call center turnover...
An extremely large company I was involved in building a system for had a requirement that you be able to read your password over the phone to a call center agent, resulting in requirements like case insensitivity and character limits.
Terrible security, sure, but at least it came from the desire for usability, not just basic encryption idiocy.
Who said the text persists, you could take it off the phone and type it in to compare against any existing salted hash. Still not good security, but not necessarily stored in plaintext.
A former employer, that I will decline to mention by name, stored a hash of the password AND the plaintext in the database so it could be sent to people via email when they forgot it.
I tried to explain to my boss why this was such a terrible idea and he was not hearing any of it.
If I ever use the "forgot my password" functionality at a site and they mail out something that is probably my original password, I make a point of cancelling my account and sending them an e-mail explaining why I don't trust them any more.
They have two classes of site that they don’t distinguish to be fair. One is the awful “You’ve forgotten your password. It’s: xxxx” where they’re just storing the password in plaintext in the database.
The other is still not great but it’s less bad: “Thankyou for registering. Your registered password is: xxxx”. In this case they’ve just passed the user details to an emailer before (potentially) encrypting and storing them.
scarier still is when they let you set it but fail to let you log in (generally happens more with length). i don't know what you're doing, but i know it's not right and it scares the hell out of me
I had that happen because of length at an online service we needed to use in high school. I believe my password had 9 characters. After requesting a password reset and experimenting I found that the registration form would allow you to enter a password of any length, but the login form would only accept up to 8 characters. What really shocked me was that I was the only one of my classmates that used a password longer than 8 characters.
I see this all the time. They accept it and then when you go to log in, it fails. I usually try chopping it down to 32, 30, 24, 20, ... until I hit a match.
I've had that happen with Comcast. I think they fixed it but it was pretty annoying. The signup password input had no max length but the login form did.
At least you got a notification. One bank just stripped all of mine off and submitted like that. At least they were consistent about it, I didn't realize until I accidentally mistyped and still got in.
In disbelief I logged out, tried again but this time I intentionally didn't use any special characters. It worked....
Scarier still is when it's a server-side response that rejects my password for its contents...