brakeman-min 3.3.5 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 58050375c093250d4ebd8b8244b919f5f6b8c7d9
4
- data.tar.gz: f928b15bb0a2629f39c6d95dfb21d3acba92946e
3
+ metadata.gz: 6979dd5270ff39f9f08c1391c27591e26c822a7d
4
+ data.tar.gz: a9a5f659a64c9fce7f5d6e8c820e220533d4ccb2
5
5
  SHA512:
6
- metadata.gz: 570a8fb1e6ff7631738c0a780e2293972379d2ba84f54d24449116198f75759ca47cac6b2aa03ff58b13259f105ed1b02a7c9b21a9937e3ede8f294964a1aee6
7
- data.tar.gz: aa1515a72f8a33d02d5e003e837a12e7dd796855f6843518dd7e105bc572304e0ab2fde053b61b7ebd8667ee67c3c9e8e3cc479966f6a3536062cc13f4dba3c1
6
+ metadata.gz: 09fae3a07ebe6eda7ef6403eddf52110d85e2a708d6ae167e3053ee8e678d34981bbde2eeba28a2dc0794b47813522c860a99f744197da24c0f1513061ec54d7
7
+ data.tar.gz: cc031803fe4afbb9c2572365415ab218e23344a0bfb0f759f2812ed63ab84503a06d354ac60b0a9d83492a1818c648d96c5ae013a48ea7bcec55980bc351cf90
data/CHANGES CHANGED
@@ -1,3 +1,12 @@
1
+ # 3.4.0
2
+
3
+ * Add new `plain` report format
4
+ * Add option to prune ignore file with `-I`
5
+ * Improved Slim template support
6
+ * Show obsolete ignore entries in reports (Jonathan Cheatham)
7
+ * Support creating reports in non-existent paths
8
+ * Add `--no-exit-warn`
9
+
1
10
  # 3.3.5
2
11
 
3
12
  * Fix bug in reports when using --debug option
@@ -145,7 +145,8 @@ module Brakeman
145
145
  :parallel_checks => true,
146
146
  :relative_path => false,
147
147
  :report_progress => true,
148
- :html_style => "#{File.expand_path(File.dirname(__FILE__))}/brakeman/format/style.css"
148
+ :html_style => "#{File.expand_path(File.dirname(__FILE__))}/brakeman/format/style.css",
149
+ :output_color => true
149
150
  }
150
151
  end
151
152
 
@@ -186,6 +187,8 @@ module Brakeman
186
187
  [:to_markdown]
187
188
  when :cc, :to_cc, :codeclimate, :to_codeclimate
188
189
  [:to_codeclimate]
190
+ when :plain ,:to_plain
191
+ [:to_plain]
189
192
  else
190
193
  [:to_s]
191
194
  end
@@ -209,6 +212,8 @@ module Brakeman
209
212
  :to_markdown
210
213
  when /(\.cc|\.codeclimate)$/i
211
214
  :to_codeclimate
215
+ when /\.plain$/i
216
+ :to_plain
212
217
  else
213
218
  :to_s
214
219
  end
@@ -362,7 +367,15 @@ module Brakeman
362
367
  end
363
368
 
364
369
  def self.write_report_to_files tracker, output_files
370
+ require 'fileutils'
371
+ tracker.options[:output_color] = false
372
+
365
373
  output_files.each_with_index do |output_file, idx|
374
+ dir = File.dirname(output_file)
375
+ unless Dir.exist? dir
376
+ FileUtils.mkdir_p(dir)
377
+ end
378
+
366
379
  File.open output_file, "w" do |f|
367
380
  f.write tracker.report.format(tracker.options[:output_formats][idx])
368
381
  end
@@ -372,6 +385,10 @@ module Brakeman
372
385
  private_class_method :write_report_to_files
373
386
 
374
387
  def self.write_report_to_formats tracker, output_formats
388
+ unless $stdout.tty?
389
+ tracker.options[:output_color] = false
390
+ end
391
+
375
392
  output_formats.each do |output_format|
376
393
  puts tracker.report.format(output_format)
