brakeman-lib 3.7.0 → 3.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3c3cd6ef685d42e97e293f59c00f8dbb22fdd260
4
- data.tar.gz: 607b26573452f7a3003e34ff1151dc1e46a41cb1
3
+ metadata.gz: d8caf9e1df412c52a1a95b66b77512b0a8e8ff48
4
+ data.tar.gz: de550a511ffb1f74a101214a5184afa7edb0b878
5
5
  SHA512:
6
- metadata.gz: b88ae2370d4dfde46dcfd88558bf41bbc99bb2b371ea27749bdb0a0c1e0bb456f9de3ecc44f9f891f61ae4f19cb99ae2b2347f55391580f8ae43c72657ac410b
7
- data.tar.gz: a0ff1f759bde8f5ed837bc01d812bbc8e6140b4e8930ab799cd0e7362c7a5594272a9ef438cf1eaf3291431442d67f051c33aff5a2322ee131267f1eb218e179
6
+ metadata.gz: d8938f327f53f200f7d0dcf4a89ca8b7785deff656cf8ac55469366e419517bf8644a8152b71fe3611e2e9a8622791cf09ab88a09e93f0a0fc9e17b265c0dc1d
7
+ data.tar.gz: f76360d0a4d0b1850a599efea4e1be2e08cd2c1795274705abaf92a95d200af5769dfc70320ccf0fbdaa710bc00889854fd5a0091b8d7fe8e79c914bf2d92c95
data/CHANGES CHANGED
@@ -1,3 +1,11 @@
1
+ # 3.7.1
2
+
3
+ * Handle simple guard with return at end of branch
4
+ * Modularize bin/brakeman
5
+ * Improve multi-value Sexp error message
6
+ * Add more collection methods for iteration detection
7
+ * Update ruby2ruby and ruby_parser
8
+
1
9
  # 3.7.0
2
10
 
3
11
  * Improve support for rails4/rails5 options in config file
data/bin/brakeman CHANGED
@@ -3,100 +3,6 @@
3
3
  $:.unshift "#{File.expand_path(File.dirname(__FILE__))}/../lib"
4
4
 
5
5
  require 'brakeman'
6
- require 'brakeman/options'
7
- require 'brakeman/version'
6
+ require 'brakeman/commandline'
8
7
 
9
- #Parse options
10
- begin
11
- options, parser = Brakeman::Options.parse! ARGV
12
- rescue OptionParser::ParseError => e
13
- $stderr.puts e.message
14
- $stderr.puts "Please see `brakeman --help` for valid options"
15
- exit(-1)
16
- end
17
-
18
- #Exit early for these options
19
- if options[:list_checks] or options[:list_optional_checks]
20
- Brakeman.list_checks options
21
- exit
22
- elsif options[:create_config]
23
- Brakeman.dump_config options
24
- exit
25
- elsif options[:show_help]
26
- puts parser
27
- exit
28
- elsif options[:show_version]
29
- puts "brakeman #{Brakeman::Version}"
30
- exit
31
- end
32
-
33
- #Set application path according to the commandline arguments
34
- unless options[:app_path]
35
- if ARGV[-1].nil?
36
- options[:app_path] = "."
37
- else
38
- options[:app_path] = ARGV[-1]
39
- end
40
- end
41
-
42
- trap("INT") do
43
- $stderr.puts "\nInterrupted - exiting."
44
-
45
- if options[:debug]
46
- $stderr.puts caller
47
- end
48
-
49
- exit!
50
- end
51
-
52
- if options[:quiet].nil?
53
- options[:quiet] = :command_line
54
- end
55
-
56
- begin
57
- if options[:ensure_latest]
58
- if error = Brakeman.ensure_latest
59
- warn error
60
- exit Brakeman::Not_Latest_Version_Exit_Code
61
- end
62
- end
63
-
64
- if options[:previous_results_json]
65
- require 'json'
66
- vulns = Brakeman.compare options.merge(:quiet => options[:quiet])
67
-
68
- if options[:comparison_output_file]
69
- File.open options[:comparison_output_file], "w" do |f|
70
- f.puts JSON.pretty_generate(vulns)
71
- end
72
-
73
- Brakeman.notify "Comparison saved in '#{options[:comparison_output_file]}'"
74
- else
75
- puts JSON.pretty_generate(vulns)
76
- end
77
-
78
- if options[:exit_on_warn] && vulns[:new].count > 0
79
- exit Brakeman::Warnings_Found_Exit_Code
80
- end
81
- else
82
- #Run scan and output a report
83
- tracker = Brakeman.run options.merge(:print_report => true, :quiet => options[:quiet])
84
-
85
- #Return error code if --exit-on-warn is used and warnings were found
86
- if tracker.options[:exit_on_warn] and not tracker.filtered_warnings.empty?
87
- exit Brakeman::Warnings_Found_Exit_Code
88
- end
89
-
90
- #Return error code if --exit-on-error is used and errors were found
91
- if tracker.options[:exit_on_error] and tracker.errors.any?
92
- exit Brakeman::Errors_Found_Exit_Code
93
- end
94
- end
95
-
96
- rescue Brakeman::NoApplication => e
97
- warn e.message
98
- exit Brakeman::No_App_Found_Exit_Code
99
- rescue Brakeman::MissingChecksError => e
100
- warn e.message
101
- exit Brakeman::Missing_Checks_Exit_Code
102
- end
8
+ Brakeman::Commandline.start
data/lib/brakeman.rb CHANGED
@@ -511,6 +511,14 @@ module Brakeman
511
511
  end
