brakeman 4.3.0 → 4.3.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.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +13 -0
  3. data/README.md +2 -2
  4. data/bundle/load.rb +1 -1
  5. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.2 → unicode-display_width-1.4.0}/CHANGELOG.md +9 -0
  6. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.2 → unicode-display_width-1.4.0}/MIT-LICENSE.txt +1 -1
  7. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.2 → unicode-display_width-1.4.0}/README.md +6 -2
  8. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.2 → unicode-display_width-1.4.0}/Rakefile +0 -0
  9. data/bundle/ruby/2.5.0/gems/unicode-display_width-1.4.0/data/display_width.marshal.gz +0 -0
  10. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.2 → unicode-display_width-1.4.0}/lib/unicode/display_width.rb +0 -0
  11. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.2 → unicode-display_width-1.4.0}/lib/unicode/display_width/constants.rb +2 -2
  12. data/bundle/ruby/2.5.0/gems/unicode-display_width-1.4.0/lib/unicode/display_width/index.rb +12 -0
  13. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.2 → unicode-display_width-1.4.0}/lib/unicode/display_width/no_string_ext.rb +0 -0
  14. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.2 → unicode-display_width-1.4.0}/lib/unicode/display_width/string_ext.rb +0 -0
  15. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.2 → unicode-display_width-1.4.0}/spec/display_width_spec.rb +0 -0
  16. data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.3.2 → unicode-display_width-1.4.0}/unicode-display_width.gemspec +0 -0
  17. data/lib/brakeman/checks/check_execute.rb +7 -1
  18. data/lib/brakeman/checks/check_sql.rb +4 -2
  19. data/lib/brakeman/parsers/template_parser.rb +5 -1
  20. data/lib/brakeman/processors/alias_processor.rb +40 -102
  21. data/lib/brakeman/processors/controller_alias_processor.rb +5 -2
  22. data/lib/brakeman/processors/lib/call_conversion_helper.rb +90 -0
  23. data/lib/brakeman/processors/library_processor.rb +1 -1
  24. data/lib/brakeman/util.rb +18 -0
  25. data/lib/brakeman/version.rb +1 -1
  26. metadata +15 -14
  27. data/bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/data/display_width.marshal.gz +0 -0
  28. data/bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/lib/unicode/display_width/index.rb +0 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b713c88d7aa856518beb948e7d39c0b43dda963378064d5a3126f9684d6d6a2d
4
- data.tar.gz: 3ed9ad3b22f8196745f64019867776a6c09984d19fdcbe166046aadbbc4b545c
3
+ metadata.gz: b7912833fc9223bcc1cc51f6a167010c98efa8d7708d17cb885982b6abc9aff9
4
+ data.tar.gz: dbbb0d18b323adb38ed5477ae02150f9b87a5f7925720665c29f81642634621b
5
5
  SHA512:
6
- metadata.gz: 90414d86f666acb334d05532d07b1edcf7cb90b8174e4682e06c6fd37c7063709043bf95767246f9529d897e0d39637a0088f2ce32fce1c1db78cd9040e38664
7
- data.tar.gz: b3cdf474521d19cfc27cfd06d9168b3fc97284ff4ad6f73e2615c15099e93a84d0e90b24c185af5108c49b4fac07dae7acd3717f7f9e4f54f1dbd57f487cca17
6
+ metadata.gz: 4b4295ab0723815f53330abf5f83f302d497aea30b8a6d12859956c425e85cc2b1308bceed3b92083955c4cc17d3d1cae0023f182d8e7504ae2061dd30f5c272
7
+ data.tar.gz: 2b87b43e89e578da4ee186ae0c395bfe9f444784a4c19875f87a8f1f4bafba92e3d975f288779b873d3fa8811ae2cb5d15bfccb8b9695e696c0640fac80c8030
data/CHANGES.md CHANGED
@@ -1,3 +1,16 @@
1
+ # 4.3.1
2
+
3
+ * Ignore `Object#freeze`, use the target instead
4
+ * Ignore `foreign_key` calls in SQL
5
+ * Handle `included` calls outside of classes/modules
6
+ * Add `:BRAKEMAN_SAFE_LITERAL` to represent known-safe literals
7
+ * Handle `Array#map` and `Array#each` over literal arrays
8
+ * Use safe literal when accessing literal hash with unknown key
9
+ * Avoid deprecated use of ERB in Ruby 2.6 (Koichi ITO)
10
+ * Allow `symbolize_keys` to be called on `params` in SQL (Jacob Evelyn)
11
+ * Improve handling of conditionals in shell commands (Jacob Evenlyn)
12
+ * Fix error when setting line number in implicit renders
13
+
1
14
  # 4.3.0