377
394
  end
@@ -39,8 +39,8 @@ module Brakeman::Options
39
39
  options[:quiet] = quiet
40
40
  end
41
41
 
42
- opts.on( "-z", "--exit-on-warn", "Exit code is non-zero if warnings found") do
43
- options[:exit_on_warn] = true
42
+ opts.on( "-z", "--[no-]exit-on-warn", "Exit code is non-zero if warnings found") do |exit_on_warn|
43
+ options[:exit_on_warn] = exit_on_warn
44
44
  end
45
45
 
46
46
  opts.on "-3", "--rails3", "Force Rails 3 mode" do
@@ -172,12 +172,12 @@ module Brakeman::Options
172
172
 
173
173
  opts.on "-f",
174
174
  "--format TYPE",
175
- [:pdf, :text, :html, :csv, :tabs, :json, :markdown, :codeclimate, :cc],
175
+ [:pdf, :text, :html, :csv, :tabs, :json, :markdown, :codeclimate, :cc, :plain],
176
176
  "Specify output formats. Default is text" do |type|
177
177
 
178
178
  type = "s" if type == :text
179
179
  options[:output_format] = ("to_" << type.to_s).to_sym
180
- end
180
+ end
181
181
 
182
182
  opts.on "--css-file CSSFile", "Specify CSS to use for HTML output" do |file|
183
183
  options[:html_style] = File.expand_path file
@@ -199,6 +199,10 @@ module Brakeman::Options
199
199
  options[:highlight_user_input] = highlight
200
200
  end
201
201
 
202
+ opts.on "--[no-]color", "Use ANSI colors in report (Default)" do |color|
203
+ options[:output_color] = color
204
+ end
205
+
202
206
  opts.on "-m", "--routes", "Report controller information" do
203
207
  options[:report_routes] = true
204
208
  end
@@ -9,7 +9,9 @@ class Brakeman::OutputProcessor < Ruby2Ruby
9
9
  include Brakeman::Util
10
10
 
11
11
  #Copies +exp+ and then formats it.
12
- def format exp
12
+ def format exp, user_input = nil, &block
13
+ @user_input = user_input
14
+ @user_input_block = block
13
15
  process(exp.deep_clone) || "[Format Error]"
14
16
  end
15
17
 
@@ -17,7 +19,11 @@ class Brakeman::OutputProcessor < Ruby2Ruby
17
19
 
18
20
  def process exp
19
21
  begin
20
- super exp if sexp? exp and not exp.empty?
22
+ if @user_input and @user_input == exp
23
+ @user_input_block.call(exp, super(exp))
24
+ else
25
+ super exp if sexp? exp and not exp.empty?
26
+ end
21
27
  rescue => e
22
28
  Brakeman.debug "While formatting #{exp}: #{e}\n#{e.backtrace.join("\n")}"
23
29
  end
@@ -7,6 +7,7 @@ class Brakeman::SlimTemplateProcessor < Brakeman::TemplateProcessor
7
7
  SAFE_BUFFER = s(:call, s(:colon2, s(:const, :ActiveSupport), :SafeBuffer), :new)
8
8
  OUTPUT_BUFFER = s(:ivar, :@output_buffer)
9
9
  TEMPLE_UTILS = s(:colon2, s(:colon3, :Temple), :Utils)
10
+ ATTR_MERGE = s(:call, s(:call, s(:array), :reject, s(:block_pass, s(:lit, :empty?))), :join, s(:str, " "))
10
11
 
11
12
  def process_call exp
12
13
  target = exp.target
@@ -16,7 +17,7 @@ class Brakeman::SlimTemplateProcessor < Brakeman::TemplateProcessor
16
17
  arg = normalize_output(exp.first_arg)
17
18
 
18
19
  if is_escaped? arg
19
- add_escaped_output arg
20
+ add_escaped_output arg.first_arg
20
21
  elsif string? arg
21
22
  ignore
22
23
  elsif render? arg
@@ -25,11 +26,15 @@ class Brakeman::SlimTemplateProcessor < Brakeman::TemplateProcessor
25
26
  process_inside_interp arg
