/
check_basic_auth.rb
88 lines (72 loc) · 2.35 KB
/
check_basic_auth.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
require 'brakeman/checks/base_check'
#Checks if password is stored in controller
#when using http_basic_authenticate_with
#
#Only for Rails >= 3.1
class Brakeman::CheckBasicAuth < Brakeman::BaseCheck
Brakeman::Checks.add self
@description = "Checks for the use of http_basic_authenticate_with"
def run_check
return if version_between? "0.0.0", "3.0.99"
check_basic_auth_filter
check_basic_auth_request
end
def check_basic_auth_filter
controllers = tracker.controllers.select do |name, c|
c.options[:http_basic_authenticate_with]
end
Hash[controllers].each do |name, controller|
controller.options[:http_basic_authenticate_with].each do |call|
if pass = get_password(call) and string? pass
warn :controller => name,
:warning_type => "Basic Auth",
:warning_code => :basic_auth_password,
:message => "Basic authentication password stored in source code",
:code => call,
:confidence => 0,
:file => controller.file
break
end
end
end
end
# Look for
# authenticate_or_request_with_http_basic do |username, password|
# username == "foo" && password == "bar"
# end
def check_basic_auth_request
tracker.find_call(:target => nil, :method => :authenticate_or_request_with_http_basic).each do |result|
if include_password_literal? result
warn :result => result,
:code => @include_password,
:warning_type => "Basic Auth",
:warning_code => :basic_auth_password,
:message => "Basic authentication password stored in source code",
:confidence => 0
end
end
end
# Check if the block of a result contains a comparison of password to string
def include_password_literal? result
@password_var = result[:block_args].last
@include_password = false
process result[:block]
@include_password
end
# Looks for :== calls on password var
def process_call exp
target = exp.target
if node_type?(target, :lvar) and
target.value == @password_var and
exp.method == :== and
string? exp.first_arg
@include_password = exp
end
exp
end
def get_password call
arg = call.first_arg
return false if arg.nil? or not hash? arg
hash_access(arg, :password)
end
end