brakeman-lib 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGES +872 -0
- data/FEATURES +16 -0
- data/README.md +169 -0
- data/WARNING_TYPES +95 -0
- data/bin/brakeman +89 -0
- data/lib/brakeman.rb +495 -0
- data/lib/brakeman/app_tree.rb +161 -0
- data/lib/brakeman/brakeman.rake +17 -0
- data/lib/brakeman/call_index.rb +219 -0
- data/lib/brakeman/checks.rb +191 -0
- data/lib/brakeman/checks/base_check.rb +518 -0
- data/lib/brakeman/checks/check_basic_auth.rb +88 -0
- data/lib/brakeman/checks/check_basic_auth_timing_attack.rb +33 -0
- data/lib/brakeman/checks/check_content_tag.rb +160 -0
- data/lib/brakeman/checks/check_create_with.rb +75 -0
- data/lib/brakeman/checks/check_cross_site_scripting.rb +385 -0
- data/lib/brakeman/checks/check_default_routes.rb +86 -0
- data/lib/brakeman/checks/check_deserialize.rb +57 -0
- data/lib/brakeman/checks/check_detailed_exceptions.rb +55 -0
- data/lib/brakeman/checks/check_digest_dos.rb +38 -0
- data/lib/brakeman/checks/check_dynamic_finders.rb +49 -0
- data/lib/brakeman/checks/check_escape_function.rb +21 -0
- data/lib/brakeman/checks/check_evaluation.rb +36 -0
- data/lib/brakeman/checks/check_execute.rb +167 -0
- data/lib/brakeman/checks/check_file_access.rb +63 -0
- data/lib/brakeman/checks/check_file_disclosure.rb +35 -0
- data/lib/brakeman/checks/check_filter_skipping.rb +31 -0
- data/lib/brakeman/checks/check_forgery_setting.rb +74 -0
- data/lib/brakeman/checks/check_header_dos.rb +31 -0
- data/lib/brakeman/checks/check_i18n_xss.rb +48 -0
- data/lib/brakeman/checks/check_jruby_xml.rb +38 -0
- data/lib/brakeman/checks/check_json_encoding.rb +47 -0
- data/lib/brakeman/checks/check_json_parsing.rb +107 -0
- data/lib/brakeman/checks/check_link_to.rb +132 -0
- data/lib/brakeman/checks/check_link_to_href.rb +115 -0
- data/lib/brakeman/checks/check_mail_to.rb +49 -0
- data/lib/brakeman/checks/check_mass_assignment.rb +198 -0
- data/lib/brakeman/checks/check_mime_type_dos.rb +39 -0
- data/lib/brakeman/checks/check_model_attr_accessible.rb +55 -0
- data/lib/brakeman/checks/check_model_attributes.rb +119 -0
- data/lib/brakeman/checks/check_model_serialize.rb +67 -0
- data/lib/brakeman/checks/check_nested_attributes.rb +38 -0
- data/lib/brakeman/checks/check_nested_attributes_bypass.rb +58 -0
- data/lib/brakeman/checks/check_number_to_currency.rb +74 -0
- data/lib/brakeman/checks/check_quote_table_name.rb +40 -0
- data/lib/brakeman/checks/check_redirect.rb +215 -0
- data/lib/brakeman/checks/check_regex_dos.rb +69 -0
- data/lib/brakeman/checks/check_render.rb +92 -0
- data/lib/brakeman/checks/check_render_dos.rb +37 -0
- data/lib/brakeman/checks/check_render_inline.rb +54 -0
- data/lib/brakeman/checks/check_response_splitting.rb +21 -0
- data/lib/brakeman/checks/check_route_dos.rb +42 -0
- data/lib/brakeman/checks/check_safe_buffer_manipulation.rb +31 -0
- data/lib/brakeman/checks/check_sanitize_methods.rb +79 -0
- data/lib/brakeman/checks/check_secrets.rb +40 -0
- data/lib/brakeman/checks/check_select_tag.rb +60 -0
- data/lib/brakeman/checks/check_select_vulnerability.rb +60 -0
- data/lib/brakeman/checks/check_send.rb +48 -0
- data/lib/brakeman/checks/check_send_file.rb +19 -0
- data/lib/brakeman/checks/check_session_manipulation.rb +36 -0
- data/lib/brakeman/checks/check_session_settings.rb +170 -0
- data/lib/brakeman/checks/check_simple_format.rb +59 -0
- data/lib/brakeman/checks/check_single_quotes.rb +101 -0
- data/lib/brakeman/checks/check_skip_before_filter.rb +60 -0
- data/lib/brakeman/checks/check_sql.rb +660 -0
- data/lib/brakeman/checks/check_sql_cves.rb +101 -0
- data/lib/brakeman/checks/check_ssl_verify.rb +49 -0
- data/lib/brakeman/checks/check_strip_tags.rb +89 -0
- data/lib/brakeman/checks/check_symbol_dos.rb +64 -0
- data/lib/brakeman/checks/check_symbol_dos_cve.rb +30 -0
- data/lib/brakeman/checks/check_translate_bug.rb +45 -0
- data/lib/brakeman/checks/check_unsafe_reflection.rb +51 -0
- data/lib/brakeman/checks/check_unscoped_find.rb +41 -0
- data/lib/brakeman/checks/check_validation_regex.rb +116 -0
- data/lib/brakeman/checks/check_weak_hash.rb +151 -0
- data/lib/brakeman/checks/check_without_protection.rb +80 -0
- data/lib/brakeman/checks/check_xml_dos.rb +51 -0
- data/lib/brakeman/checks/check_yaml_parsing.rb +121 -0
- data/lib/brakeman/differ.rb +66 -0
- data/lib/brakeman/file_parser.rb +50 -0
- data/lib/brakeman/format/style.css +133 -0
- data/lib/brakeman/options.rb +301 -0
- data/lib/brakeman/parsers/rails2_erubis.rb +6 -0
- data/lib/brakeman/parsers/rails2_xss_plugin_erubis.rb +48 -0
- data/lib/brakeman/parsers/rails3_erubis.rb +74 -0
- data/lib/brakeman/parsers/template_parser.rb +89 -0
- data/lib/brakeman/processor.rb +102 -0
- data/lib/brakeman/processors/alias_processor.rb +1013 -0
- data/lib/brakeman/processors/base_processor.rb +277 -0
- data/lib/brakeman/processors/config_processor.rb +14 -0
- data/lib/brakeman/processors/controller_alias_processor.rb +273 -0
- data/lib/brakeman/processors/controller_processor.rb +326 -0
- data/lib/brakeman/processors/erb_template_processor.rb +80 -0
- data/lib/brakeman/processors/erubis_template_processor.rb +104 -0
- data/lib/brakeman/processors/gem_processor.rb +57 -0
- data/lib/brakeman/processors/haml_template_processor.rb +190 -0
- data/lib/brakeman/processors/lib/basic_processor.rb +37 -0
- data/lib/brakeman/processors/lib/find_all_calls.rb +223 -0
- data/lib/brakeman/processors/lib/find_call.rb +183 -0
- data/lib/brakeman/processors/lib/find_return_value.rb +134 -0
- data/lib/brakeman/processors/lib/processor_helper.rb +75 -0
- data/lib/brakeman/processors/lib/rails2_config_processor.rb +145 -0
- data/lib/brakeman/processors/lib/rails2_route_processor.rb +313 -0
- data/lib/brakeman/processors/lib/rails3_config_processor.rb +132 -0
- data/lib/brakeman/processors/lib/rails3_route_processor.rb +308 -0
- data/lib/brakeman/processors/lib/render_helper.rb +181 -0
- data/lib/brakeman/processors/lib/render_path.rb +107 -0
- data/lib/brakeman/processors/lib/route_helper.rb +68 -0
- data/lib/brakeman/processors/lib/safe_call_helper.rb +16 -0
- data/lib/brakeman/processors/library_processor.rb +119 -0
- data/lib/brakeman/processors/model_processor.rb +191 -0
- data/lib/brakeman/processors/output_processor.rb +171 -0
- data/lib/brakeman/processors/route_processor.rb +17 -0
- data/lib/brakeman/processors/slim_template_processor.rb +107 -0
- data/lib/brakeman/processors/template_alias_processor.rb +116 -0
- data/lib/brakeman/processors/template_processor.rb +74 -0
- data/lib/brakeman/report.rb +78 -0
- data/lib/brakeman/report/config/remediation.yml +71 -0
- data/lib/brakeman/report/ignore/config.rb +135 -0
- data/lib/brakeman/report/ignore/interactive.rb +311 -0
- data/lib/brakeman/report/renderer.rb +24 -0
- data/lib/brakeman/report/report_base.rb +286 -0
- data/lib/brakeman/report/report_codeclimate.rb +70 -0
- data/lib/brakeman/report/report_csv.rb +55 -0
- data/lib/brakeman/report/report_hash.rb +23 -0
- data/lib/brakeman/report/report_html.rb +216 -0
- data/lib/brakeman/report/report_json.rb +42 -0
- data/lib/brakeman/report/report_markdown.rb +156 -0
- data/lib/brakeman/report/report_table.rb +107 -0
- data/lib/brakeman/report/report_tabs.rb +17 -0
- data/lib/brakeman/report/templates/controller_overview.html.erb +22 -0
- data/lib/brakeman/report/templates/controller_warnings.html.erb +21 -0
- data/lib/brakeman/report/templates/error_overview.html.erb +29 -0
- data/lib/brakeman/report/templates/header.html.erb +58 -0
- data/lib/brakeman/report/templates/ignored_warnings.html.erb +25 -0
- data/lib/brakeman/report/templates/model_warnings.html.erb +21 -0
- data/lib/brakeman/report/templates/overview.html.erb +38 -0
- data/lib/brakeman/report/templates/security_warnings.html.erb +23 -0
- data/lib/brakeman/report/templates/template_overview.html.erb +21 -0
- data/lib/brakeman/report/templates/view_warnings.html.erb +34 -0
- data/lib/brakeman/report/templates/warning_overview.html.erb +17 -0
- data/lib/brakeman/rescanner.rb +483 -0
- data/lib/brakeman/scanner.rb +317 -0
- data/lib/brakeman/tracker.rb +347 -0
- data/lib/brakeman/tracker/collection.rb +93 -0
- data/lib/brakeman/tracker/config.rb +101 -0
- data/lib/brakeman/tracker/constants.rb +101 -0
- data/lib/brakeman/tracker/controller.rb +161 -0
- data/lib/brakeman/tracker/library.rb +17 -0
- data/lib/brakeman/tracker/model.rb +90 -0
- data/lib/brakeman/tracker/template.rb +33 -0
- data/lib/brakeman/util.rb +481 -0
- data/lib/brakeman/version.rb +3 -0
- data/lib/brakeman/warning.rb +255 -0
- data/lib/brakeman/warning_codes.rb +111 -0
- data/lib/ruby_parser/bm_sexp.rb +610 -0
- data/lib/ruby_parser/bm_sexp_processor.rb +116 -0
- metadata +362 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
require 'brakeman/processors/lib/basic_processor'
|
|
2
|
+
|
|
3
|
+
#Finds method calls matching the given target(s).
|
|
4
|
+
# #-- This should be deprecated --#
|
|
5
|
+
# #-- Do not use for new code --#
|
|
6
|
+
#
|
|
7
|
+
#Targets/methods can be:
|
|
8
|
+
#
|
|
9
|
+
# - nil: matches anything, including nothing
|
|
10
|
+
# - Empty array: matches nothing
|
|
11
|
+
# - Symbol: matches single target/method exactly
|
|
12
|
+
# - Array of symbols: matches against any of the symbols
|
|
13
|
+
# - Regular expression: matches the expression
|
|
14
|
+
# - Array of regular expressions: matches any of the expressions
|
|
15
|
+
#
|
|
16
|
+
#If a target is also the name of a class, methods called on instances
|
|
17
|
+
#of that class will also be matched, in a very limited way.
|
|
18
|
+
#(Any methods called on Klass.new, basically. More useful when used
|
|
19
|
+
#in conjunction with AliasProcessor.)
|
|
20
|
+
#
|
|
21
|
+
#Examples:
|
|
22
|
+
#
|
|
23
|
+
# #To find any uses of this class:
|
|
24
|
+
# FindCall.new :FindCall, nil
|
|
25
|
+
#
|
|
26
|
+
# #Find system calls without a target
|
|
27
|
+
# FindCall.new [], [:system, :exec, :syscall]
|
|
28
|
+
#
|
|
29
|
+
# #Find all calls to length(), no matter the target
|
|
30
|
+
# FindCall.new nil, :length
|
|
31
|
+
#
|
|
32
|
+
# #Find all calls to sub, sub!, gsub, or gsub!
|
|
33
|
+
# FindCall.new nil, /^g?sub!?$/
|
|
34
|
+
class Brakeman::FindCall < Brakeman::BasicProcessor
|
|
35
|
+
|
|
36
|
+
def initialize targets, methods, tracker, in_depth = false
|
|
37
|
+
super tracker
|
|
38
|
+
@calls = []
|
|
39
|
+
@find_targets = targets
|
|
40
|
+
@find_methods = methods
|
|
41
|
+
@current_class = nil
|
|
42
|
+
@current_method = nil
|
|
43
|
+
@in_depth = in_depth
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
#Returns a list of results.
|
|
47
|
+
#
|
|
48
|
+
#A result looks like:
|
|
49
|
+
#
|
|
50
|
+
# s(:result, :ClassName, :method_name, s(:call, ...))
|
|
51
|
+
#
|
|
52
|
+
#or
|
|
53
|
+
#
|
|
54
|
+
# s(:result, :template_name, s(:call, ...))
|
|
55
|
+
def matches
|
|
56
|
+
@calls
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
#Process the given source. Provide either class and method being searched
|
|
60
|
+
#or the template. These names are used when reporting results.
|
|
61
|
+
#
|
|
62
|
+
#Use FindCall#matches to retrieve results.
|
|
63
|
+
def process_source exp, klass = nil, method = nil, template = nil
|
|
64
|
+
@current_class = klass
|
|
65
|
+
@current_method = method
|
|
66
|
+
@current_template = template
|
|
67
|
+
process exp
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
#Process body of method
|
|
71
|
+
def process_defn exp
|
|
72
|
+
process_all exp.body
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
alias :process_defs :process_defn
|
|
76
|
+
|
|
77
|
+
#Process body of block
|
|
78
|
+
def process_rlist exp
|
|
79
|
+
process_all exp
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
#Look for matching calls and add them to results
|
|
83
|
+
def process_call exp
|
|
84
|
+
target = get_target exp.target
|
|
85
|
+
method = exp.method
|
|
86
|
+
|
|
87
|
+
process_call_args exp
|
|
88
|
+
|
|
89
|
+
if match(@find_targets, target) and match(@find_methods, method)
|
|
90
|
+
|
|
91
|
+
if @current_template
|
|
92
|
+
@calls << Sexp.new(:result, @current_template, exp).line(exp.line)
|
|
93
|
+
else
|
|
94
|
+
@calls << Sexp.new(:result, @current_module, @current_class, @current_method, exp).line(exp.line)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
#Normally FindCall won't match a method invocation that is the target of
|
|
100
|
+
#another call, such as:
|
|
101
|
+
#
|
|
102
|
+
# User.find(:first, :conditions => "user = '#{params['user']}').name
|
|
103
|
+
#
|
|
104
|
+
#A search for User.find will not match this unless @in_depth is true.
|
|
105
|
+
if @in_depth and call? exp.target
|
|
106
|
+
process exp.target
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
exp
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
#Process an assignment like a call
|
|
113
|
+
def process_attrasgn exp
|
|
114
|
+
process_call exp
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
private
|
|
118
|
+
|
|
119
|
+
#Gets the target of a call as a Symbol
|
|
120
|
+
#if possible
|
|
121
|
+
def get_target exp
|
|
122
|
+
if sexp? exp
|
|
123
|
+
case exp.node_type
|
|
124
|
+
when :ivar, :lvar, :const, :lit
|
|
125
|
+
exp.value
|
|
126
|
+
when :true, :false
|
|
127
|
+
exp.node_type
|
|
128
|
+
when :colon2
|
|
129
|
+
class_name exp
|
|
130
|
+
else
|
|
131
|
+
exp
|
|
132
|
+
end
|
|
133
|
+
else
|
|
134
|
+
exp
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
#Checks if the search terms match the given item
|
|
139
|
+
def match search_terms, item
|
|
140
|
+
case search_terms
|
|
141
|
+
when Symbol
|
|
142
|
+
if search_terms == item
|
|
143
|
+
true
|
|
144
|
+
elsif sexp? item
|
|
145
|
+
is_instance_of? item, search_terms
|
|
146
|
+
else
|
|
147
|
+
false
|
|
148
|
+
end
|
|
149
|
+
when Sexp
|
|
150
|
+
search_terms == item
|
|
151
|
+
when Enumerable
|
|
152
|
+
if search_terms.empty?
|
|
153
|
+
item == nil
|
|
154
|
+
else
|
|
155
|
+
search_terms.each do|term|
|
|
156
|
+
if match(term, item)
|
|
157
|
+
return true
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
false
|
|
161
|
+
end
|
|
162
|
+
when Regexp
|
|
163
|
+
search_terms.match item.to_s
|
|
164
|
+
when nil
|
|
165
|
+
true
|
|
166
|
+
else
|
|
167
|
+
raise "Cannot match #{search_terms} and #{item}"
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
#Checks if +item+ is an instance of +klass+ by looking for Klass.new
|
|
172
|
+
def is_instance_of? item, klass
|
|
173
|
+
if call? item
|
|
174
|
+
if sexp? item.target
|
|
175
|
+
item.method == :new and item.target.node_type == :const and item.target.value == klass
|
|
176
|
+
else
|
|
177
|
+
item.method == :new and item.target == klass
|
|
178
|
+
end
|
|
179
|
+
else
|
|
180
|
+
false
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
require 'brakeman/processors/alias_processor'
|
|
2
|
+
|
|
3
|
+
#Attempts to determine the return value of a method.
|
|
4
|
+
#
|
|
5
|
+
#Preferred usage:
|
|
6
|
+
#
|
|
7
|
+
# Brakeman::FindReturnValue.return_value exp
|
|
8
|
+
class Brakeman::FindReturnValue
|
|
9
|
+
include Brakeman::Util
|
|
10
|
+
|
|
11
|
+
#Returns a guess at the return value of a given method or other block of code.
|
|
12
|
+
#
|
|
13
|
+
#If multiple return values are possible, returns all values in an :or Sexp.
|
|
14
|
+
def self.return_value exp, env = nil
|
|
15
|
+
self.new.get_return_value exp, env
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def initialize
|
|
19
|
+
@uses_ivars = false
|
|
20
|
+
@return_values = []
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def uses_ivars?
|
|
24
|
+
@uses_ivars
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
#Find return value of Sexp. Takes an optional starting environment.
|
|
28
|
+
def get_return_value exp, env = nil
|
|
29
|
+
process_method exp, env
|
|
30
|
+
value = make_return_value
|
|
31
|
+
value.original_line = exp.line
|
|
32
|
+
value
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
#Process method (or, actually, any Sexp) for return value.
|
|
36
|
+
def process_method exp, env = nil
|
|
37
|
+
exp = Brakeman::AliasProcessor.new.process_safely exp, env
|
|
38
|
+
|
|
39
|
+
find_explicit_return_values exp
|
|
40
|
+
|
|
41
|
+
if node_type? exp, :defn, :defs
|
|
42
|
+
body = exp.body
|
|
43
|
+
|
|
44
|
+
unless body.empty?
|
|
45
|
+
@return_values << last_value(body)
|
|
46
|
+
else
|
|
47
|
+
Brakeman.debug "FindReturnValue: Empty method? #{exp.inspect}"
|
|
48
|
+
end
|
|
49
|
+
elsif exp
|
|
50
|
+
@return_values << last_value(exp)
|
|
51
|
+
else
|
|
52
|
+
Brakeman.debug "FindReturnValue: Given something strange? #{exp.inspect}"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
exp
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
#Searches expression for return statements.
|
|
59
|
+
def find_explicit_return_values exp
|
|
60
|
+
todo = [exp]
|
|
61
|
+
|
|
62
|
+
until todo.empty?
|
|
63
|
+
current = todo.shift
|
|
64
|
+
|
|
65
|
+
@uses_ivars = true if node_type? current, :ivar
|
|
66
|
+
|
|
67
|
+
if node_type? current, :return
|
|
68
|
+
@return_values << current.value unless current.value.nil?
|
|
69
|
+
elsif sexp? current
|
|
70
|
+
todo = current[1..-1].concat todo
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
#Determines the "last value" of an expression.
|
|
76
|
+
def last_value exp
|
|
77
|
+
case exp.node_type
|
|
78
|
+
when :rlist, :block, :scope, Sexp
|
|
79
|
+
last_value exp.last
|
|
80
|
+
when :if
|
|
81
|
+
then_clause = exp.then_clause
|
|
82
|
+
else_clause = exp.else_clause
|
|
83
|
+
|
|
84
|
+
if then_clause.nil?
|
|
85
|
+
last_value else_clause
|
|
86
|
+
elsif else_clause.nil?
|
|
87
|
+
last_value then_clause
|
|
88
|
+
else
|
|
89
|
+
true_branch = last_value then_clause
|
|
90
|
+
false_branch = last_value else_clause
|
|
91
|
+
|
|
92
|
+
if true_branch and false_branch
|
|
93
|
+
value = make_or(true_branch, false_branch)
|
|
94
|
+
value.original_line = value.rhs.line
|
|
95
|
+
value
|
|
96
|
+
else #Unlikely?
|
|
97
|
+
true_branch or false_branch
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
when :lasgn, :iasgn
|
|
101
|
+
exp.rhs
|
|
102
|
+
when :return
|
|
103
|
+
exp.value
|
|
104
|
+
else
|
|
105
|
+
exp.original_line = exp.line unless exp.original_line
|
|
106
|
+
exp
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def make_or lhs, rhs
|
|
111
|
+
#Better checks in future
|
|
112
|
+
if lhs == rhs
|
|
113
|
+
lhs
|
|
114
|
+
else
|
|
115
|
+
Sexp.new(:or, lhs, rhs)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
#Turns the array of return values into an :or Sexp
|
|
120
|
+
def make_return_value
|
|
121
|
+
@return_values.compact!
|
|
122
|
+
@return_values.uniq!
|
|
123
|
+
|
|
124
|
+
if @return_values.empty?
|
|
125
|
+
Sexp.new(:nil)
|
|
126
|
+
elsif @return_values.length == 1
|
|
127
|
+
@return_values.first
|
|
128
|
+
else
|
|
129
|
+
@return_values.reduce do |value, sexp|
|
|
130
|
+
make_or value, sexp
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#Contains a couple shared methods for Processors.
|
|
2
|
+
module Brakeman::ProcessorHelper
|
|
3
|
+
def process_all exp
|
|
4
|
+
exp.each_sexp do |e|
|
|
5
|
+
process e
|
|
6
|
+
end
|
|
7
|
+
exp
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def process_all! exp
|
|
11
|
+
exp.map! do |e|
|
|
12
|
+
if sexp? e
|
|
13
|
+
process e
|
|
14
|
+
else
|
|
15
|
+
e
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
exp
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
#Process the arguments of a method call. Does not store results.
|
|
23
|
+
#
|
|
24
|
+
#This method is used because Sexp#args and Sexp#arglist create new objects.
|
|
25
|
+
def process_call_args exp
|
|
26
|
+
exp.each_arg do |a|
|
|
27
|
+
process a if sexp? a
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
exp
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def process_class exp
|
|
34
|
+
current_class = @current_class
|
|
35
|
+
@current_class = class_name exp[1]
|
|
36
|
+
process_all exp.body
|
|
37
|
+
@current_class = current_class
|
|
38
|
+
exp
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
#Sets the current module.
|
|
42
|
+
def process_module exp
|
|
43
|
+
module_name = class_name(exp.class_name).to_s
|
|
44
|
+
prev_module = @current_module
|
|
45
|
+
|
|
46
|
+
if prev_module
|
|
47
|
+
@current_module = "#{prev_module}::#{module_name}"
|
|
48
|
+
else
|
|
49
|
+
@current_module = module_name
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
if block_given?
|
|
53
|
+
yield
|
|
54
|
+
else
|
|
55
|
+
process_all exp.body
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
@current_module = prev_module
|
|
59
|
+
|
|
60
|
+
exp
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# e.g. private defn
|
|
64
|
+
def process_call_defn? exp
|
|
65
|
+
if call? exp and exp.target.nil? and node_type? exp.first_arg, :defn, :defs and [:private, :public, :protected].include? exp.method
|
|
66
|
+
prev_visibility = @visibility
|
|
67
|
+
@visibility = exp.method
|
|
68
|
+
process exp.first_arg
|
|
69
|
+
@visibility = prev_visibility
|
|
70
|
+
exp
|
|
71
|
+
else
|
|
72
|
+
false
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
require 'brakeman/processors/lib/basic_processor'
|
|
2
|
+
|
|
3
|
+
#Processes configuration. Results are put in tracker.config.
|
|
4
|
+
#
|
|
5
|
+
#Configuration of Rails via Rails::Initializer are stored in tracker.config.rails.
|
|
6
|
+
#For example:
|
|
7
|
+
#
|
|
8
|
+
# Rails::Initializer.run |config|
|
|
9
|
+
# config.action_controller.session_store = :cookie_store
|
|
10
|
+
# end
|
|
11
|
+
#
|
|
12
|
+
#will be stored in
|
|
13
|
+
#
|
|
14
|
+
# tracker.config[:rails][:action_controller][:session_store]
|
|
15
|
+
#
|
|
16
|
+
#Values for tracker.config.rails will still be Sexps.
|
|
17
|
+
class Brakeman::Rails2ConfigProcessor < Brakeman::BasicProcessor
|
|
18
|
+
#Replace block variable in
|
|
19
|
+
#
|
|
20
|
+
# Rails::Initializer.run |config|
|
|
21
|
+
#
|
|
22
|
+
#with this value so we can keep track of it.
|
|
23
|
+
RAILS_CONFIG = Sexp.new(:const, :"!BRAKEMAN_RAILS_CONFIG")
|
|
24
|
+
|
|
25
|
+
def initialize *args
|
|
26
|
+
super
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#Use this method to process configuration file
|
|
30
|
+
def process_config src, file_name
|
|
31
|
+
@file_name = file_name
|
|
32
|
+
res = Brakeman::ConfigAliasProcessor.new.process_safely(src, nil, file_name)
|
|
33
|
+
process res
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
#Check if config is set to use Erubis
|
|
37
|
+
def process_call exp
|
|
38
|
+
target = exp.target
|
|
39
|
+
target = process target if sexp? target
|
|
40
|
+
|
|
41
|
+
if exp.method == :gem and exp.first_arg.value == "erubis"
|
|
42
|
+
Brakeman.notify "[Notice] Using Erubis for ERB templates"
|
|
43
|
+
@tracker.config.erubis = true
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
exp
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
#Look for configuration settings
|
|
50
|
+
def process_attrasgn exp
|
|
51
|
+
if exp.target == RAILS_CONFIG
|
|
52
|
+
#Get rid of '=' at end
|
|
53
|
+
attribute = exp.method.to_s[0..-2].to_sym
|
|
54
|
+
if exp.args.length > 1
|
|
55
|
+
#Multiple arguments?...not sure if this will ever happen
|
|
56
|
+
@tracker.config.rails[attribute] = exp.args
|
|
57
|
+
else
|
|
58
|
+
@tracker.config.rails[attribute] = exp.first_arg
|
|
59
|
+
end
|
|
60
|
+
elsif include_rails_config? exp
|
|
61
|
+
options = get_rails_config exp
|
|
62
|
+
level = @tracker.config.rails
|
|
63
|
+
options[0..-2].each do |o|
|
|
64
|
+
level[o] ||= {}
|
|
65
|
+
level = level[o]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
level[options.last] = exp.first_arg
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
exp
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
#Check for Rails version
|
|
75
|
+
def process_cdecl exp
|
|
76
|
+
#Set Rails version required
|
|
77
|
+
if exp.lhs == :RAILS_GEM_VERSION
|
|
78
|
+
@tracker.config.rails_version = exp.rhs.value
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
exp
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
#Check if an expression includes a call to set Rails config
|
|
85
|
+
def include_rails_config? exp
|
|
86
|
+
target = exp.target
|
|
87
|
+
if call? target
|
|
88
|
+
if target.target == RAILS_CONFIG
|
|
89
|
+
true
|
|
90
|
+
else
|
|
91
|
+
include_rails_config? target
|
|
92
|
+
end
|
|
93
|
+
elsif target == RAILS_CONFIG
|
|
94
|
+
true
|
|
95
|
+
else
|
|
96
|
+
false
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
#Returns an array of symbols for each 'level' in the config
|
|
101
|
+
#
|
|
102
|
+
# config.action_controller.session_store = :cookie
|
|
103
|
+
#
|
|
104
|
+
#becomes
|
|
105
|
+
#
|
|
106
|
+
# [:action_controller, :session_store]
|
|
107
|
+
def get_rails_config exp
|
|
108
|
+
if node_type? exp, :attrasgn
|
|
109
|
+
attribute = exp.method.to_s[0..-2].to_sym
|
|
110
|
+
get_rails_config(exp.target) << attribute
|
|
111
|
+
elsif call? exp
|
|
112
|
+
if exp.target == RAILS_CONFIG
|
|
113
|
+
[exp.method]
|
|
114
|
+
else
|
|
115
|
+
get_rails_config(exp.target) << exp.method
|
|
116
|
+
end
|
|
117
|
+
else
|
|
118
|
+
raise "WHAT"
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
#This is necessary to replace block variable so we can track config settings
|
|
124
|
+
class Brakeman::ConfigAliasProcessor < Brakeman::AliasProcessor
|
|
125
|
+
|
|
126
|
+
RAILS_INIT = Sexp.new(:colon2, Sexp.new(:const, :Rails), :Initializer)
|
|
127
|
+
|
|
128
|
+
#Look for a call to
|
|
129
|
+
#
|
|
130
|
+
# Rails::Initializer.run do |config|
|
|
131
|
+
# ...
|
|
132
|
+
# end
|
|
133
|
+
#
|
|
134
|
+
#and replace config with RAILS_CONFIG
|
|
135
|
+
def process_iter exp
|
|
136
|
+
target = exp.block_call.target
|
|
137
|
+
method = exp.block_call.method
|
|
138
|
+
|
|
139
|
+
if sexp? target and target == RAILS_INIT and method == :run
|
|
140
|
+
env[Sexp.new(:lvar, exp.block_args.value)] = Brakeman::Rails2ConfigProcessor::RAILS_CONFIG
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
process_default exp
|
|
144
|
+
end
|
|
145
|
+
end
|