26
27
  elsif node_type? arg, :ignore
27
28
  ignore
29
+ elsif internal_variable? arg
30
+ ignore
31
+ elsif arg == ATTR_MERGE
32
+ ignore
28
33
  else
29
34
  add_output arg
30
35
  end
31
36
  elsif is_escaped? exp
32
- add_escaped_output exp.first_arg
37
+ add_escaped_output arg
33
38
  elsif target == nil and method == :render
34
39
  exp.arglist = process exp.arglist
35
40
  make_render_in_view exp
@@ -73,12 +78,25 @@ class Brakeman::SlimTemplateProcessor < Brakeman::TemplateProcessor
73
78
  end
74
79
  end
75
80
 
81
+ def add_escaped_output exp
82
+ exp = normalize_output(exp)
83
+
84
+ return exp if string? exp or internal_variable? exp
85
+
86
+ super exp
87
+ end
88
+
76
89
  def is_escaped? exp
77
90
  call? exp and
78
91
  exp.target == TEMPLE_UTILS and
79
92
  (exp.method == :escape_html or exp.method == :escape_html_safe)
80
93
  end
81
94
 
95
+ def internal_variable? exp
96
+ node_type? exp, :lvar and
97
+ exp.value =~ /^_(temple_|slim_)/
98
+ end
99
+
82
100
  def render? exp
83
101
  call? exp and
84
102
  exp.target.nil? and
@@ -6,7 +6,7 @@ require 'brakeman/report/report_base'
6
6
  class Brakeman::Report
7
7
  attr_reader :tracker
8
8
 
9
- VALID_FORMATS = [:to_html, :to_pdf, :to_csv, :to_json, :to_tabs, :to_hash, :to_s, :to_markdown, :to_codeclimate]
9
+ VALID_FORMATS = [:to_html, :to_pdf, :to_csv, :to_json, :to_tabs, :to_hash, :to_s, :to_markdown, :to_codeclimate, :to_plain]
10
10
 
11
11
  def initialize app_tree, tracker
12
12
  @app_tree = app_tree
@@ -34,6 +34,8 @@ class Brakeman::Report
34
34
  Brakeman::Report::Hash
35
35
  when :to_markdown
36
36
  return self.to_markdown
37
+ when :to_plain
38
+ return self.to_plain
37
39
  when :to_s
38
40
  return self.to_s
39
41
  when :to_pdf
@@ -72,6 +74,11 @@ class Brakeman::Report
72
74
  generate Brakeman::Report::Markdown
73
75
  end
74
76
 
77
+ def to_plain
78
+ require_report 'text'
79
+ generate Brakeman::Report::Text
80
+ end
81
+
75
82
  def generate reporter
76
83
  reporter.new(@app_tree, @tracker).generate_report
77
84
  end
@@ -11,6 +11,7 @@ module Brakeman
11
11
  @new_warnings = new_warnings
12
12
  @already_ignored = []
13
13
  @ignored_fingerprints = Set.new
14
+ @used_fingerprints = Set.new
14
15
  @notes = {}
15
16
  @shown_warnings = @ignored_warnings = nil
16
17
  @changed = false
@@ -43,6 +44,7 @@ module Brakeman
43
44
 
44
45
  # Determine if warning should be ignored
45
46
  def ignored? warning
47
+ @used_fingerprints << warning.fingerprint
46
48
  @ignored_fingerprints.include? warning.fingerprint
47
49
  end
48
50
 
@@ -75,6 +77,22 @@ module Brakeman
75
77
  nil
76
78
  end
77
79
 
80
+ # The set of unused ignore entries
81
+ def obsolete_fingerprints
82
+ (@ignored_fingerprints - @used_fingerprints).to_a
83
+ end
84
+
85
+ def prune_obsolete
86
+ obsolete = obsolete_fingerprints.to_set
87
+ @ignored_fingerprints -= obsolete
88
+
89
+ @already_ignored.reject! do |w|
90
+ if obsolete.include? w[:fingerprint]
91
+ @changed = true
92
+ end
93
+ end
94
+ end
95
+
78
96
  # Read configuration to file