512
512
  end
513
513
 
514
+ def self.debug= val
515
+ @debug = val
516
+ end
517
+
518
+ def self.quiet= val
519
+ @quiet = val
520
+ end
521
+
514
522
  class DependencyError < RuntimeError; end
515
523
  class NoBrakemanError < RuntimeError; end
516
524
  class NoApplication < RuntimeError; end
@@ -0,0 +1,179 @@
1
+ require 'brakeman/options'
2
+
3
+ module Brakeman
4
+
5
+ # Implements handling of running Brakeman from the command line.
6
+ class Commandline
7
+ class << self
8
+
9
+ # Main method to run Brakeman from the command line.
10
+ #
11
+ # If no options are provided, ARGV will be parsed and used instead.
12
+ # Otherwise, the options are expected to be a Hash like the one returned
13
+ # after ARGV is parsed.
14
+ def start options = nil, app_path = "."
15
+
16
+ unless options
17
+ options, app_path = parse_options ARGV
18
+ end
19
+
20
+ run options, app_path
21
+ end
22
+
23
+ # Runs everything:
24
+ #
25
+ # - `set_interrupt_handler`
26
+ # - `early_exit_options`
27
+ # - `set_options`
28
+ # - `check_latest`
29
+ # - `run_report`
30
+ def run options, default_app_path = "."
31
+ set_interrupt_handler options
32
+ early_exit_options options
33
+ set_options options, default_app_path
34
+ check_latest if options[:ensure_latest]
35
+ run_report options
36
+ end
37
+
38
+ # Check for the latest version.
39
+ #
40
+ # If the latest version is newer, quit with a message.
41
+ def check_latest
42
+ if error = Brakeman.ensure_latest
43
+ quit Brakeman::Not_Latest_Version_Exit_Code, error
44
+ end
45
+ end
46
+
47
+ # Runs a comparison report based on the options provided.
48
+ def compare_results options
49
+ require 'json'
50
+ vulns = Brakeman.compare options.merge(:quiet => options[:quiet])
51
+
52
+ if options[:comparison_output_file]
53
+ File.open options[:comparison_output_file], "w" do |f|
54
+ f.puts JSON.pretty_generate(vulns)
55
+ end
56
+
57
+ Brakeman.notify "Comparison saved in '#{options[:comparison_output_file]}'"
58
+ else
59
+ puts JSON.pretty_generate(vulns)
60
+ end
61
+
62
+ if options[:exit_on_warn] && vulns[:new].count > 0
63
+ quit Brakeman::Warnings_Found_Exit_Code
64
+ end
65
+ end
66
+
67
+ # Handle options that exit without generating a report.
68
+ def early_exit_options options
69
+ if options[:list_checks] or options[:list_optional_checks]
70
+ Brakeman.list_checks options
71
+ quit
72
+ elsif options[:create_config]
73
+ Brakeman.dump_config options
74
+ quit
75
+ elsif options[:show_help]
76
+ puts Brakeman::Options.create_option_parser({})
77
+ quit
78
+ elsif options[:show_version]
79
+ require 'brakeman/version'
80
+ puts "brakeman #{Brakeman::Version}"
81
+ quit
82
+ end
83
+ end
84
+
85
+ # Parse ARGV-style array of options.
86
+ #
87
+ # Exits if options are invalid.
88
+ #
89
+ # Returns an option hash and the app_path.
90
+ def parse_options argv
91
+ begin
92
+ options, _ = Brakeman::Options.parse! argv
93
+ rescue OptionParser::ParseError => e
94
+ $stderr.puts e.message
95
+ $stderr.puts "Please see `brakeman --help` for valid options"
96
+ quit(-1)
97
+ end
98
+
99
+ if argv[-1]
100
+ app_path = argv[-1]
101
+ else
102
+ app_path = "."
103
+ end
104
+
105
+ return options, app_path
106
+ end
107
+
108
+ # Exits with the given exit code and prints out the message, if given.
109
+ #
110
+ # Override this method for different behavior.
111
+ def quit exit_code = 0, message = nil
112
+ warn message if message
113
+ exit exit_code
114
+ end
115
+
116
+ # Runs a regular report based on the options provided.
117
+ def regular_report options
118
+ tracker = run_brakeman options
119
+
120
+ if options[:exit_on_warn] and not tracker.filtered_warnings.empty?
121
+ quit Brakeman::Warnings_Found_Exit_Code
122
+ end
123
+
124
+ if options[:exit_on_error] and tracker.errors.any?
125
+ quit Brakeman::Errors_Found_Exit_Code
126
+ end
127
+ end
128
+
129
+ # Actually run Brakeman.
130
+ #
131
+ # Returns a Tracker object.
132
+ def run_brakeman options
133
+ Brakeman.run options.merge(:print_report => true, :quiet => options[:quiet])
134
+ end
135
+
136
+ # Run either a comparison or regular report based on options provided.
137
+ def run_report options
138
+ begin
139
+ if options[:previous_results_json]
140
+ compare_results options
141
+ else
142
+ regular_report options
143
+ end
144
+ rescue Brakeman::NoApplication => e
145
+ quit Brakeman::No_App_Found_Exit_Code, e.message
146
+ rescue Brakeman::MissingChecksError => e
147
+ quit Brakeman::Missing_Checks_Exit_Code, e.message
148
+ end
149
+ end
150
+
151
+ # Sets interrupt handler to gracefully handle Ctrl+C
152
+ def set_interrupt_handler options
153
+ trap("INT") do
154
+ warn "\nInterrupted - exiting."
155
+
156
+ if options[:debug]
157
+ warn caller
158
+ end
159
+
160
+ exit!
161
+ end
162
+ end
163
+
164
+ # Modifies options, including setting the app_path
165
+ # if none is given in the options hash.
166
+ def set_options options, default_app_path = "."
167
+ unless options[:app_path]
168
+ options[:app_path] = default_app_path
169
+ end
170
+
171
+ if options[:quiet].nil?
172
+ options[:quiet] = :command_line
173
+ end
174
+
175
+ options
176
+ end
177
+ end
178
+ end
179
+ end
@@ -20,7 +20,23 @@ module Brakeman::Options
20
20
  def get_options args, destructive = false