2
15
 
3
16
  * Check exec-type calls even if they are targets
data/README.md CHANGED
@@ -82,9 +82,9 @@ If Brakeman is running a bit slow, try
82
82
 
83
83
  This will disable some features, but will probably be much faster (currently it is the same as `--skip-libs --no-branching`). *WARNING*: This may cause Brakeman to miss some vulnerabilities.
84
84
 
85
- By default, Brakeman will return 0 as an exit code unless something went very wrong. To return an error code when warnings were found:
85
+ By default, Brakeman will return a non-zero exit code if any security warnings are found or scanning errors are encountered. To disable this:
86
86
 
87
- brakeman -z
87
+ brakeman --no-exit-on-warn --no-exit-on-error
88
88
 
89
89
  To skip certain files or directories that Brakeman may have trouble parsing, use:
90
90
 
@@ -10,6 +10,6 @@ $:.unshift "#{path}/bundle/ruby/2.5.0/gems/ruby_parser-3.11.0/lib"
10
10
  $:.unshift "#{path}/bundle/ruby/2.5.0/gems/sexp_processor-4.11.0/lib"
11
11
  $:.unshift "#{path}/bundle/ruby/2.5.0/gems/ruby2ruby-2.4.1/lib"
12
12
  $:.unshift "#{path}/bundle/ruby/2.5.0/gems/slim-3.0.7/lib"
13
- $:.unshift "#{path}/bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/lib"
13
+ $:.unshift "#{path}/bundle/ruby/2.5.0/gems/unicode-display_width-1.4.0/lib"
14
14
  $:.unshift "#{path}/bundle/ruby/2.5.0/gems/erubis-2.7.0/lib"
15
15
  $:.unshift "#{path}/bundle/ruby/2.5.0/gems/safe_yaml-1.0.4/lib"
@@ -1,5 +1,14 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.4.0
4
+
5
+ - Unicode 11
6
+
7
+ ## 1.3.3
8
+
9
+ - Replace Gem::Util.gunzip with direct zlib implementation
10
+ This removes the dependency on rubygems, fixes #17
11
+
3
12
  ## 1.3.2
4
13
 
5
14
  - Explicitly load rubygems/util, fixes regression in 1.3.1 (autoload issue)
@@ -1,6 +1,6 @@
1
1
  The MIT LICENSE
2
2
 
3
- Copyright (c) 2011, 2015-2017 Jan Lelis
3
+ Copyright (c) 2011, 2015-2018 Jan Lelis
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
@@ -2,7 +2,11 @@
2
2
 
