brakeman-lib 3.7.0 → 3.7.1

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: 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