21
21
  options = {}
22
22
 
23
- parser = OptionParser.new do |opts|
23
+ parser = create_option_parser options
24
+
25
+ if destructive
26
+ parser.parse! args
27
+ else
28
+ parser.parse args
29
+ end
30
+
31
+ if options[:previous_results_json] and options[:output_files]
32
+ options[:comparison_output_file] = options[:output_files].shift
33
+ end
34
+
35
+ return options, parser
36
+ end
37
+
38
+ def create_option_parser options
39
+ OptionParser.new do |opts|
24
40
  opts.banner = "Usage: brakeman [options] rails/root/path"
25
41
 
26
42
  opts.on "-n", "--no-threads", "Run checks sequentially" do
@@ -306,18 +322,6 @@ module Brakeman::Options
306
322
  options[:show_help] = true
307
323
  end
308
324
  end
309
-
310
- if destructive
311
- parser.parse! args
312
- else
313
- parser.parse args
314
- end
315
-
316
- if options[:previous_results_json] and options[:output_files]
317
- options[:comparison_output_file] = options[:output_files].shift
318
- end
319
-
320
- return options, parser
321
325
  end
322
326
  end
323
327
  end
@@ -682,7 +682,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
682
682
  env.current[var] = condition.target[1]
683
683
  exp[branch_index] = process_if_branch branch