3
3
  Determines the monospace display width of a string in Ruby. Implementation based on [EastAsianWidth.txt](http://www.unicode.org/Public/UNIDATA/EastAsianWidth.txt) and other data, 100% in Ruby. Other than [wcwidth()](https://github.com/janlelis/wcswidth-ruby), which fulfills a similar purpose, it does not rely on the OS vendor to provide an up-to-date method for measuring string width.
4
4
 
5
- Unicode version: **10.0.0**
5
+ Unicode version: **11.0.0**
6
+
7
+ Supported Rubies: **2.5**, **2.4**, **2.3**
8
+
9
+ Old Rubies that might still work: **2.2**, **2.1**, **2.0**, **1.9**
6
10
 
7
11
  ## Introduction to Character Widths
8
12
 
@@ -114,7 +118,7 @@ See [unicode-x](https://github.com/janlelis/unicode-x) for more Unicode related
114
118
 
115
119
  ## Copyright & Info
116
120
 
117
- - Copyright (c) 2011, 2015-2017 Jan Lelis, http://janlelis.com, released under the MIT
121
+ - Copyright (c) 2011, 2015-2018 Jan Lelis, http://janlelis.com, released under the MIT
118
122
  license
119
123
  - Early versions based on runpaint's unicode-data interface: Copyright (c) 2009 Run Paint Run Run
120
124
  - Unicode data: http://www.unicode.org/copyright.html#Exhibit1
@@ -1,7 +1,7 @@
1
1
  module Unicode
2
2
  module DisplayWidth
3
- VERSION = '1.3.2'
4
- UNICODE_VERSION = "10.0.0".freeze
3
+ VERSION = '1.4.0'
4
+ UNICODE_VERSION = "11.0.0".freeze
5
5
  DATA_DIRECTORY = File.expand_path(File.dirname(__FILE__) + '/../../../data/').freeze
6
6
  INDEX_FILENAME = (DATA_DIRECTORY + '/display_width.marshal.gz').freeze
7
7
  end
@@ -0,0 +1,12 @@
1
+ require 'zlib'
2
+ require_relative 'constants'
3
+
4
+ module Unicode
5
+ module DisplayWidth
6
+ File.open(INDEX_FILENAME, "rb") do |file|
7
+ serialized_data = Zlib::GzipReader.new(file).read
8
+ serialized_data.force_encoding Encoding::BINARY
9
+ INDEX = Marshal.load(serialized_data)
10
+ end
11
+ end
12
+ end
@@ -143,7 +143,13 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
143
143
  next if SAFE_VALUES.include? e
144
144
  next if shell_escape? e
145
145
 
146
- if node_type? e, :or, :evstr, :dstr
146
+ if node_type? e, :if
147
+ # If we're in a conditional, evaluate the `then` and `else` clauses to
148
+ # see if they're dangerous.
149
+ if res = dangerous?(e.values[1..-1])
150
+ return res
151
+ end
152
+ elsif node_type? e, :or, :evstr, :dstr
147
153
  if res = dangerous?(e)
148
154
  return res
149
155
  end
@@ -290,7 +290,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
290
290
  end
291
291
 
292
292
  if request_value? arg
293
- unless call? arg and params? arg.target and [:permit, :slice, :to_h, :to_hash].include? arg.method
293
+ unless call? arg and params? arg.target and [:permit, :slice, :to_h, :to_hash, :symbolize_keys].include? arg.method
294
294
  # Model.where(params[:where])
295
295
  arg
296
296
  end
@@ -404,6 +404,8 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
404
404
  nil
405
405
  elsif call? value and value.method == :to_s
406
406
  unsafe_string_interp? value.target
407
+ elsif call? value and safe_literal_target? value
408
+ nil
407
409
  else
408
410
  case value.node_type
409
411
  when :or
@@ -576,7 +578,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
576
578
  :sanitize_sql_for_assignment, :sanitize_sql_for_conditions, :sanitize_sql_hash,
577
579
  :sanitize_sql_hash_for_assignment, :sanitize_sql_hash_for_conditions,
578
580
  :to_sql, :sanitize, :primary_key, :table_name_prefix, :table_name_suffix,
579
- :where_values_hash
581
+ :where_values_hash, :foreign_key
580
582
  ]
581
583
 
582
584
  def safe_value? exp
@@ -58,7 +58,11 @@ module Brakeman
58
58
  Brakeman::ScannerErubis.new(text, :filename => path).src
59
59
  else
60
60
  require 'erb'
61
- src = ERB.new(text, nil, path).src
61
+ src = if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+
62
+ ERB.new(text, trim_mode: path).src
63
+ else
64
+ ERB.new(text, nil, path).src
65
+ end
62
66
  src.sub!(/^#.*\n/, '') if Brakeman::Scanner::RUBY_1_9
63
67
  src
64
68
  end
@@ -2,6 +2,7 @@ require 'brakeman/util'
2
2
  require 'ruby_parser/bm_sexp_processor'
3
3
  require 'brakeman/processors/lib/processor_helper'
4
4
  require 'brakeman/processors/lib/safe_call_helper'
5
+ require 'brakeman/processors/lib/call_conversion_helper'
5
6
 
6
7
  #Returns an s-expression with aliases replaced with their value.
7
8
  #This does not preserve semantics (due to side effects, etc.), but it makes
@@ -10,6 +11,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
10
11
  include Brakeman::ProcessorHelper
11
12
  include Brakeman::SafeCallHelper
12
13
  include Brakeman::Util
14
+ include Brakeman::CallConversionHelper
13
15
 
14
16
  attr_reader :result, :tracker
15
17
 
@@ -122,7 +124,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
122
124
  end
123
125
 
124
126
  if hash? t
125
- if v = hash_access(t, exp.first_arg)
127
+ if v = process_hash_access(t, exp.first_arg)
126
128
  v.deep_clone(exp.line)
127
129
  else
128
130
  case t.node_type
@@ -202,49 +204,19 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
202
204
  case method
203
205
  when :+
204
206
  if array? target and array? first_arg
205
- joined = join_arrays target, first_arg
206
- joined.line(exp.line)
207
- exp = joined
207
+ exp = join_arrays(target, first_arg, exp)
208
208
  elsif string? first_arg
209
- if string? target # "blah" + "blah"
210
- joined = join_strings target, first_arg
211
- joined.line(exp.line)
212
- exp = joined
213
- elsif call? target and target.method == :+ and string? target.first_arg
214
- joined = join_strings target.first_arg, first_arg
215
- joined.line(exp.line)
216
- target.first_arg = joined
217
- exp = target
218
- end
209
+ exp = join_strings(target, first_arg, exp)
219
210
  elsif number? first_arg
220
- if number? target
221
- exp = Sexp.new(:lit, target.value + first_arg.value)
222
- elsif call? target and target.method == :+ and number? target.first_arg
223
- target.first_arg = Sexp.new(:lit, target.first_arg.value + first_arg.value)
224
- exp = target
225
- end
226
- end
227
- when :-
228
- if number? target and number? first_arg
229
- exp = Sexp.new(:lit, target.value - first_arg.value)
230
- end
231
- when :*
232
- if number? target and number? first_arg
233
- exp = Sexp.new(:lit, target.value * first_arg.value)
234
- end
235
- when :/
236
- if number? target and number? first_arg
237
- unless first_arg.value == 0 and not target.value.is_a? Float
238
- exp = Sexp.new(:lit, target.value / first_arg.value)
239
- end
211
+ exp = math_op(:+, target, first_arg, exp)
240
212
  end
213
+ when :-, :*, :/
214
+ exp = math_op(method, target, first_arg, exp)
241
215
  when :[]
242
216
  if array? target
243
- temp_exp = process_array_access target, exp.args
244
- exp = temp_exp if temp_exp
217
+ exp = process_array_access(target, exp.args, exp)
245
218
  elsif hash? target
246
- temp_exp = process_hash_access target, first_arg
247
- exp = temp_exp if temp_exp
219
+ exp = process_hash_access(target, first_arg, exp)
248
220
  end
249
221
  when :merge!, :update
250
222
  if hash? target and hash? first_arg
@@ -287,8 +259,8 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
287
259
  exp = target[1]
288
260
  end
289
261
  when :freeze
290
- if string? target
291
- exp = process exp.target
262
+ unless target.nil?
263
+ exp = target
292
264
  end
293
265
  when :join
294
266
  if array? target and target.length > 2 and (string? first_arg or first_arg.nil?)
@@ -364,28 +336,37 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
364
336
  @exp_context.push exp
365
337
  exp[1] = process exp.block_call
366
338
  if array_detect_all_literals? exp[1]
367
- return exp.block_call.target[1]
339
+ return safe_literal(exp.line)
368
340
  end
369
341
 
370
342
  @exp_context.pop
371
343
 
372
344
  env.scope do
373
- exp.block_args.each do |e|
374
- #Force block arg(s) to be local
375
- if node_type? e, :lasgn
376
- env.current[Sexp.new(:lvar, e.lhs)] = Sexp.new(:lvar, e.lhs)
377
- elsif node_type? e, :kwarg
378
- env.current[Sexp.new(:lvar, e[1])] = e[2]
379
- elsif node_type? e, :masgn, :shadow
380
- e[1..-1].each do |var|
381
- local = Sexp.new(:lvar, var)
345
+ call = exp.block_call
346
+ block_args = exp.block_args
347
+
348
+ if call? call and [:each, :map].include? call.method and all_literals? call.target and block_args.length == 2 and block_args.last.is_a? Symbol
349
+ # Iterating over an array of all literal values
350
+ local = Sexp.new(:lvar, block_args.last)
351
+ env.current[local] = safe_literal(exp.line)
352
+ else
353
+ block_args.each do |e|
354
+ #Force block arg(s) to be local
355
+ if node_type? e, :lasgn
356
+ env.current[Sexp.new(:lvar, e.lhs)] = Sexp.new(:lvar, e.lhs)
357
+ elsif node_type? e, :kwarg
358
+ env.current[Sexp.new(:lvar, e[1])] = e[2]
359
+ elsif node_type? e, :masgn, :shadow
360
+ e[1..-1].each do |var|
361
+ local = Sexp.new(:lvar, var)
362
+ env.current[local] = local
363
+ end
364
+ elsif e.is_a? Symbol
365
+ local = Sexp.new(:lvar, e)
382
366
  env.current[local] = local
367
+ else
368
+ raise "Unexpected value in block args: #{e.inspect}"
383
369
  end
384
- elsif e.is_a? Symbol
385
- local = Sexp.new(:lvar, e)
386
- env.current[local] = local
387
- else
388
- raise "Unexpected value in block args: #{e.inspect}"
389
370
  end
390
371
  end
391
372
 
@@ -715,18 +696,14 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
715
696
  def array_include_all_literals? exp
716
697
  call? exp and
717
698
  exp.method == :include? and
718
- node_type? exp.target, :array and
719
- exp.target.length > 1 and
720
- exp.target.all? { |e| e.is_a? Symbol or node_type? e, :lit, :str }
699
+ all_literals? exp.target
721
700
  end
722
701
 
723
702
  def array_detect_all_literals? exp
724
703
  call? exp and
725
704
  [:detect, :find].include? exp.method and
726
- node_type? exp.target, :array and
727
- exp.target.length > 1 and
728
705
  exp.first_arg.nil? and
729
- exp.target.all? { |e| e.is_a? Symbol or node_type? e, :lit, :str }
706
+ all_literals? exp.target
730
707
  end
731
708
 
732
709
  #Sets @inside_if = true
@@ -767,12 +744,12 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
767
744
  # set x to "a" inside the true branch
768
745
  var = condition.first_arg
769
746
  previous_value = env.current[var]
770
- env.current[var] = condition.target[1]
747
+ env.current[var] = safe_literal(var.line)
771
748
  exp[branch_index] = process_if_branch branch
772
749
  env.current[var] = previous_value
773
750
  elsif i == 1 and array_include_all_literals? condition and early_return? branch
774
751
  var = condition.first_arg
775
- env.current[var] = condition.target[1]
752
+ env.current[var] = safe_literal(var.line)
776
753
  exp[branch_index] = process_if_branch branch
777
754
  else
778
755
  exp[branch_index] = process_if_branch branch
@@ -911,45 +888,6 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
911
888
  exp.or_depth >= @or_depth_limit
912
889
  end
913
890
 
914
- #Process single integer access to an array.
915
- #
916
- #Returns the value inside the array, if possible.
917
- def process_array_access target, args
918
- if args.length == 1 and integer? args.first
919
- index = args.first.value
920
-
921
- #Have to do this because first element is :array and we have to skip it
922
- target[1..-1][index]
923
- else
924
- nil
925
- end
926
- end
927
-
928
- #Process hash access by returning the value associated
929
- #with the given argument.
930
- def process_hash_access target, index
931
- hash_access(target, index)
932
- end
933
-
934
- #Join two array literals into one.
935
- def join_arrays array1, array2
936
- result = Sexp.new(:array)
937
- result.concat array1[1..-1]
938
- result.concat array2[1..-1]
939
- end
940
-
941
- #Join two string literals into one.
942
- def join_strings string1, string2
943
- result = Sexp.new(:str)
944
- result.value = string1.value + string2.value
945
-
946
- if result.value.length > 50
947
- string1
948
- else
949
- result
950
- end
951
- end
952
-
953
891
  # Change x.send(:y, 1) to x.y(1)
954
892
  def collapse_send_call exp, first_arg
955
893
  # Handle try(&:id)
@@ -179,8 +179,11 @@ class Brakeman::ControllerAliasProcessor < Brakeman::AliasProcessor
179
179
  # method as the line number
180
180
  if line.nil? and controller = @tracker.controllers[@current_class]
181
181
  if meth = controller.get_method(@current_method)
182
- line = meth[:src] && meth[:src].last && meth[:src].last.line
183
- line += 1
182
+ if line = meth[:src] && meth[:src].last && meth[:src].last.line
183
+ line += 1
184
+ else
185
+ line = 1
186
+ end
184
187
  end
185
188
  end
186
189
 
@@ -0,0 +1,90 @@
1
+ module Brakeman
2
+ module CallConversionHelper
3
+ def all_literals? exp, expected_type = :array
4
+ node_type? exp, expected_type and
5
+ exp.length > 1 and
6
+ exp.all? { |e| e.is_a? Symbol or node_type? e, :lit, :str }
7
+ end
8
+
9
+ # Join two array literals into one.
10
+ def join_arrays lhs, rhs, original_exp = nil
11
+ if array? lhs and array? rhs
12
+ result = Sexp.new(:array).line(lhs.line)
13
+ result.concat lhs[1..-1]
14
+ result.concat rhs[1..-1]
15
+ result
16
+ else
17
+ original_exp
18
+ end
19
+ end
20
+
21
+ # Join two string literals into one.
22
+ def join_strings lhs, rhs, original_exp = nil
23
+ if string? lhs and string? rhs
24
+ result = Sexp.new(:str).line(lhs.line)
25
+ result.value = lhs.value + rhs.value
26
+
27
+ if result.value.length > 50
28
+ # Avoid gigantic strings
29
+ lhs
30
+ else
31
+ result
32
+ end
33
+ elsif call? lhs and lhs.method == :+ and string? lhs.first_arg and string? rhs
34
+ joined = join_strings lhs.first_arg, rhs
35
+ lhs.first_arg = joined
36
+ lhs
37
+ elsif safe_literal? lhs or safe_literal? rhs
38
+ safe_literal(lhs.line)
39
+ else
40
+ original_exp
41
+ end
42
+ end
43
+
44
+ def math_op op, lhs, rhs, original_exp = nil
45
+ if number? lhs and number? rhs
46
+ if op == :/ and rhs.value == 0 and not lhs.value.is_a? Float
47
+ # Avoid division by zero
48
+ return original_exp
49
+ else
50
+ value = lhs.value.send(op, rhs.value)
51
+ Sexp.new(:lit, value).line(lhs.line)
52
+ end
53
+ elsif call? lhs and lhs.method == :+ and number? lhs.first_arg and number? rhs
54
+ # (x + 1) + 2 -> (x + 3)
55
+ lhs.first_arg = Sexp.new(:lit, lhs.first_arg.value + rhs.value).line(lhs.first_arg.line)
56
+ lhs
57
+ elsif safe_literal? lhs or safe_literal? rhs
58
+ safe_literal(lhs.line)
59
+ else
60
+ original_exp
61
+ end
62
+ end
63
+
64
+ # Process single integer access to an array.
65
+ #
66
+ # Returns the value inside the array, if possible.
67
+ def process_array_access array, args, original_exp = nil
68
+ if args.length == 1 and integer? args.first
69
+ index = args.first.value
70
+
71
+ #Have to do this because first element is :array and we have to skip it
72
+ array[1..-1][index] or original_exp
73
+ else
74
+ original_exp
75
+ end
76
+ end
77
+
78
+ # Process hash access by returning the value associated
79
+ # with the given argument.
80
+ def process_hash_access hash, index, original_exp = nil
81
+ if value = hash_access(hash, index)
82
+ value # deep_clone?
83
+ elsif all_literals? hash, :hash
84
+ safe_literal(hash.line)
85
+ else
86
+ original_exp
87
+ end
88
+ end
89
+ end
90
+ end
@@ -64,7 +64,7 @@ class Brakeman::LibraryProcessor < Brakeman::BaseProcessor
64
64
  res = process_default exp
65
65
 
66
66
  if node_type? res, :iter and call? exp.block_call # sometimes this changes after processing
67
- if exp.block_call.method == :included
67
+ if exp.block_call.method == :included and (@current_module or @current_class)
68
68
  (@current_module || @current_class).options[:included] = res.block
69
69
  end
70
70
  end
@@ -26,6 +26,8 @@ module Brakeman::Util
26
26
 
27
27
  ALL_COOKIES = Set[COOKIES, REQUEST_COOKIES]
28
28
 
29
+ SAFE_LITERAL = s(:lit, :BRAKEMAN_SAFE_LITERAL)
30
+
29
31
  #Convert a string from "something_like_this" to "SomethingLikeThis"
30
32
  #
31
33
  #Taken from ActiveSupport.
@@ -307,6 +309,22 @@ module Brakeman::Util
307
309
  call
308
310
  end
309
311
 
312
+ def safe_literal line = nil
313
+ s(:lit, :BRAKEMAN_SAFE_LITERAL).line(line || 0)
314
+ end
315
+
316
+ def safe_literal? exp
317
+ exp == SAFE_LITERAL
318
+ end
319
+
320
+ def safe_literal_target? exp
321
+ if call? exp
322
+ safe_literal_target? exp.target
323
+ else
324
+ safe_literal? exp
325
+ end
326
+ end
327
+
310
328
  def rails_version
311
329
  @tracker.config.rails_version
312
330
  end
@@ -1,3 +1,3 @@
1
1
  module Brakeman
2
- Version = "4.3.0"
2
+ Version = "4.3.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brakeman
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.3.0
4
+ version: 4.3.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: 2018-05-11 00:00:00.000000000 Z
12
+ date: 2018-06-07 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Brakeman detects security vulnerabilities in Ruby on Rails applications
15
15
  via static analysis.
@@ -1220,18 +1220,18 @@ files:
1220
1220
  - bundle/ruby/2.5.0/gems/tilt-2.0.8/test/tilt_wikiclothtemplate_test.rb
1221
1221
  - bundle/ruby/2.5.0/gems/tilt-2.0.8/test/tilt_yajltemplate_test.rb
1222
1222
  - bundle/ruby/2.5.0/gems/tilt-2.0.8/tilt.gemspec
1223
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/CHANGELOG.md
1224
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/MIT-LICENSE.txt
1225
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/README.md
1226
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/Rakefile
1227
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/data/display_width.marshal.gz
1228
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/lib/unicode/display_width.rb
1229
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/lib/unicode/display_width/constants.rb
1230
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/lib/unicode/display_width/index.rb
1231
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/lib/unicode/display_width/no_string_ext.rb
1232
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/lib/unicode/display_width/string_ext.rb
1233
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/spec/display_width_spec.rb
1234
- - bundle/ruby/2.5.0/gems/unicode-display_width-1.3.2/unicode-display_width.gemspec
1223
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.4.0/CHANGELOG.md
1224
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.4.0/MIT-LICENSE.txt
1225
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.4.0/README.md
1226
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.4.0/Rakefile
1227
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.4.0/data/display_width.marshal.gz
1228
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.4.0/lib/unicode/display_width.rb
1229
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.4.0/lib/unicode/display_width/constants.rb
1230
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.4.0/lib/unicode/display_width/index.rb
1231
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.4.0/lib/unicode/display_width/no_string_ext.rb
1232
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.4.0/lib/unicode/display_width/string_ext.rb
1233
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.4.0/spec/display_width_spec.rb
1234
+ - bundle/ruby/2.5.0/gems/unicode-display_width-1.4.0/unicode-display_width.gemspec
1235
1235
  - lib/brakeman.rb
1236
1236
  - lib/brakeman/app_tree.rb
1237
1237
  - lib/brakeman/call_index.rb
@@ -1327,6 +1327,7 @@ files:
1327
1327
  - lib/brakeman/processors/gem_processor.rb
1328
1328
  - lib/brakeman/processors/haml_template_processor.rb
1329
1329
  - lib/brakeman/processors/lib/basic_processor.rb
1330
+ - lib/brakeman/processors/lib/call_conversion_helper.rb
1330
1331
  - lib/brakeman/processors/lib/find_all_calls.rb
1331
1332
  - lib/brakeman/processors/lib/find_call.rb
1332
1333
  - lib/brakeman/processors/lib/find_return_value.rb
@@ -1,8 +0,0 @@
1
- require 'rubygems/util'
2
- require_relative 'constants'
3
-
4
- module Unicode
5
- module DisplayWidth
6
- INDEX = Marshal.load(Gem::Util.gunzip(File.binread(INDEX_FILENAME)))
7
- end
8
- end