brakeman-min 4.3.1 → 4.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +24 -1
- data/README.md +35 -6
- data/bin/brakeman +2 -0
- data/lib/brakeman.rb +5 -3
- data/lib/brakeman/app_tree.rb +15 -1
- data/lib/brakeman/call_index.rb +7 -4
- data/lib/brakeman/checks.rb +16 -8
- data/lib/brakeman/checks/base_check.rb +2 -19
- data/lib/brakeman/checks/check_basic_auth_timing_attack.rb +1 -1
- data/lib/brakeman/checks/check_content_tag.rb +4 -4
- data/lib/brakeman/checks/check_create_with.rb +1 -1
- data/lib/brakeman/checks/check_cross_site_scripting.rb +3 -3
- data/lib/brakeman/checks/check_default_routes.rb +3 -3
- data/lib/brakeman/checks/check_deserialize.rb +1 -1
- data/lib/brakeman/checks/check_detailed_exceptions.rb +1 -1
- data/lib/brakeman/checks/check_digest_dos.rb +4 -4
- data/lib/brakeman/checks/check_escape_function.rb +1 -1
- data/lib/brakeman/checks/check_execute.rb +5 -4
- data/lib/brakeman/checks/check_file_access.rb +13 -3
- data/lib/brakeman/checks/check_file_disclosure.rb +1 -1
- data/lib/brakeman/checks/check_filter_skipping.rb +1 -1
- data/lib/brakeman/checks/check_forgery_setting.rb +3 -3
- data/lib/brakeman/checks/check_header_dos.rb +3 -3
- data/lib/brakeman/checks/check_i18n_xss.rb +3 -3
- data/lib/brakeman/checks/check_jruby_xml.rb +1 -1
- data/lib/brakeman/checks/check_json_encoding.rb +3 -3
- data/lib/brakeman/checks/check_json_parsing.rb +8 -11
- data/lib/brakeman/checks/check_link_to.rb +3 -3
- data/lib/brakeman/checks/check_link_to_href.rb +2 -2
- data/lib/brakeman/checks/check_mail_to.rb +3 -3
- data/lib/brakeman/checks/check_mime_type_dos.rb +1 -1
- data/lib/brakeman/checks/check_model_attributes.rb +4 -4
- data/lib/brakeman/checks/check_model_serialize.rb +1 -1
- data/lib/brakeman/checks/check_nested_attributes.rb +3 -3
- data/lib/brakeman/checks/check_nested_attributes_bypass.rb +1 -1
- data/lib/brakeman/checks/check_number_to_currency.rb +4 -4
- data/lib/brakeman/checks/check_quote_table_name.rb +2 -2
- data/lib/brakeman/checks/check_regex_dos.rb +1 -1
- data/lib/brakeman/checks/check_render.rb +2 -2
- data/lib/brakeman/checks/check_render_dos.rb +1 -1
- data/lib/brakeman/checks/check_render_inline.rb +1 -1
- data/lib/brakeman/checks/check_response_splitting.rb +1 -1
- data/lib/brakeman/checks/check_route_dos.rb +1 -1
- data/lib/brakeman/checks/check_safe_buffer_manipulation.rb +1 -1
- data/lib/brakeman/checks/check_sanitize_methods.rb +3 -3
- data/lib/brakeman/checks/check_secrets.rb +1 -1
- data/lib/brakeman/checks/check_select_tag.rb +1 -1
- data/lib/brakeman/checks/check_select_vulnerability.rb +1 -1
- data/lib/brakeman/checks/check_session_manipulation.rb +1 -1
- data/lib/brakeman/checks/check_session_settings.rb +1 -1
- data/lib/brakeman/checks/check_simple_format.rb +2 -2
- data/lib/brakeman/checks/check_single_quotes.rb +14 -10
- data/lib/brakeman/checks/check_skip_before_filter.rb +2 -2
- data/lib/brakeman/checks/check_sprockets_path_traversal.rb +39 -0
- data/lib/brakeman/checks/check_sql.rb +1 -1
- data/lib/brakeman/checks/check_sql_cves.rb +2 -2
- data/lib/brakeman/checks/check_strip_tags.rb +10 -8
- data/lib/brakeman/checks/check_symbol_dos.rb +1 -1
- data/lib/brakeman/checks/check_symbol_dos_cve.rb +1 -1
- data/lib/brakeman/checks/check_translate_bug.rb +7 -7
- data/lib/brakeman/checks/check_unsafe_reflection.rb +1 -1
- data/lib/brakeman/checks/check_unscoped_find.rb +1 -1
- data/lib/brakeman/checks/check_validation_regex.rb +1 -1
- data/lib/brakeman/checks/check_weak_hash.rb +18 -19
- data/lib/brakeman/checks/check_xml_dos.rb +1 -1
- data/lib/brakeman/checks/check_yaml_parsing.rb +1 -1
- data/lib/brakeman/format/style.css +8 -0
- data/lib/brakeman/messages.rb +220 -0
- data/lib/brakeman/options.rb +13 -0
- data/lib/brakeman/parsers/template_parser.rb +2 -2
- data/lib/brakeman/processors/alias_processor.rb +7 -0
- data/lib/brakeman/processors/config_processor.rb +4 -1
- data/lib/brakeman/processors/gem_processor.rb +30 -2
- data/lib/brakeman/processors/lib/call_conversion_helper.rb +2 -1
- data/lib/brakeman/processors/lib/rails3_route_processor.rb +0 -2
- data/lib/brakeman/processors/lib/rails4_config_processor.rb +18 -0
- data/lib/brakeman/processors/lib/render_helper.rb +5 -0
- data/lib/brakeman/processors/lib/render_path.rb +15 -0
- data/lib/brakeman/processors/library_processor.rb +1 -1
- data/lib/brakeman/report/report_base.rb +17 -161
- data/lib/brakeman/report/report_csv.rb +17 -0
- data/lib/brakeman/report/report_html.rb +34 -31
- data/lib/brakeman/report/report_json.rb +21 -0
- data/lib/brakeman/report/report_markdown.rb +13 -6
- data/lib/brakeman/report/report_table.rb +157 -0
- data/lib/brakeman/report/report_tabs.rb +3 -1
- data/lib/brakeman/report/report_text.rb +16 -0
- data/lib/brakeman/scanner.rb +5 -1
- data/lib/brakeman/tracker/config.rb +1 -1
- data/lib/brakeman/util.rb +0 -17
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman/warning.rb +9 -4
- data/lib/brakeman/warning_codes.rb +1 -0
- metadata +9 -6
@@ -13,7 +13,7 @@ class Brakeman::LibraryProcessor < Brakeman::BaseProcessor
|
|
13
13
|
@alias_processor = Brakeman::AliasProcessor.new tracker
|
14
14
|
@current_module = nil
|
15
15
|
@current_class = nil
|
16
|
-
@
|
16
|
+
@initializer_env = nil
|
17
17
|
end
|
18
18
|
|
19
19
|
def process_library src, file_name = nil
|
@@ -22,18 +22,25 @@ class Brakeman::Report::Base
|
|
22
22
|
@warnings_summary = nil
|
23
23
|
end
|
24
24
|
|
25
|
-
#
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
#Return summary of warnings in hash and store in @warnings_summary
|
26
|
+
def warnings_summary
|
27
|
+
return @warnings_summary if @warnings_summary
|
28
|
+
|
29
|
+
summary = Hash.new(0)
|
30
|
+
high_confidence_warnings = 0
|
31
|
+
|
32
|
+
[all_warnings].each do |warnings|
|
33
|
+
warnings.each do |warning|
|
34
|
+
summary[warning.warning_type.to_s] += 1
|
35
|
+
high_confidence_warnings += 1 if warning.confidence == 0
|
36
|
+
end
|
37
|
+
end
|
31
38
|
|
32
|
-
|
39
|
+
summary[:high_confidence] = high_confidence_warnings
|
40
|
+
@warnings_summary = summary
|
33
41
|
end
|
34
42
|
|
35
|
-
|
36
|
-
def generate_controllers
|
43
|
+
def controller_information
|
37
44
|
controller_rows = []
|
38
45
|
|
39
46
|
tracker.controllers.keys.map{|k| k.to_s}.sort.each do |name|
|
@@ -67,148 +74,7 @@ class Brakeman::Report::Base
|
|
67
74
|
}
|
68
75
|
end
|
69
76
|
|
70
|
-
|
71
|
-
|
72
|
-
locals = {:controller_rows => controller_rows}
|
73
|
-
values = controller_rows.collect{|row| row.values_at(*cols) }
|
74
|
-
render_array('controller_overview', cols, values, locals)
|
75
|
-
end
|
76
|
-
|
77
|
-
#Generate table of errors or return nil if no errors
|
78
|
-
def generate_errors
|
79
|
-
values = tracker.errors.collect{|error| [error[:error], error[:backtrace][0]]}
|
80
|
-
render_array('error_overview', ['Error', 'Location'], values, {:tracker => tracker})
|
81
|
-
end
|
82
|
-
|
83
|
-
def generate_obsolete
|
84
|
-
values = tracker.unused_fingerprints.collect{|fingerprint| [fingerprint] }
|
85
|
-
render_array('obsolete_ignore_entries', ['fingerprint'], values, {:tracker => tracker})
|
86
|
-
end
|
87
|
-
|
88
|
-
def generate_warnings
|
89
|
-
render_warnings generic_warnings,
|
90
|
-
:warning,
|
91
|
-
'security_warnings',
|
92
|
-
["Confidence", "Class", "Method", "Warning Type", "Message"],
|
93
|
-
'Class'
|
94
|
-
end
|
95
|
-
|
96
|
-
#Generate table of template warnings or return nil if no warnings
|
97
|
-
def generate_template_warnings
|
98
|
-
render_warnings template_warnings,
|
99
|
-
:template,
|
100
|
-
'view_warnings',
|
101
|
-
['Confidence', 'Template', 'Warning Type', 'Message'],
|
102
|
-
'Template'
|
103
|
-
|
104
|
-
end
|
105
|
-
|
106
|
-
#Generate table of model warnings or return nil if no warnings
|
107
|
-
def generate_model_warnings
|
108
|
-
render_warnings model_warnings,
|
109
|
-
:model,
|
110
|
-
'model_warnings',
|
111
|
-
['Confidence', 'Model', 'Warning Type', 'Message'],
|
112
|
-
'Model'
|
113
|
-
end
|
114
|
-
|
115
|
-
#Generate table of controller warnings or nil if no warnings
|
116
|
-
def generate_controller_warnings
|
117
|
-
render_warnings controller_warnings,
|
118
|
-
:controller,
|
119
|
-
'controller_warnings',
|
120
|
-
['Confidence', 'Controller', 'Warning Type', 'Message'],
|
121
|
-
'Controller'
|
122
|
-
end
|
123
|
-
|
124
|
-
def generate_ignored_warnings
|
125
|
-
render_warnings ignored_warnings,
|
126
|
-
:ignored,
|
127
|
-
'ignored_warnings',
|
128
|
-
['Confidence', 'Warning Type', 'File', 'Message'],
|
129
|
-
'Warning Type'
|
130
|
-
end
|
131
|
-
|
132
|
-
def render_warnings warnings, type, template, cols, sort_col
|
133
|
-
unless warnings.empty?
|
134
|
-
rows = sort(convert_to_rows(warnings, type), sort_col)
|
135
|
-
|
136
|
-
values = rows.collect { |row| row.values_at(*cols) }
|
137
|
-
|
138
|
-
locals = { :warnings => rows }
|
139
|
-
|
140
|
-
render_array(template, cols, values, locals)
|
141
|
-
else
|
142
|
-
nil
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
def convert_to_rows warnings, type = :warning
|
147
|
-
warnings.map do |warning|
|
148
|
-
w = warning.to_row type
|
149
|
-
|
150
|
-
case type
|
151
|
-
when :warning
|
152
|
-
convert_warning w, warning
|
153
|
-
when :template
|
154
|
-
convert_template_warning w, warning
|
155
|
-
when :model
|
156
|
-
convert_model_warning w, warning
|
157
|
-
when :controller
|
158
|
-
convert_controller_warning w, warning
|
159
|
-
when :ignored
|
160
|
-
convert_ignored_warning w, warning
|
161
|
-
end
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
def convert_warning warning, original
|
166
|
-
warning["Confidence"] = TEXT_CONFIDENCE[warning["Confidence"]]
|
167
|
-
warning["Message"] = text_message original, warning["Message"]
|
168
|
-
warning
|
169
|
-
end
|
170
|
-
|
171
|
-
def convert_template_warning warning, original
|
172
|
-
convert_warning warning, original
|
173
|
-
end
|
174
|
-
|
175
|
-
def convert_model_warning warning, original
|
176
|
-
convert_warning warning, original
|
177
|
-
end
|
178
|
-
|
179
|
-
def convert_controller_warning warning, original
|
180
|
-
convert_warning warning, original
|
181
|
-
end
|
182
|
-
|
183
|
-
def convert_ignored_warning warning, original
|
184
|
-
convert_warning warning, original
|
185
|
-
end
|
186
|
-
|
187
|
-
def sort rows, sort_col
|
188
|
-
stabilizer = 0
|
189
|
-
rows.sort_by do |row|
|
190
|
-
stabilizer += 1
|
191
|
-
|
192
|
-
row.values_at("Confidence", "Warning Type", sort_col) << stabilizer
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
#Return summary of warnings in hash and store in @warnings_summary
|
197
|
-
def warnings_summary
|
198
|
-
return @warnings_summary if @warnings_summary
|
199
|
-
|
200
|
-
summary = Hash.new(0)
|
201
|
-
high_confidence_warnings = 0
|
202
|
-
|
203
|
-
[all_warnings].each do |warnings|
|
204
|
-
warnings.each do |warning|
|
205
|
-
summary[warning.warning_type.to_s] += 1
|
206
|
-
high_confidence_warnings += 1 if warning.confidence == 0
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
summary[:high_confidence] = high_confidence_warnings
|
211
|
-
@warnings_summary = summary
|
77
|
+
controller_rows
|
212
78
|
end
|
213
79
|
|
214
80
|
def all_warnings
|
@@ -279,14 +145,4 @@ class Brakeman::Report::Base
|
|
279
145
|
"Unknown"
|
280
146
|
end
|
281
147
|
end
|
282
|
-
|
283
|
-
#Escape warning message and highlight user input in text output
|
284
|
-
def text_message warning, message
|
285
|
-
if @highlight_user_input and warning.user_input
|
286
|
-
user_input = warning.format_user_input
|
287
|
-
message.gsub(user_input, "+#{user_input}+")
|
288
|
-
else
|
289
|
-
message
|
290
|
-
end
|
291
|
-
end
|
292
148
|
end
|
@@ -52,4 +52,21 @@ class Brakeman::Report::CSV < Brakeman::Report::Table
|
|
52
52
|
header << CSV.generate_line([File.expand_path(tracker.app_path), Time.now.to_s, checks.checks_run.sort.join(", "), rails_version])
|
53
53
|
"BRAKEMAN REPORT\n\n" + header
|
54
54
|
end
|
55
|
+
|
56
|
+
# rely on Terminal::Table to build the structure, extract the data out in CSV format
|
57
|
+
def table_to_csv table
|
58
|
+
return "" unless table
|
59
|
+
|
60
|
+
Brakeman.load_brakeman_dependency 'terminal-table'
|
61
|
+
headings = table.headings
|
62
|
+
if headings.is_a? Array
|
63
|
+
headings = headings.first
|
64
|
+
end
|
65
|
+
|
66
|
+
output = CSV.generate_line(headings.cells.map{|cell| cell.to_s.strip})
|
67
|
+
table.rows.each do |row|
|
68
|
+
output << CSV.generate_line(row.cells.map{|cell| cell.to_s.strip})
|
69
|
+
end
|
70
|
+
output
|
71
|
+
end
|
55
72
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'cgi'
|
2
|
+
require 'brakeman/report/report_table.rb'
|
2
3
|
|
3
|
-
class Brakeman::Report::HTML < Brakeman::Report::
|
4
|
+
class Brakeman::Report::HTML < Brakeman::Report::Table
|
4
5
|
HTML_CONFIDENCE = [ "<span class='high-confidence'>High</span>",
|
5
|
-
|
6
|
-
|
6
|
+
"<span class='med-confidence'>Medium</span>",
|
7
|
+
"<span class='weak-confidence'>Weak</span>" ]
|
7
8
|
|
8
9
|
def initialize *args
|
9
10
|
super
|
@@ -66,20 +67,18 @@ class Brakeman::Report::HTML < Brakeman::Report::Base
|
|
66
67
|
end
|
67
68
|
|
68
69
|
def convert_warning warning, original
|
69
|
-
warning["Confidence"] = HTML_CONFIDENCE[
|
70
|
+
warning["Confidence"] = HTML_CONFIDENCE[original.confidence]
|
70
71
|
warning["Message"] = with_context original, warning["Message"]
|
71
72
|
warning["Warning Type"] = with_link original, warning["Warning Type"]
|
72
73
|
warning
|
73
74
|
end
|
74
75
|
|
75
76
|
def with_link warning, message
|
76
|
-
"<a rel=\"
|
77
|
+
"<a rel=\"noreferrer\" href=\"#{warning.link}\">#{message}</a>"
|
77
78
|
end
|
78
79
|
|
79
80
|
def convert_template_warning warning, original
|
80
|
-
warning
|
81
|
-
warning["Message"] = with_context original, warning["Message"]
|
82
|
-
warning["Warning Type"] = with_link original, warning["Warning Type"]
|
81
|
+
warning = convert_warning warning, original
|
83
82
|
warning["Called From"] = original.called_from
|
84
83
|
warning["Template Name"] = original.template.name
|
85
84
|
warning
|
@@ -113,29 +112,16 @@ class Brakeman::Report::HTML < Brakeman::Report::Base
|
|
113
112
|
|
114
113
|
#Generate HTML for warnings, including context show/hidden via Javascript
|
115
114
|
def with_context warning, message
|
115
|
+
@element_id += 1
|
116
116
|
context = context_for(@app_tree, warning)
|
117
|
-
full_message = nil
|
118
|
-
|
119
|
-
if tracker.options[:message_limit] and tracker.options[:message_limit] > 0 and message.length > tracker.options[:message_limit]
|
120
|
-
full_message = html_message(warning, message)
|
121
|
-
message = message[0..tracker.options[:message_limit]] << "..."
|
122
|
-
end
|
123
|
-
|
124
117
|
message = html_message(warning, message)
|
125
|
-
return message if context.empty? and not full_message
|
126
118
|
|
127
|
-
@element_id += 1
|
128
119
|
code_id = "context#@element_id"
|
129
120
|
message_id = "message#@element_id"
|
130
121
|
full_message_id = "full_message#@element_id"
|
131
122
|
alt = false
|
132
123
|
output = "<div class='warning_message' onClick=\"toggle('#{code_id}');toggle('#{message_id}');toggle('#{full_message_id}')\" >" <<
|
133
|
-
|
134
|
-
"<span id='#{message_id}' style='display:block' >#{message}</span>" <<
|
135
|
-
"<span id='#{full_message_id}' style='display:none'>#{full_message}</span>"
|
136
|
-
else
|
137
|
-
message
|
138
|
-
end <<
|
124
|
+
message <<
|
139
125
|
"<table id='#{code_id}' class='context' style='display:none'>" <<
|
140
126
|
"<caption>#{CGI.escapeHTML warning_file(warning) || ''}</caption>"
|
141
127
|
|
@@ -199,18 +185,35 @@ class Brakeman::Report::HTML < Brakeman::Report::Base
|
|
199
185
|
|
200
186
|
#Escape warning message and highlight user input in HTML output
|
201
187
|
def html_message warning, message
|
202
|
-
message =
|
188
|
+
message = message.to_html
|
203
189
|
|
204
190
|
if warning.file
|
205
|
-
github_url = github_url
|
206
|
-
|
191
|
+
if github_url = github_url(warning.file, warning.line)
|
192
|
+
message << " <a href=\"#{github_url}\" target='_blank'>near line #{warning.line}</a>"
|
193
|
+
elsif warning.line
|
194
|
+
message << " near line #{warning.line}"
|
195
|
+
end
|
207
196
|
end
|
208
197
|
|
209
|
-
if
|
210
|
-
|
211
|
-
|
212
|
-
|
198
|
+
if warning.code
|
199
|
+
code = warning.format_with_user_input do |_, user_input|
|
200
|
+
"[BMP_UI]#{user_input}[/BMP_UI]"
|
201
|
+
end
|
202
|
+
|
203
|
+
code = "<span class=\"code\">#{CGI.escapeHTML(code).gsub("[BMP_UI]", "<span class=\"user_input\">").gsub("[/BMP_UI]", "</span>")}</span>"
|
204
|
+
full_message = "#{message}: #{code}"
|
213
205
|
|
214
|
-
|
206
|
+
if warning.code.mass > 20
|
207
|
+
message_id = "message#@element_id"
|
208
|
+
full_message_id = "full_message#@element_id"
|
209
|
+
|
210
|
+
"<span id='#{message_id}' style='display:block'>#{message}: ...</span>" <<
|
211
|
+
"<span id='#{full_message_id}' style='display:none'>#{full_message}</span>"
|
212
|
+
else
|
213
|
+
full_message
|
214
|
+
end
|
215
|
+
else
|
216
|
+
message
|
217
|
+
end
|
215
218
|
end
|
216
219
|
end
|
@@ -38,8 +38,29 @@ class Brakeman::Report::JSON < Brakeman::Report::Base
|
|
38
38
|
def convert_to_hashes warnings
|
39
39
|
warnings.map do |w|
|
40
40
|
hash = w.to_hash
|
41
|
+
hash[:render_path] = convert_render_path hash[:render_path]
|
41
42
|
hash[:file] = warning_file w
|
43
|
+
|
42
44
|
hash
|
43
45
|
end.sort_by { |w| "#{w[:fingerprint]}#{w[:line]}" }
|
44
46
|
end
|
47
|
+
|
48
|
+
def convert_render_path render_path
|
49
|
+
return unless render_path and not @tracker.options[:absolute_paths]
|
50
|
+
|
51
|
+
render_path.map do |r|
|
52
|
+
r = r.dup
|
53
|
+
|
54
|
+
if r[:file]
|
55
|
+
r[:file] = relative_path(r[:file])
|
56
|
+
end
|
57
|
+
|
58
|
+
if r[:rendered] and r[:rendered][:file]
|
59
|
+
r[:rendered] = r[:rendered].dup
|
60
|
+
r[:rendered][:file] = relative_path(r[:rendered][:file])
|
61
|
+
end
|
62
|
+
|
63
|
+
r
|
64
|
+
end
|
65
|
+
end
|
45
66
|
end
|
@@ -92,16 +92,23 @@ class Brakeman::Report::Markdown < Brakeman::Report::Table
|
|
92
92
|
|
93
93
|
# Escape and code format warning message
|
94
94
|
def markdown_message warning, message
|
95
|
+
message = message.to_s
|
96
|
+
|
95
97
|
if warning.file
|
96
98
|
github_url = github_url warning.file, warning.line
|
97
|
-
|
99
|
+
|
100
|
+
if github_url
|
101
|
+
message << " near line [#{warning.line}](#{github_url})"
|
102
|
+
elsif warning.line
|
103
|
+
message << " near line #{warning.line}"
|
104
|
+
end
|
98
105
|
end
|
106
|
+
|
99
107
|
if warning.code
|
100
|
-
code = warning.format_code
|
101
|
-
message
|
102
|
-
else
|
103
|
-
message
|
108
|
+
code = warning.format_code.gsub('`','``').gsub(/\A``|``\z/, '` `')
|
109
|
+
message << ": `#{code}`"
|
104
110
|
end
|
105
|
-
end
|
106
111
|
|
112
|
+
message
|
113
|
+
end
|
107
114
|
end
|
@@ -62,6 +62,96 @@ class Brakeman::Report::Table < Brakeman::Report::Base
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
+
#Generate table of how many warnings of each warning type were reported
|
66
|
+
def generate_warning_overview
|
67
|
+
types = warnings_summary.keys
|
68
|
+
types.delete :high_confidence
|
69
|
+
values = types.sort.collect{|warning_type| [warning_type, warnings_summary[warning_type]] }
|
70
|
+
locals = {:types => types, :warnings_summary => warnings_summary}
|
71
|
+
|
72
|
+
render_array('warning_overview', ['Warning Type', 'Total'], values, locals)
|
73
|
+
end
|
74
|
+
|
75
|
+
#Generate table of controllers and routes found for those controllers
|
76
|
+
def generate_controllers
|
77
|
+
controller_rows = controller_information
|
78
|
+
|
79
|
+
cols = ['Name', 'Parent', 'Includes', 'Routes']
|
80
|
+
|
81
|
+
locals = {:controller_rows => controller_rows}
|
82
|
+
values = controller_rows.collect{|row| row.values_at(*cols) }
|
83
|
+
render_array('controller_overview', cols, values, locals)
|
84
|
+
end
|
85
|
+
|
86
|
+
#Generate table of errors or return nil if no errors
|
87
|
+
def generate_errors
|
88
|
+
values = tracker.errors.collect{|error| [error[:error], error[:backtrace][0]]}
|
89
|
+
render_array('error_overview', ['Error', 'Location'], values, {:tracker => tracker})
|
90
|
+
end
|
91
|
+
|
92
|
+
def generate_obsolete
|
93
|
+
values = tracker.unused_fingerprints.collect{|fingerprint| [fingerprint] }
|
94
|
+
render_array('obsolete_ignore_entries', ['fingerprint'], values, {:tracker => tracker})
|
95
|
+
end
|
96
|
+
|
97
|
+
def generate_warnings
|
98
|
+
render_warnings generic_warnings,
|
99
|
+
:warning,
|
100
|
+
'security_warnings',
|
101
|
+
["Confidence", "Class", "Method", "Warning Type", "Message"],
|
102
|
+
'Class'
|
103
|
+
end
|
104
|
+
|
105
|
+
#Generate table of template warnings or return nil if no warnings
|
106
|
+
def generate_template_warnings
|
107
|
+
render_warnings template_warnings,
|
108
|
+
:template,
|
109
|
+
'view_warnings',
|
110
|
+
['Confidence', 'Template', 'Warning Type', 'Message'],
|
111
|
+
'Template'
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
#Generate table of model warnings or return nil if no warnings
|
116
|
+
def generate_model_warnings
|
117
|
+
render_warnings model_warnings,
|
118
|
+
:model,
|
119
|
+
'model_warnings',
|
120
|
+
['Confidence', 'Model', 'Warning Type', 'Message'],
|
121
|
+
'Model'
|
122
|
+
end
|
123
|
+
|
124
|
+
#Generate table of controller warnings or nil if no warnings
|
125
|
+
def generate_controller_warnings
|
126
|
+
render_warnings controller_warnings,
|
127
|
+
:controller,
|
128
|
+
'controller_warnings',
|
129
|
+
['Confidence', 'Controller', 'Warning Type', 'Message'],
|
130
|
+
'Controller'
|
131
|
+
end
|
132
|
+
|
133
|
+
def generate_ignored_warnings
|
134
|
+
render_warnings ignored_warnings,
|
135
|
+
:ignored,
|
136
|
+
'ignored_warnings',
|
137
|
+
['Confidence', 'Warning Type', 'File', 'Message'],
|
138
|
+
'Warning Type'
|
139
|
+
end
|
140
|
+
|
141
|
+
def render_warnings warnings, type, template, cols, sort_col
|
142
|
+
unless warnings.empty?
|
143
|
+
rows = sort(convert_to_rows(warnings, type), sort_col)
|
144
|
+
|
145
|
+
values = rows.collect { |row| row.values_at(*cols) }
|
146
|
+
|
147
|
+
locals = { :warnings => rows }
|
148
|
+
|
149
|
+
render_array(template, cols, values, locals)
|
150
|
+
else
|
151
|
+
nil
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
65
155
|
#Generate listings of templates and their output
|
66
156
|
def generate_templates
|
67
157
|
out_processor = Brakeman::OutputProcessor.new
|
@@ -92,6 +182,44 @@ class Brakeman::Report::Table < Brakeman::Report::Base
|
|
92
182
|
output
|
93
183
|
end
|
94
184
|
|
185
|
+
def convert_to_rows warnings, type = :warning
|
186
|
+
warnings.map do |warning|
|
187
|
+
w = warning.to_row type
|
188
|
+
|
189
|
+
case type
|
190
|
+
when :warning
|
191
|
+
convert_warning w, warning
|
192
|
+
when :ignored
|
193
|
+
convert_ignored_warning w, warning
|
194
|
+
when :template
|
195
|
+
convert_template_warning w, warning
|
196
|
+
else
|
197
|
+
convert_warning w, warning
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def convert_warning warning, original
|
203
|
+
warning
|
204
|
+
end
|
205
|
+
|
206
|
+
def convert_ignored_warning warning, original
|
207
|
+
convert_warning warning, original
|
208
|
+
end
|
209
|
+
|
210
|
+
def convert_template_warning warning, original
|
211
|
+
convert_warning warning, original
|
212
|
+
end
|
213
|
+
|
214
|
+
def sort rows, sort_col
|
215
|
+
stabilizer = 0
|
216
|
+
rows.sort_by do |row|
|
217
|
+
stabilizer += 1
|
218
|
+
|
219
|
+
row.values_at("Confidence", "Warning Type", sort_col) << stabilizer
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
95
223
|
def render_array template, headings, value_array, locals
|
96
224
|
return if value_array.empty?
|
97
225
|
|
@@ -100,6 +228,35 @@ class Brakeman::Report::Table < Brakeman::Report::Base
|
|
100
228
|
end
|
101
229
|
end
|
102
230
|
|
231
|
+
def convert_warning warning, original
|
232
|
+
warning["Message"] = text_message original, warning["Message"]
|
233
|
+
|
234
|
+
warning
|
235
|
+
end
|
236
|
+
|
237
|
+
#Escape warning message and highlight user input in text output
|
238
|
+
def text_message warning, message
|
239
|
+
message = message.to_s
|
240
|
+
|
241
|
+
if warning.line
|
242
|
+
message << " near line #{warning.line}"
|
243
|
+
end
|
244
|
+
|
245
|
+
if warning.code
|
246
|
+
if @highlight_user_input and warning.user_input
|
247
|
+
code = warning.format_with_user_input do |user_input, user_input_string|
|
248
|
+
"+#{user_input_string}+"
|
249
|
+
end
|
250
|
+
else
|
251
|
+
code = warning.format_code
|
252
|
+
end
|
253
|
+
|
254
|
+
message << ": #{code}"
|
255
|
+
end
|
256
|
+
|
257
|
+
message
|
258
|
+
end
|
259
|
+
|
103
260
|
#Generate header for text output
|
104
261
|
def text_header
|
105
262
|
<<-HEADER
|