79
97
  def read_from_file file = @file
80
98
  if File.exist? file
@@ -19,6 +19,7 @@ module Brakeman
19
19
  @ignore_config.filter_ignored
20
20
 
21
21
  unless @quit
22
+ penultimate_menu
22
23
  final_menu
23
24
  end
24
25
 
@@ -65,6 +66,10 @@ module Brakeman
65
66
  process_warnings
66
67
  end
67
68
 
69
+ m.choice "Prune obsolete ignored warnings" do
70
+ prune_obsolete
71
+ end
72
+
68
73
  m.choice "Skip - use current ignore configuration" do
69
74
  @quit = true
70
75
  @ignore_config.filter_ignored
@@ -103,6 +108,36 @@ q - Quit, do not update ignored warnings
103
108
  end
104
109
  end
105
110
 
111
+ def penultimate_menu
112
+ obsolete = @ignore_config.obsolete_fingerprints
113
+ return unless obsolete.any?
114
+
115
+ if obsolete.length > 1
116
+ plural = 's'
117
+ verb = 'are'
118
+ else
119
+ plural = ''
120
+ verb = 'is'
121
+ end
122
+
123
+ say "\n#{obsolete.length} fingerprint#{plural} #{verb} unused:", :green
124
+ obsolete.each do |obs|
125
+ say obs
126
+ end
127
+
128
+ if yes_or_no "\nRemove fingerprint#{plural}?"
129
+ @ignore_config.prune_obsolete
130
+ end
131
+ end
132
+
133
+ def prune_obsolete
134
+ @ignore_config.filter_ignored
135
+ obsolete = @ignore_config.obsolete_fingerprints
136
+ @ignore_config.prune_obsolete
137
+
138
+ say "Removed #{obsolete.length} obsolete fingerprint#{'s' if obsolete.length > 1} from ignore config.", :yellow
139
+ end
140
+
106
141
  def final_menu
107
142
  summarize_changes
108
143
 
@@ -79,6 +79,11 @@ class Brakeman::Report::Base
79
79
  render_array('error_overview', ['Error', 'Location'], values, {:tracker => tracker})
80
80
  end
81
81
 
82
+ def generate_obsolete
83
+ values = tracker.unused_fingerprints.collect{|fingerprint| [fingerprint] }
84
+ render_array('obsolete_ignore_entries', ['fingerprint'], values, {:tracker => tracker})
85
+ end
86
+
82
87
  def generate_warnings
83
88
  render_warnings generic_warnings,
84
89
  :warning,
@@ -2,6 +2,8 @@ class Brakeman::Report::JSON < Brakeman::Report::Base
2
2
  def generate_report
3
3
  errors = tracker.errors.map{|e| { :error => e[:error], :location => e[:backtrace][0] }}
4
4
 
5
+ obsolete = tracker.unused_fingerprints
6
+
5
7
  warnings = convert_to_hashes all_warnings
6
8
 
7
9
  ignored = convert_to_hashes ignored_warnings
@@ -26,7 +28,8 @@ class Brakeman::Report::JSON < Brakeman::Report::Base
26
28
  :scan_info => scan_info,
27
29
  :warnings => warnings,
28
30
  :ignored_warnings => ignored,
29
- :errors => errors
31
+ :errors => errors,
32
+ :obsolete => obsolete
30
33
  }
31
34
 
32
35
  JSON.pretty_generate report_info
@@ -25,6 +25,7 @@ class Brakeman::Report::Table < Brakeman::Report::Base
25
25
  truncate_table(generate_templates.to_s) << "\n"
26
26
  end
27
27
 
28
+ output_table("+Obsolete Ignore Entries+", generate_obsolete, out)
28
29
  output_table("+Errors+", generate_errors, out)
29
30
  output_table("+SECURITY WARNINGS+", generate_warnings, out)
30
31
  output_table("Controller Warnings:", generate_controller_warnings, out)
