@@ -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 )
0 commit comments