Skip to content

Commit abdcc08

Browse files
committed
Handle OpenSSL::HMAC.new correctly
1 parent 4d952bb commit abdcc08

File tree

2 files changed

+58
-6
lines changed

2 files changed

+58
-6
lines changed

lib/rubocop/cop/github/insecure_hash_algorithm.rb

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,24 @@ class InsecureHashAlgorithm < Cop
3737
(send _ :Digest #insecure_algorithm?)
3838
PATTERN
3939

40+
# Matches calls like "OpenSSL::HMAC.new(secret, hash)"
41+
def_node_matcher :openssl_hmac_new?, <<-PATTERN
42+
(send (const (const _ :OpenSSL) :HMAC) :new ...)
43+
PATTERN
44+
45+
# Matches calls like "OpenSSL::HMAC.new(secret, 'sha1')"
46+
def_node_matcher :openssl_hmac_new_insecure?, <<-PATTERN
47+
(send (const (const _ :OpenSSL) :HMAC) :new _ #insecure_algorithm?)
48+
PATTERN
49+
4050
def insecure_algorithm?(val)
4151
return false if val == :Digest # Don't match "Digest::Digest".
42-
case str_val(val).downcase
52+
case alg_name(val)
4353
when *allowed_hash_functions
4454
false
55+
when Symbol
56+
# can't figure this one out, it's nil or a var or const.
57+
false
4558
else
4659
true
4760
end
@@ -68,11 +81,15 @@ def allowed_hash_functions
6881
@allowed_algorithms ||= cop_config.fetch("Allowed", DEFAULT_ALLOWED).map(&:downcase)
6982
end
7083

71-
def str_val(val)
72-
return "" if val.nil?
73-
return val.to_s unless val.is_a?(RuboCop::AST::Node)
74-
return val.children.first.to_s if val.type == :sym || val.type == :str
75-
raise "Unexpected: #{val.inspect}"
84+
def alg_name(val)
85+
return :nil if val.nil?
86+
return val.to_s.downcase unless val.is_a?(RuboCop::AST::Node)
87+
case val.type
88+
when :sym, :str
89+
val.children.first.to_s.downcase
90+
else
91+
val.type
92+
end
7693
end
7794

7895
def on_const(const_node)
@@ -83,6 +100,10 @@ def on_const(const_node)
83100

84101
def on_send(send_node)
85102
case
103+
when openssl_hmac_new?(send_node)
104+
if openssl_hmac_new_insecure?(send_node)
105+
add_offense(send_node, message: MSG)
106+
end
86107
when insecure_digest?(send_node)
87108
add_offense(send_node, message: MSG)
88109
when insecure_hash_lookup?(send_node)

test/test_insecure_hash_algorithm.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,37 @@ def bubblebabble_the_string_md5
2929
assert_equal 0, cop.offenses.count
3030
end
3131

32+
def test_openssl_hmac_new_sha256_indirect
33+
investigate(cop, <<-RUBY)
34+
class Something
35+
HASH = OpenSSL::Digest::SHA256
36+
37+
attr :secret
38+
39+
def secret_hmac
40+
OpenSSL::HMAC.new(self.secret, HASH)
41+
end
42+
end
43+
RUBY
44+
45+
assert_equal 0, cop.offenses.count
46+
end
47+
48+
def test_openssl_hmac_new_sha1
49+
investigate(cop, <<-RUBY)
50+
class Something
51+
attr :secret
52+
53+
def secret_hmac
54+
OpenSSL::HMAC.new(self.secret, 'sha1')
55+
end
56+
end
57+
RUBY
58+
59+
assert_equal 1, cop.offenses.count
60+
assert_equal cop_class::MSG, cop.offenses.first.message
61+
end
62+
3263
def test_digest_method_md5_str
3364
investigate(cop, <<-RUBY)
3465
class Something

0 commit comments

Comments
 (0)