@@ -0,0 +1,193 @@
1
+ Brakeman.load_brakeman_dependency 'highline'
2
+
3
+ class Brakeman::Report::Text < Brakeman::Report::Base
4
+ def generate_report
5
+ HighLine.use_color = !!tracker.options[:output_color]
6
+ @output_string = "\n"
7
+
8
+ add_chunk generate_header
9
+ add_chunk generate_overview
10
+ add_chunk generate_warning_overview
11
+ return @output_string if tracker.options[:summary_only]
12
+
13
+ add_chunk generate_controllers if tracker.options[:debug] or tracker.options[:report_routes]
14
+ add_chunk generate_templates if tracker.options[:debug]
15
+ add_chunk generate_obsolete
16
+ add_chunk generate_errors
17
+ add_chunk generate_warnings
18
+ end
19
+
20
+ def add_chunk chunk, out = @output_string
21
+ if chunk and not chunk.empty?
22
+ if chunk.is_a? Array
23
+ chunk = chunk.join("\n")
24
+ end
25
+
26
+ out << chunk << "\n\n"
27
+ end
28
+ end
29
+
30
+ def generate_header
31
+ [
32
+ header("Brakeman Report"),
33
+ label("Application Path", tracker.app_path),
34
+ label("Rails Version", rails_version),
35
+ label("Brakeman Version", Brakeman::Version),
36
+ label("Scan Date", tracker.start_time),
37
+ label("Duration", "#{tracker.duration} seconds"),
38
+ label("Checks Run", checks.checks_run.sort.join(", "))
39
+ ]
40
+ end
41
+
42
+ def generate_overview
43
+ overview = [
44
+ header("Overview"),
45
+ label('Controllers', tracker.controllers.length),
46
+ label('Models', tracker.models.length - 1),
47
+ label('Templates', number_of_templates(@tracker)),
48
+ label('Errors', tracker.errors.length),
49
+ label('Security Warnings', all_warnings.length)
50
+ ]
51
+
52
+ unless ignored_warnings.empty?
53
+ overview << label('Ignored Warnings', ignored_warnings.length)
54
+ end
55
+
56
+ overview
57
+ end
58
+
59
+ def generate_warning_overview
60
+ warning_types = warnings_summary
61
+ warning_types.delete :high_confidence
62
+
63
+ warning_types.sort_by { |t, c| t }.map do |type, count|
64
+ label(type, count)
65
+ end.unshift(header('Warning Types'))
66
+ end
67
+
68
+ def generate_warnings
69
+ if tracker.filtered_warnings.empty?
70
+ HighLine.color("No warnings found", :bold, :green)
71
+ else
72
+ warnings = tracker.filtered_warnings.sort_by do |w|
73
+ [w.confidence, w.warning_type, w.fingerprint]
74
+ end.map do |w|
75
+ output_warning w
76
+ end
77
+
78
+ double_space "Warnings", warnings
79
+ end
80
+ end
81
+
82
+ def generate_errors
83
+ return if tracker.errors.empty?
84
+ full_trace = tracker.options[:debug]
85
+
86
+ errors = tracker.errors.map do |e|
87
+ trace = if full_trace
88
+ e[:backtrace].join("\n")
89
+ else
90
+ e[:backtrace][0]
91
+ end
92
+
93
+ [
94
+ label("Error", e[:error]),
95
+ label("Location", trace)
96
+ ]
97
+ end
98
+
99
+ double_space "Errors", errors
100
+ end
101
+
102
+ def generate_obsolete
103
+ return if tracker.unused_fingerprints.empty?
104
+
105
+ [header("Obsolete Ignore Entries")] + tracker.unused_fingerprints
106
+ end
107
+
108
+ def generate_templates
109
+ out_processor = Brakeman::OutputProcessor.new
110
+
111
+ template_rows = {}
112
+ tracker.templates.each do |name, template|
113
+ template.each_output do |out|
114
+ out = out_processor.format out
115
+ template_rows[name] ||= []
116
+ template_rows[name] << out.gsub("\n", ";").gsub(/\s+/, " ")
117
+ end
118
+ end
119
+
120
+ double_space "Template Output", template_rows.sort_by { |name, value| name.to_s }.map { |template|
121
+ [HighLine.new.color(template.first.to_s << "\n", :cyan)] + template[1]
122
+ }.compact
123
+ end
124
+
125
+ def output_warning w
126
+ out = [
127
+ label('Confidence', confidence(w.confidence)),
128
+ label('Category', w.warning_type.to_s),
129
+ label('Message', w.message)
130
+ ]
131
+
132
+ if w.code
133
+ out << label('Code', format_code(w))
134
+ end
135
+
136
+ out << label('File', warning_file(w))
137
+
138
+ if w.line
139
+ out << label('Line', w.line)
140
+ end
141
+
142
+ out
143
+ end
144
+
145
+ def double_space title, values
146
+ values = values.map { |v| v.join("\n") }.join("\n\n")
147
+ [header(title), values]
148
+ end
149
+
150
+ def format_code w
151
+ if @highlight_user_input and w.user_input
152
+ w.format_with_user_input do |exp, text|
153
+ HighLine.new.color(text, :yellow)
154
+ end
155
+ else
156
+ w.format_code
157
+ end
158
+ end
159
+
160
+ def confidence c
161
+ case c
162
+ when 0
163
+ HighLine.new.color("High", :red)
164
+ when 1
165
+ HighLine.new.color("Medium", :yellow)
166
+ when 2
167
+ HighLine.new.color("Weak", :none)
168
+ end
169
+ end
170
+
171
+ def label l, value, color = :green
172
+ "#{HighLine.new.color(l, color)}: #{value}"
173
+ end
174
+
175
+ def header text
176
+ HighLine.new.color("== #{text} ==\n", :bold, :magenta)
177
+ end
178
+
179
+ # ONLY used for generate_controllers to avoid duplication
180
+ def render_array name, cols, values, locals
181
+ controllers = values.map do |name, parent, includes, routes|
182
+ [
183
+ label("Controller", name),
184
+ label("Parent", parent),
185
+ label("Includes", includes),
186
+ label("Routes", routes)
187
+ ]
188
+ end
189
+
190
+ double_space "Controller Overview", controllers
191
+ end
192
+ end
193
+
@@ -185,6 +185,11 @@ class Brakeman::Tracker
185
185
  end
