28

I'm a listener of the podcast "Security Now" where they often claim that there are no reasons to limit the number of characters a user can use in their passwords when they create an account on a website. I have never understood how it is even technically possible to allow an unlimited number of characters and how it could not be exploited to create a sort of buffer overflow.

I found a related question here, but mine is slightly different. The author of the other question explicitly mentions in their description that they understand why setting a maximum length of 100000000 characters would be a problem. I actually want to know why it would be a problem, is it like I have just said because of buffer overflows? But to be vulnerable to a buffer overflow, shouldn't you have a sort of boundary which you can't exceed in the first place, and thus if you didn't limit the number of characters, would you even have this risk? And if you are thinking about starving a computer's RAM or resources, could even a very large password be a problem?

So, I guess it is possible not to limit the number of characters in a password: all you'd have to do would be to not use the maxlength attribute or not have a password validation function on the server side. Would that be the secure way to do it? And if it is, is there any danger in allowing an unlimited number of characters for your passwords? On the other hand, NIST recommends developers to allow for passwords up to 64 characters at least. If they take the time to recommend a limitation, does it mean there has to be one?

Some have suggested that this question could be a duplicate of my question. It is not. The other question starts from the premise that there is always a threshold on passwords, I was just wondering if there was a reason to put a threshold on passwords to begin with.

Thomas
  • 390
  • 3
  • 8
  • 9
    Generally speaking passwords are not stored in plain text but are hashed. Depending on the hash algorithm used, the maximum characters are limited by the algorithm. Calculating a hash of a password with 'unlimited' characters on the other hand would be rather CPU intensive. – Jeroen Sep 06 '20 at 19:26
  • When you say that the maximum characters are limited, you mean the characters of the hash? Isn't a hash function by definition a function that accepts an unlimited number of inputs but has only a limited number of outputs? So, if I understand your argument, do you mean that it's technically feasible but that it would just be intensive? – Thomas Sep 06 '20 at 19:29
  • 4
    Unless using a low-level language, an application developer typically doesn't need to worry about buffer overflows in their own code. – multithr3at3d Sep 06 '20 at 22:46
  • 1
    Hash functions don't actually accept an unlimited amount of input. Many have a character limit including modern ones. Considering that no computer system can accept "unlimited" input, there is clearly a limit somewhere. – Conor Mancone Sep 07 '20 at 01:50
  • I wonder how long it takes the fastest keyboard-like-device to send this Question's hypothetical 100 MB maximum length password. We should assume that every character uses a different subset of shifts. (Go [double bucky coke bottle](http://catb.org/~esr/jargon/html/Q/quadruple-bucky.html).) – Eric Towers Sep 07 '20 at 05:49
  • @RoryAlsop Why do you say Steve Gibson is a renowned charlatan? Can you give an example of what he says that doesn't make sense? – Thomas Sep 09 '20 at 15:21
  • @Thomas easy start point: http://attrition.org/errata/charlatan/steve_gibson/ but you'll find all manner of commentary on reddit, and in fact on here. Your question is good though, hence the upvotes – Rory Alsop Sep 09 '20 at 16:01
  • If you did a preliminary hashing client-side before sending it to the server (which I would recommend, it doesn't cost you anything), the processing of the gigabytes of password would happen client-side; from the network perspective, you could reject anything that doesn't have the N characters you expect the client-side hash to return. – Carson Graham Sep 10 '20 at 01:26

2 Answers2

73

A limit is recommended simply to avoid exhausting resources on the server.

Without a limit, an attacker could call the login endpoint with an extremely large password, say a gigabyte (let's ignore whether it's practical to send that much at once. You could instead send 10MB at a time, but more quickly).

Any work the server needs to do on the password will now be that much more expensive. This applies not just to password hashing but every level of processing to reassemble the packets and get them to the application. Memory usage on the server also increases considerably.

Just a few concurrent 10MB login requests will start having an impact on server performance, perhaps to the point of exhausting resources and triggering a denial of service.

These may not be security issues in the sense of password/data leakage but crippling a service by DOS or crashing definitely is. Note that I make no mention of buffer overflow: decent code can handle arbitrarily big passwords without overflowing.

To wrap up, I think when someone says "there's no reason to limit the number of characters of a password", they are talking about commonly seen small limits (eg: 10 or 20 characters). There is indeed no reason for those other than laziness or working with old systems. A limit of 256 characters which is larger than desired by most people (except those testing those limits) is reasonable and can prevent some of the issues related to arbitrarily-large payloads.

Marc
  • 4,091
  • 1
  • 17
  • 23
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackexchange.com/rooms/112735/discussion-on-answer-by-marc-is-there-any-security-risk-in-not-setting-a-maximum). – schroeder Sep 07 '20 at 08:31
  • 4
    I don't think that limiting the password length is a helping against DOS attacks. The password length probably will be checked in the application code, that means the request already passed the infrastructure and processing in between. Of course it would be convenient for the attacker if you pass unchecked requests to your password hashing algorithm, but if you don't reject them early on you're vulnerable by DOS anyway. – Christian Strempfer Sep 07 '20 at 16:27
  • If the language/libraries used are reasonable about processing/copying network requests, validating inputs will be sufficient, the OS can likely handle it. What happens after is what is likely to cause trouble (eg: multiple copies within your handler, expensive hashing, etc...). Or at least, the OS can handle orders of magnitude more than the application code can. – Marc Sep 07 '20 at 16:30
  • 2
    @Marc Do you have any evidence for this DOS? I looked into this a couple years ago and determined that any extremely long password DOS was likely to DOS the network before the CPU as long as the hash was implemented efficiently. Every password hash I've looked at has some sort of quick initial hash that's fast enough that performance on large inputs is a non-issue. – AndrolGenhald Sep 07 '20 at 17:37
  • There's [this](https://www.djangoproject.com/weblog/2013/sep/15/security/) from 2013, but that's due to old versions of openssl having an inefficient implementation of PBKDF2 (hashing the password as the HMAC key for each round instead of prehashing once and reusing the result). – AndrolGenhald Sep 07 '20 at 17:38
  • You may have a point as far as request size in general causing memory issues assuming it isn't streamed into the hash function (and why would someone bother implementing that?), but that seems to me like a general issue that's not specific to password length limitations, and that needs to be handled on a different level. – AndrolGenhald Sep 07 '20 at 17:41
  • True, it's more of a request size and input valuation issue. One big difference between login and other requests is that others tend to be behind authentication and will fail earlier. I've seen DOS from cpu starvation due to password hashing and combined memory blowup due to pending requests. If those requests have larger payloads, it just gets worse. You can of course reproduce that with a lot of concurrent login requests and any large request on the side. – Marc Sep 07 '20 at 17:51
  • Many web servers/reverse proxies set request size limits. At least nginx you can filter this on the uri, if for some reason you wanted to allow massive POSTs to that endpoint – richard Sep 07 '20 at 20:32
  • @ChristianStrempfer employing a size restriction does not prevent a DOS of another kind from happening, but it makes it more difficult. Instead of just sending you one request that crashes your application / exhausts the memory limit, I need to find another flaw or potentially send a gazillion requests to actually overload your resources instead of using a straight forward weakness where rate limiting, for instance, couldn't help because my rate is perfectly fine. – Frank Hopkins Sep 08 '20 at 19:10
  • @FrankHopkins I agree with that. Still that's not specific for passwords, but any kind of input that's taken for computations, and there are better places to enforce size restrictions. So my suggestion for the answer is to focus more on the waste of resources and less on the DOS scenario. – Christian Strempfer Sep 08 '20 at 19:27
