brakeman-lib 4.3.1 → 4.4.0
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 +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 +13 -10
@@ -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
|