186
186
  end
187
187
 
188
+ def unused_fingerprints
189
+ return [] unless self.ignored_filter
190
+ self.ignored_filter.obsolete_fingerprints
191
+ end
192
+
188
193
  def add_constant name, value, context = nil
189
194
  @constants.add name, value, context unless @options[:disable_constant_tracking]
190
195
  end
@@ -1,3 +1,3 @@
1
1
  module Brakeman
2
- Version = "3.3.5"
2
+ Version = "3.4.0"
3
3
  end
@@ -134,6 +134,16 @@ class Brakeman::Warning
134
134
  format_ruby self.user_input, strip
135
135
  end
136
136
 
137
+ def format_with_user_input strip = true, &block
138
+ if self.user_input
139
+ formatted = Brakeman::OutputProcessor.new.format(code, self.user_input, &block)
140
+ formatted.gsub!(/(\t|\r|\n)+/, " ") if strip
141
+ formatted
142
+ else
143
+ format_code
144
+ end
145
+ end
146
+
137
147
  #Return formatted warning message
138
148
  def format_message
139
149
  return @format_message if @format_message
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brakeman-min
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.5
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Collins
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain:
11
11
  - brakeman-public_cert.pem
12
- date: 2016-08-12 00:00:00.000000000 Z
12
+ date: 2016-09-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: minitest
@@ -207,6 +207,7 @@ files:
207
207
  - lib/brakeman/report/report_markdown.rb
208
208
  - lib/brakeman/report/report_table.rb
209
209
  - lib/brakeman/report/report_tabs.rb
210
+ - lib/brakeman/report/report_text.rb
210
211
  - lib/brakeman/report/templates/controller_overview.html.erb
211
212
  - lib/brakeman/report/templates/controller_warnings.html.erb
212
213
  - lib/brakeman/report/templates/error_overview.html.erb