684
684
  env.current[var] = previous_value
685
- elsif i == 1 and array_include_all_literals? condition and node_type? branch, :return
685
+ elsif i == 1 and array_include_all_literals? condition and early_return? branch
686
686
  var = condition.first_arg
687
687
  env.current[var] = condition.target[1]
688
688
  exp[branch_index] = process_if_branch branch
@@ -704,6 +704,16 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
704
704
  exp
705
705
  end
706
706
 
707
+ def early_return? exp
708
+ return true if node_type? exp, :return
709
+
710
+ if node_type? exp, :block, :rlist
711
+ node_type? exp.last, :return
712
+ else
713
+ false
714
+ end
715
+ end
716
+
707
717
  def simple_when? exp
708
718
  node_type? exp[1], :array and
709
719
  not node_type? exp[1][1], :splat, :array and
@@ -30,22 +30,18 @@ class Brakeman::OutputProcessor < Ruby2Ruby
30
30
  end
31
31
 
32
32
  def process_ignore exp
33
- exp.clear
34
33
  "[ignored]"
35
34
  end
36
35
 
37
36
  def process_params exp
38
- exp.clear
39
37
  "params"
40
38
  end
41
39
 
42
40
  def process_session exp
43
- exp.clear
44
41
  "session"
45
42
  end
46
43
 
47
44
  def process_cookies exp
48
- exp.clear
49
45
  "cookies"
50
46
  end
51
47
 
@@ -58,13 +54,15 @@ class Brakeman::OutputProcessor < Ruby2Ruby
58
54
  res
59
55
  end
60
56
  end.compact.join("\n")
61
- exp.clear
57
+
62
58
  out
63
59
  end
64
60
 
65
61
  def process_defn exp
66
62
  # Copied from Ruby2Ruby except without the whole
67
63
  # "convert methods to attr_*" stuff
64
+ exp = exp.deep_clone
65
+ exp.shift
68
66
  name = exp.shift
69
67
  args = process exp.shift
70
68
  args = "" if args == "()"
@@ -84,10 +82,10 @@ class Brakeman::OutputProcessor < Ruby2Ruby
84
82
  end
85
83
 
86
84
  def process_iter exp
87
- call = process exp[0]
88
- block = process_rlist exp[2..-1]
85
+ call = process exp[1]
86
+ block = process_rlist exp[3..-1]
89
87
  out = "#{call} do\n #{block}\n end"
90
- exp.clear
88
+
91
89
  out
92
90
  end
93
91
 
@@ -109,10 +107,10 @@ class Brakeman::OutputProcessor < Ruby2Ruby
109
107
  end
110
108
 
111
109
  def output_format exp, tag
112
- out = if exp[0].node_type == :str or exp[0].node_type == :ignore
110
+ out = if exp[1].node_type == :str or exp[1].node_type == :ignore
113
111
  ""
114
112
  else
115
- res = process exp[0]
113
+ res = process exp[1]
116
114
 
117
115
  if res == ""
118
116
  ""
@@ -120,26 +118,27 @@ class Brakeman::OutputProcessor < Ruby2Ruby
120
118
  "[#{tag}] #{res}"
121
119
  end
122
120
  end
123
- exp.clear
121
+
124
122
  out
125
123
  end
126
124
 
127
125
  def process_const exp
128
- if exp[0] == Brakeman::Tracker::UNKNOWN_MODEL
129
- exp.clear
126
+ if exp[1] == Brakeman::Tracker::UNKNOWN_MODEL
130
127
  "(Unresolved Model)"
131
128
  else
