Hacker News new | ask | show | jobs
by fruchtose 4824 days ago
There's one reason I haven't seen mentioned yet:

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.

3 comments

Because the developer is storing passwords in plaintext, and he wants to save database space.

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.

If you allow truly unlimited-length passwords, malicious users can set gigabyte-long passwords. Whether you hash them or just store them, that's a DoS waiting to happen with every login.

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.

While this is true, hashes use a set number of characters. For example, SHA-256 hashes can be stored in 32-character hex strings. In that sense, there's no point in allowing for a variable length field for password hashes.
It's not only dealing with password length. You could DoS the server by tying up all threads in processing the upload. Uploading 4GB isn't instantaneous.
For the application code to complain about password length then the 4gb upload has to have already occurred.

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'm not arguing with that. I wholly agree with you that a client should not be able to upload 4 GB for the password field. I think I misread your first point as if it dealt with server-side storage.
That's why the client should perform the hash and only submit the result.
No; this is effectively the same as doing no hashing at all. If your database gets stolen, people can replay the "hashed" passwords from it to the server, without having to hash them themselves.
Some developers love that kind of micro optimizations. Even smart ones. I've had my varchar(256) columns changed to a more modest varchar(30) because I was "wasting space." Those people dont like being wrong either so there's no point arguing it either and instead concentrate on the bigger issues.
I've seen that, but once the internal format is actually explained, varchar(256) generally survives.

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.

I believe in InnoDB the way text and varchar(X) is stored is exactly the same. They both only use as much space as the data they are storing requires. However if you pass a 101 character string to a varchar(100) it will be truncated. I'd guess that is useful in some cases, but in reality you probably want to do the truncation in your application so you have more control over it.
Truncation is the failure mode which MySQL describes as a feature.

Don't use MySQL.

Thanks for the explanation, didn't know that.

Is this true in most modern DBs? (I'm thinking MySQL and Postgres particularly).

Close enough in PostgreSQL. String columns larger than 256 actually use 4 bytes to indicate the length, but on the other hand, large strings are automatically compressed, so they may use less space than 4 + length.

http://www.postgresql.org/docs/9.2/static/datatype-character...

I recently discovered its a similar case for numbers in Oracle, which slightly surprised me.
I would think that the kind of developer that considers it acceptable to store passwords in plaintext could easily be the kind of developer that would make arbitrary decisions based on feelings rather calculating the actual likely storage a longer limit would result in to make an informed decision...
Just use ROT13 - same space requirements as in plaintext

(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)

One iteration of ROT13 is too fast to compute to guarantee any sort of security. If you really want to secure your passwords, make sure you perform 2↑↑100 iterations of ROT13 or so to ensure substantial computational cost to the operation.
Yeah- you need at least rot26 or else it's just too easy to crack with today's technology. But everybody ought to know that. (Hey! It's April 1st somewhere...um, or will be in a few hours)
Fortunately I've already upgraded my encryption to rot52.
Even if saving database space is a concern, you could store a truncated password hash.
If you don't use the full hash, I believe you can't really make any guarantees about the variance and distribution of characters in the hash. So not sure that's such a good idea.
If you'll go as far as saving a truncated hash, it's better to just save the whole thing. I don't see any good reasons not to.