On Thu, Apr 22, 2021 at 11:04 AM Kamil Tekiela <tekiela...@gmail.com> wrote:
>
> I don't like throwing exceptions for pretty much the same reasons as
Nikita described.
> This is a rather limited attack vector. It depends either on the user
going out of their way
> to make their password vulnerable or on the developer introducing the
vulnerability with
> the use of another function mangling the passwords. The latter is more
likely. In your
> example, you had to make the output of MD5 binary to make the function
fail. In fact,
> as far as I know, browsers strip NUL bytes or convert them to Unicode
unknown character.
> See spec
https://html.spec.whatwg.org/multipage/parsing.html#parse-error-unexpected-null-character
>
To simplify this discussion, let's take it as a given that we're not
getting nul bytes directly from the end user, or if we are that they
deserve what they get.

I'd like to focus on the other case, where pre-digests are done.  I'll
agree that it's the framework author doing something unexpected that puts
us in this situation, but I don't agree that them doing so is unreasonable.
It's known that bcrypt has a length limitation.  It's also clear that bits
of collision space are wasted by using ascii input. Those two facts make
producing binary output from a pre-digest function entirely reasonable.
Specifically, the largest output digest function available for the input
space.  sha512 produces 64 bytes of output which fit neatly into bcrypt's
72 character limit.
There is a 64 * (1/256) chance that at least one of those octets is a \0.
Or more concisely 1 in 8.  The degree to which this weakens the password
depends on the specific position, anywhere from negligible (last position)
to complete (first position).

I don't like 1/8 odds of my password being made less secure due to a poor
understanding of the limits of the default* password algorithm. That's my
motivation.

* bcrypt being the only "always available" algorithm is an issue unto
itself and deserves a separate thread.

> As for PHP's behaviour, what we could do is strip NUL bytes before
hashing with bcrypt.
> This would still weaken passwords, but at least wouldn't discard the rest
of the string.
>
That's an option, but then we run into multi-version incompatibilities.
If a machine running 8.1 hashes "foo\0bar" (meaning it effectively hashes
"foobar"), other machines running 8.1+ can verify it just fine, but any
machine running 8.0- try to verify against "foo", and fail.
This is a specific issue for heterogeneous deployments, so maybe that's a
tolerable thing, but I'd probably introduce it in a major (e.g. 9.0).  We
could add the fallback check in verify now, and the change to hash in 9.0
so that the only way it'd fail would be producing on 9.0+ but verifying on
8.0- which is a bit extreme in terms of mixed deployments.

I'll be honest, I'd probably defer the exception in this PR until 9.0 as
well, given the pushback.

> We could also add a warning to the manual explaining that the function is
not binary safe.
>

100%  Gonna do that regardless of any decision made here.

-Sara

>

Reply via email to