Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:114102 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 3910 invoked from network); 22 Apr 2021 14:19:15 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 22 Apr 2021 14:19:15 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 918F41804D8 for ; Thu, 22 Apr 2021 07:22:17 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: **** X-Spam-Status: No, score=4.0 required=5.0 tests=BAYES_50, HEADER_FROM_DIFFERENT_DOMAINS,HTML_MESSAGE,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_SOFTFAIL autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-lj1-f173.google.com (mail-lj1-f173.google.com [209.85.208.173]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Thu, 22 Apr 2021 07:22:16 -0700 (PDT) Received: by mail-lj1-f173.google.com with SMTP id u20so52039781lja.13 for ; Thu, 22 Apr 2021 07:22:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=UIBvNdPmZ610jk1vOqOW4XIQEcHH0aiQ5dzmBZRybJY=; b=Lcxm/oP1XYgkM14xFy8CXjjOl3VRxO8CNQTaZCC5aL/4NiAy4xGeCUfGR7iUxjmjZY 0o47ZBFmDN0Uq5ZC9d9p5COgyg+PBfteMdD0PD8da2qINHJ29+QBN/So7eYhxNFaAl81 G0gitm2mmLhwtd5lskslxGhk2EFAnfQSiR1RniBPH20Ya3V+QS4w5/oqSN8eMie0SL14 v6CtCjS+SQp0Hyq+rKUKJydy8lMrZuHTf5HbGYFe+MTaqVi7GSBR1GLBpLBGItDglONs jPQp6EBHwnJA2Vq7igGvYGYoVmQ7oWnwb74aPcdz1XD/mBP2vO21aQts3JAKZ8ou/MlK gs2Q== X-Gm-Message-State: AOAM531V0fHEvNTX4tkaf02hB/FY+NpcOYlNWAiVeYF7LoL/AjqDQPPq NKzX7xFbefhpWkqD7Xb5D253GNE+5J6SETUd+pjCJA== X-Google-Smtp-Source: ABdhPJwcjLWQnfpAUYSYWWBotcFWT2/4WXqrvG2GRCRRAXAmMyCTIxu2WRGmWLO7in1B+lOJQGQr6IijOsZuzQ1Y7P4= X-Received: by 2002:a2e:a543:: with SMTP id e3mr2597592ljn.433.1619101334634; Thu, 22 Apr 2021 07:22:14 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Thu, 22 Apr 2021 09:22:03 -0500 Message-ID: To: Nikita Popov Cc: PHP internals , Anthony Ferrara Content-Type: multipart/alternative; boundary="000000000000e8130905c0906749" Subject: Re: [PHP-DEV] Binary (un)safety of password_hash() used with PASSWORD_BCRYPT From: pollita@php.net (Sara Golemon) --000000000000e8130905c0906749 Content-Type: text/plain; charset="UTF-8" On Thu, Apr 22, 2021 at 3:06 AM Nikita Popov wrote: > I don't think this is a good idea. > Fair, and that objection alone is enough to merit going RFC if I decide to proceed with this. > This adds an error condition that is based on the input string, which is generally user-provided. > As there is nothing in the default stack preventing null bytes from passing in via HTTP (correct me if I'm wrong), > this means the error can be trivially triggered, probably on about any PHP application using password_hash(). > Correct on all counts. However I see that as a good thing. The site developer no longer is left in a state where they have less security than they think they have. Say they have a minimum password length constraint (quite common), and that check has passed, "Yes, the user came up with a password that's at least 20 character long, good." Now they pass that into password_hash(), but because they didn't check for null bytes, the password that actually gets hashed is only three bytes long, or maybe even an empty string. Nobody in the chain realizes this is the case, because why on Earth would it be? > I'm not sure what problem you're actually trying to solve here. Ultimately, all this allows is a user to shoot themselves in the foot if they want to -- and they do need to try actively, it's not like you can end up with a null byte in a password by accident. > Niklas' reply just prior to yours actually offers a case where that's not unlikely. > it's more likely the developer uses a hash function with raw output as a pre-encoding, > for reasons such as bringing long passwords below the bcrypt character limit. I hadn't actually considered this, but it makes null bytes showing up in an input password not only possible, but reasonably likely. In fact, there's a 1/256 chance that the lead byte would be null making their effective password into an empty string from bcrypt's point of view. This means that a brute force attack trying to login as that user would also have a 1/256 chance of match it since the hashed version of a completely dissimilar password is also empty. The actual attack complexity has a worst case of 1/65536 since they have to try lead-null hashable passwords on all users as they won't know which have the unlucky property of having already hashed into a lead-null input. Though if the pre-hash algorithm is known they could probably bring this back to 1/256 by precomputing lead-null hashing inputs before scanning users for a match. Yes, this is something that can be addressed in userspace, but is it? I don't actually know the answer to that, but it worries me. -Sara --000000000000e8130905c0906749--