11

Passwords should be hashed/salted. In addition to possible DoS attack risk from GB-size passwords, OWASP recommends limiting the password length because:

Some hashing algorithms such as Bcrypt have a maximum length for the input, which is 72 characters for most implementations (there are some reports that other implementations have lower maximum lengths, but none have been identified at the time of writing). Where Bcrypt is used, a maximum length of 64 characters should be enforced on the input, as this provides a sufficiently high limit, while still allowing for string termination issues and not revealing that the application uses Bcrypt.

Due to this and the potential for DoS, they recommend a limit of 64 characters for Bcrypt (due to limitations in the algorithm and implementations), and between 64 and 128 characters for other algorithms.

Kyle Fennell
  • 921
  • 4
  • 12
  • 5
    A better recommendation would be to not use Bcrypt. – A. Hersean Sep 07 '20 at 08:38
  • 14
    There's no reason to hide the fact that you're using bcrypt. Also note that the limit is 72 **bytes**, not 72 characters. – OrangeDog Sep 07 '20 at 11:30
  • 2
    @A.Hersean Why not? And what do you recommend instead? – Suppen Sep 09 '20 at 06:19
  • If there is a limit on the number of characters the hash function uses, wouldn't it still make sense to use the longer input to increase the entropy in the input to hash function? I would expect even something as simple as taking the excess bytes, shifting them by few bits and XORing them with the initial 72 bytes to meaningfully increase the strength of the password (provided the original password is from a restricted set of characters, e.g. alphanumeric). – Martin Modrák Sep 09 '20 at 07:55
  • @Suppen because the keyspace is being limited to 72 bytes? A keyspace of more than that is better than that. Unless you're somehow in an embedded environment that only has circuitry for bcrypt, then an alternative without such restrictions is better. I'd recommend Argon2 or PBKDF2. – Adam Barnes Sep 09 '20 at 10:38
  • @OrangeDog Bcrypt is outdated and does not handle null bytes (that's a security vulnerability). Scrypt would be slightly better, Argon2 far better. – A. Hersean Sep 09 '20 at 13:12
  • @AdamBarnes PBKDF2 is weaker than bcrypt. Hardware crackers for it are significantly cheaper and faster. – OrangeDog Sep 09 '20 at 13:37
  • @OrangeDog I'd be interested to read more on that claim. – Adam Barnes Sep 10 '20 at 14:26
  • @AdamBarnes [The scrypt paper](https://www.tarsnap.com/scrypt/scrypt.pdf) compares them. – OrangeDog Sep 10 '20 at 14:56