From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS4713 221.184.0.0/13 X-Spam-Status: No, score=-3.4 required=3.0 tests=AWL,BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.1 Received: from neon.ruby-lang.org (neon.ruby-lang.org [221.186.184.75]) by dcvr.yhbt.net (Postfix) with ESMTP id 174AE208E8 for ; Tue, 24 Jul 2018 22:01:05 +0000 (UTC) Received: from neon.ruby-lang.org (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id 5FAE9120934; Wed, 25 Jul 2018 07:01:01 +0900 (JST) Received: from o1678948x4.outbound-mail.sendgrid.net (o1678948x4.outbound-mail.sendgrid.net [167.89.48.4]) by neon.ruby-lang.org (Postfix) with ESMTPS id DABC0120928 for ; Wed, 25 Jul 2018 07:00:58 +0900 (JST) Received: by filter0026p3iad2.sendgrid.net with SMTP id filter0026p3iad2-8334-5B57A194-12 2018-07-24 22:00:52.090980478 +0000 UTC m=+600911.588504683 Received: from herokuapp.com (ec2-54-221-28-188.compute-1.amazonaws.com [54.221.28.188]) by ismtpd0033p1mdw1.sendgrid.net (SG) with ESMTP id aULx6YkBTTyYrpj-ZoxOlA for ; Tue, 24 Jul 2018 22:00:51.840 +0000 (UTC) Date: Tue, 24 Jul 2018 22:00:52 +0000 (UTC) From: merch-redmine@jeremyevans.net To: ruby-core@ruby-lang.org Message-ID: References: Mime-Version: 1.0 X-Redmine-MailingListIntegration-Message-Ids: 63462 X-Redmine-Project: ruby-trunk X-Redmine-Issue-Id: 14915 X-Redmine-Issue-Author: jeremyevans0 X-Redmine-Sender: jeremyevans0 X-Mailer: Redmine X-Redmine-Host: bugs.ruby-lang.org X-Redmine-Site: Ruby Issue Tracking System X-Auto-Response-Suppress: All Auto-Submitted: auto-generated X-SG-EID: ync6xU2WACa70kv/Ymy4QrNMhiuLXJG8OTL2vJD1yS4AVr2nXlxNWqbOwTzHRLszP2c63W0240e3UZ Had0PEMc6KLe1sMGZ5gVCdYiGayYXWavDegHTqggyZmTIx2UpeIvvUrmPP2K5Lv1ZjMFVx1O6dLwxt 2geZSYIqGab8xQMCp6jTdkchInrnJt9csIfoEwH+1NCkh1+VjEZh9cvhvg== X-ML-Name: ruby-core X-Mail-Count: 88084 Subject: [ruby-core:88084] [Ruby trunk Feature#14915] Deprecate String#crypt, move implementation to string/crypt X-BeenThere: ruby-core@ruby-lang.org X-Mailman-Version: 2.1.15 Precedence: list Reply-To: Ruby developers List-Id: Ruby developers List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ruby-core-bounces@ruby-lang.org Sender: "ruby-core" Issue #14915 has been updated by jeremyevans0 (Jeremy Evans). jeremyevans0 (Jeremy Evans) wrote: > .htpasswd is an Apache-specific format, and Apache currently supports only 5 password formats: bcrypt, MD5, SHA1, crypt, plain text (https://httpd.apache.org/docs/2.4/misc/password_encryptions.html). Only bcrypt and MD5 are considered secure. The MD5 format uses a Apache-specific algorithm with 1000 iterations of MD5, and I'm not aware of a ruby implementation of it. I believe the bcrypt format is a standard bcrypt except that it uses `2y` instead of `2a` or `2b` as the version, but I have not tested this yet. I will test it and assuming the bcrypt format is compatible, that is probably the format we should recommend. Apache htpasswd generates passwords using `$2y$`, but the hashes are the same as `$2a$` format, and Apache handles `$2a$` format just fine. The bcrypt gem does not consider `$2y$` to match, but will work correctly if `$2y$` is changed to `$2a$`. According to Wikipedia (https://en.wikipedia.org/wiki/Bcrypt#Versioning_history), `$2y$` instead of `$2a$` was just to note that the hash was not generated by a bad version of the crypt_blowfish PHP library, otherwise the formats are identical. So to check the passwords in ruby, you would just need to do: `BCrypt::Password.new(password_hash.sub(/\A\$2y$/, '$2a$')) == submitted_password` Tested using Apache 2.4.33 with the following .htaccess file: ~~~ AuthType Basic AuthName "Restricted Files" AuthUserFile "/var/www/passwd" Require user foo bar ~~~ Where `/var/www/passwd` was populated: ~~~ cd /var/www touch passwd htpasswd -bB passwd foo foofoofoo ruby -r bcrypt -e 'puts BCrypt::Password.create("barbarbar")' > passwd ~~~ Testing that both foo and bar can login with the passwords, and that the ruby bcrypt library can correctly check password hashes generated by htpasswd if you do the `$2y$` to `$2a$` conversion as shown above. Should I prepare a patch to Webrick to accept :create_password_hash and :check_password_hash options, and add documentation with an example using bcrypt? ---------------------------------------- Feature #14915: Deprecate String#crypt, move implementation to string/crypt https://bugs.ruby-lang.org/issues/14915#change-73106 * Author: jeremyevans0 (Jeremy Evans) * Status: Open * Priority: Normal * Assignee: * Target version: ---------------------------------------- This method is system and implementation dependent, and the portable usage mentioned in the documentation is not truly portable (doesn't work on OpenBSD) and insecure as it uses DES. For systems that lack a crypt(3) implementation, Ruby will happily substitute a version that only supports DES. It's 2018, using DES should be avoided if at all possible. The only internal usage of String#crypt in Ruby is in Webrick, where it uses DES for basic authentication with an htpasswd file. That could and should be changed to use a more secure hash by default (bcrypt since that's the most secure htpasswd format), or at least allow the user to customize Webrick's authentication. I expect there are few if any users actively using Webrick's htpasswd support. This moves the String#crypt implementation to the string/crypt extension, but leaves the String#crypt core method. The core method prints a deprecation warning, then loads the string/crypt extension. The string/crypt extension undefines the String#crypt core method, then defines the previous implementation. Because extensions use extconf.rb instead of configure for their configuration, this ports the related configure.ac code to extconf.rb. I'm not sure that is done correctly and works on all platforms, it will need testing. For systems that lack a crypt(3) implementation, this modifies the fallback code to only define crypt_r, since that is the only function that String#crypt will call in that case. While the patch just deprecates String#crypt, I think we should plan to remove support from ruby: 2.6: core method deprecated 2.7: core method removed, string/crypt extension ships with ruby 2.8: string/crypt extension moves to external gem, not shipped ---Files-------------------------------- 0001-Deprecate-String-crypt-move-implementation-to-string.patch (20.5 KB) -- https://bugs.ruby-lang.org/