From b6ab1081cec15574e67ac91b2c30540e562748c4 Mon Sep 17 00:00:00 2001 From: "G. Ryan Sablosky" Date: Wed, 23 Mar 2022 10:26:32 -0400 Subject: [PATCH 1/3] Fix bcrypt salt regex checks The two-digit header of a bcrypt salt is a strength parameter. Valid values for the strength parameter range from 4 to 31 inclusive. Update the regex used to check the salt to only match against values from 04 to 31. --- lib/puppet/parser/functions/pw_hash.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/puppet/parser/functions/pw_hash.rb b/lib/puppet/parser/functions/pw_hash.rb index 67346efeb..728656c4e 100644 --- a/lib/puppet/parser/functions/pw_hash.rb +++ b/lib/puppet/parser/functions/pw_hash.rb @@ -48,10 +48,10 @@ 'md5' => { prefix: '1' }, 'sha-256' => { prefix: '5' }, 'sha-512' => { prefix: '6' }, - 'bcrypt' => { prefix: '2b', salt: %r{^[0-9]{2}\$[./A-Za-z0-9]{22}} }, - 'bcrypt-a' => { prefix: '2a', salt: %r{^[0-9]{2}\$[./A-Za-z0-9]{22}} }, - 'bcrypt-x' => { prefix: '2x', salt: %r{^[0-9]{2}\$[./A-Za-z0-9]{22}} }, - 'bcrypt-y' => { prefix: '2y', salt: %r{^[0-9]{2}\$[./A-Za-z0-9]{22}} }, + 'bcrypt' => { prefix: '2b', salt: %r{^(0[4-9]|[12][0-9]|3[01])\$[./A-Za-z0-9]{22}} }, + 'bcrypt-a' => { prefix: '2a', salt: %r{^(0[4-9]|[12][0-9]|3[01])\$[./A-Za-z0-9]{22}} }, + 'bcrypt-x' => { prefix: '2x', salt: %r{^(0[4-9]|[12][0-9]|3[01])\$[./A-Za-z0-9]{22}} }, + 'bcrypt-y' => { prefix: '2y', salt: %r{^(0[4-9]|[12][0-9]|3[01])\$[./A-Za-z0-9]{22}} }, } raise ArgumentError, 'pw_hash(): first argument must be a string' unless args[0].is_a?(String) || args[0].nil? From 5376514fe78548058b463bfe712f78fb05784374 Mon Sep 17 00:00:00 2001 From: "G. Ryan Sablosky" Date: Wed, 23 Mar 2022 11:14:21 -0400 Subject: [PATCH 2/3] Add tests for invalid strength parameters --- spec/functions/pw_hash_spec.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/spec/functions/pw_hash_spec.rb b/spec/functions/pw_hash_spec.rb index f7a827d7f..595f136eb 100644 --- a/spec/functions/pw_hash_spec.rb +++ b/spec/functions/pw_hash_spec.rb @@ -58,6 +58,17 @@ it { is_expected.to run.with_params('password', 'bcrypt-y', '1234').and_raise_error(ArgumentError, %r{characters in salt must match}) } end + context 'when the third argument has an invalid strength parameter for bcrypt' do + it { is_expected.to run.with_params('password', 'bcrypt', '03$salt.salt.salt.salt.sa').and_raise_error(ArgumentError, %r{characters in salt must match}) } + it { is_expected.to run.with_params('password', 'bcrypt-a', '03$salt.salt.salt.salt.sa').and_raise_error(ArgumentError, %r{characters in salt must match}) } + it { is_expected.to run.with_params('password', 'bcrypt-x', '03$salt.salt.salt.salt.sa').and_raise_error(ArgumentError, %r{characters in salt must match}) } + it { is_expected.to run.with_params('password', 'bcrypt-y', '03$salt.salt.salt.salt.sa').and_raise_error(ArgumentError, %r{characters in salt must match}) } + it { is_expected.to run.with_params('password', 'bcrypt', '32$salt.salt.salt.salt.sa').and_raise_error(ArgumentError, %r{characters in salt must match}) } + it { is_expected.to run.with_params('password', 'bcrypt-a', '32$salt.salt.salt.salt.sa').and_raise_error(ArgumentError, %r{characters in salt must match}) } + it { is_expected.to run.with_params('password', 'bcrypt-x', '32$salt.salt.salt.salt.sa').and_raise_error(ArgumentError, %r{characters in salt must match}) } + it { is_expected.to run.with_params('password', 'bcrypt-y', '32$salt.salt.salt.salt.sa').and_raise_error(ArgumentError, %r{characters in salt must match}) } + end + context 'when running on a platform with a weak String#crypt implementation' do before(:each) { allow_any_instance_of(String).to receive(:crypt).with('$1$1').and_return('a bad hash') } # rubocop:disable RSpec/AnyInstance : Unable to find a viable replacement From 90a8760ee420e616c0ff24c74600687a74124594 Mon Sep 17 00:00:00 2001 From: "G. Ryan Sablosky" Date: Fri, 14 Oct 2022 15:27:53 -0400 Subject: [PATCH 3/3] Add explanatory note to docstring for pw_hash mention the meaning of the first two characters as a strength parameter --- lib/puppet/parser/functions/pw_hash.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/pw_hash.rb b/lib/puppet/parser/functions/pw_hash.rb index 728656c4e..a99a3ea29 100644 --- a/lib/puppet/parser/functions/pw_hash.rb +++ b/lib/puppet/parser/functions/pw_hash.rb @@ -25,7 +25,9 @@ |bcrypt-x |2x |bug compatible | |bcrypt-y |2y |historic alias for 2b| - The third argument to this function is the salt to use. + The third argument to this function is the salt to use. For bcrypt-type hashes, + the first two characters of the salt represent a strength parameter, with a value + between 4 and 31 inclusive. @return [String] Provides a crypt hash usable on most POSIX systems.