132
- out = exp[0].to_s
133
- exp.clear
129
+ out = exp[1].to_s
134
130
  out
135
131
  end
136
132
  end
137
133
 
138
134
  def process_render exp
135
+ exp = exp.deep_clone
136
+ exp.shift
137
+
139
138
  exp[1] = process exp[1] if sexp? exp[1]
140
139
  exp[2] = process exp[2] if sexp? exp[2]
141
140
  out = "render(#{exp[0]} => #{exp[1]}, #{exp[2]})"
142
- exp.clear
141
+
143
142
  out
144
143
  end
145
144
  end
@@ -79,12 +79,14 @@ class Brakeman::TemplateAliasProcessor < Brakeman::AliasProcessor
79
79
  exp
80
80
  end
81
81
 
82
+ COLLECTION_METHODS = [:all, :find, :select, :where]
83
+
82
84
  #Checks if +exp+ is a call to Model.all or Model.find*
83
85
  def get_model_target exp
84
86
  if call? exp
85
87
  target = exp.target
86
88
 
87
- if exp.method == :all or exp.method.to_s[0,4] == "find"
89
+ if COLLECTION_METHODS.include? exp.method or exp.method.to_s[0,4] == "find"
88
90
  models = Set.new @tracker.models.keys
89
91
  name = class_name target
90
92
  return target if models.include?(name)
@@ -1,3 +1,3 @@
1
1
  module Brakeman
2
- Version = "3.7.0"
2
+ Version = "3.7.1"
3
3
  end
@@ -50,12 +50,12 @@ class Sexp
50
50
  end
51
51
 
52
52
  def value
53
- raise WrongSexpError, "Sexp#value called on multi-item Sexp", caller[1..-1] if size > 2
53
+ raise WrongSexpError, "Sexp#value called on multi-item Sexp: `#{self.inspect}`" if size > 2
54
54
  self[1]
55
55
  end
56
56
 
57
57
  def value= exp
58
- raise WrongSexpError, "Sexp#value= called on multi-item Sexp", caller[1..-1] if size > 2
58
+ raise WrongSexpError, "Sexp#value= called on multi-item Sexp: `#{self.inspect}`" if size > 2
59
59
  @my_hash_value = nil
60
60
  self[1] = exp
61
61
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brakeman-lib
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.7.0
4
+ version: 3.7.1
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: 2017-06-30 00:00:00.000000000 Z
12
+ date: 2017-08-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: minitest
@@ -31,14 +31,14 @@ dependencies:
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: 3.9.0
34
+ version: 3.10.0
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: 3.9.0
41
+ version: 3.10.0
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: sexp_processor
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -59,14 +59,14 @@ dependencies:
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: 2.3.0
62
+ version: 2.4.0
63
63
  type: :runtime
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
- version: 2.3.0
69
+ version: 2.4.0
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: safe_yaml
72
72
  requirement: !ruby/object:Gem::Requirement
@@ -156,6 +156,9 @@ dependencies:
156
156
  - - "~>"
157
157
  - !ruby/object:Gem::Version
158
158
  version: '3.0'
159
+ - - "<"
160
+ - !ruby/object:Gem::Version
161
+ version: 3.5.0
159
162
  type: :runtime
160
163
  prerelease: false
161
164
  version_requirements: !ruby/object:Gem::Requirement
@@ -163,6 +166,9 @@ dependencies:
163
166
  - - "~>"
164
167
  - !ruby/object:Gem::Version
165
168
  version: '3.0'
169
+ - - "<"
170
+ - !ruby/object:Gem::Version
171
+ version: 3.5.0
166
172
  - !ruby/object:Gem::Dependency
167
173
  name: slim
168
174
  requirement: !ruby/object:Gem::Requirement
@@ -268,6 +274,7 @@ files:
268
274
  - lib/brakeman/checks/check_without_protection.rb
269
275
  - lib/brakeman/checks/check_xml_dos.rb
270
276
  - lib/brakeman/checks/check_yaml_parsing.rb
277
+ - lib/brakeman/commandline.rb
271
278
  - lib/brakeman/differ.rb
272
279
  - lib/brakeman/file_parser.rb
273
280
  - lib/brakeman/format/style.css