brakeman 5.1.2 → 5.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +21 -0
  3. data/bundle/load.rb +2 -2
  4. data/bundle/ruby/2.7.0/gems/{parallel-1.21.0 → parallel-1.22.1}/MIT-LICENSE.txt +0 -0
  5. data/bundle/ruby/2.7.0/gems/{parallel-1.21.0 → parallel-1.22.1}/lib/parallel/processor_count.rb +2 -3
  6. data/bundle/ruby/2.7.0/gems/parallel-1.22.1/lib/parallel/version.rb +4 -0
  7. data/bundle/ruby/2.7.0/gems/{parallel-1.21.0 → parallel-1.22.1}/lib/parallel.rb +84 -4
  8. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/History.rdoc +40 -0
  9. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/Manifest.txt +2 -0
  10. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/README.rdoc +8 -6
  11. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/compare/normalize.rb +0 -0
  12. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/debugging.md +0 -0
  13. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/gauntlet.md +19 -18
  14. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/lib/rp_extensions.rb +0 -0
  15. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/lib/rp_stringscanner.rb +0 -0
  16. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby20_parser.rb +10973 -0
  17. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/lib/ruby20_parser.y +23 -30
  18. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby21_parser.rb +10980 -0
  19. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/lib/ruby21_parser.y +23 -30
  20. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby22_parser.rb +11123 -0
  21. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/lib/ruby22_parser.y +23 -30
  22. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby23_parser.rb +11132 -0
  23. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/lib/ruby23_parser.y +23 -30
  24. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby24_parser.rb +11231 -0
  25. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/lib/ruby24_parser.y +23 -30
  26. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby25_parser.rb +11231 -0
  27. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/lib/ruby25_parser.y +23 -30
  28. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby26_parser.rb +11253 -0
  29. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/lib/ruby26_parser.y +23 -30
  30. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby27_parser.rb +12980 -0
  31. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/lib/ruby27_parser.y +28 -44
  32. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby30_parser.rb +13242 -0
  33. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/lib/ruby30_parser.y +77 -93
  34. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby31_parser.rb +13622 -0
  35. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0/lib/ruby3_parser.yy → ruby_parser-3.19.1/lib/ruby31_parser.y} +121 -107
  36. data/bundle/ruby/2.7.0/gems/ruby_parser-3.19.1/lib/ruby3_parser.yy +3536 -0
  37. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/lib/ruby_lexer.rb +0 -0
  38. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/lib/ruby_lexer.rex +0 -0
  39. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/lib/ruby_lexer.rex.rb +0 -0
  40. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/lib/ruby_lexer_strings.rb +0 -0
  41. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/lib/ruby_parser.rb +2 -0
  42. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/lib/ruby_parser.yy +28 -44
  43. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/lib/ruby_parser_extras.rb +55 -2
  44. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/tools/munge.rb +0 -0
  45. data/bundle/ruby/2.7.0/gems/{ruby_parser-3.18.0 → ruby_parser-3.19.1}/tools/ripper.rb +0 -0
  46. data/lib/brakeman/checks/base_check.rb +10 -0
  47. data/lib/brakeman/checks/check_eol_rails.rb +23 -0
  48. data/lib/brakeman/checks/check_eol_ruby.rb +26 -0
  49. data/lib/brakeman/checks/check_sql.rb +6 -4
  50. data/lib/brakeman/checks/check_symbol_dos.rb +1 -1
  51. data/lib/brakeman/checks/check_unsafe_reflection.rb +7 -2
  52. data/lib/brakeman/checks/eol_check.rb +47 -0
  53. data/lib/brakeman/options.rb +8 -0
  54. data/lib/brakeman/processors/alias_processor.rb +17 -1
  55. data/lib/brakeman/processors/gem_processor.rb +3 -0
  56. data/lib/brakeman/processors/lib/rails3_route_processor.rb +2 -0
  57. data/lib/brakeman/scanner.rb +3 -1
  58. data/lib/brakeman/tracker/config.rb +8 -1
  59. data/lib/brakeman/version.rb +1 -1
  60. data/lib/brakeman/warning_codes.rb +4 -0
  61. metadata +48 -43
  62. data/bundle/ruby/2.7.0/gems/parallel-1.21.0/lib/parallel/version.rb +0 -4
  63. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby20_parser.rb +0 -7122
  64. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby21_parser.rb +0 -7176
  65. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby22_parser.rb +0 -7222
  66. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby23_parser.rb +0 -7231
  67. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby24_parser.rb +0 -7262
  68. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby25_parser.rb +0 -7262
  69. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby26_parser.rb +0 -7281
  70. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby27_parser.rb +0 -8511
  71. data/bundle/ruby/2.7.0/gems/ruby_parser-3.18.0/lib/ruby30_parser.rb +0 -8741
@@ -80,10 +80,12 @@ require "ruby25_parser"
80
80
  require "ruby26_parser"
81
81
  require "ruby27_parser"
82
82
  require "ruby30_parser"
83
+ require "ruby31_parser"
83
84
 
84
85
  class RubyParser # HACK
85
86
  VERSIONS.clear # also a HACK caused by racc namespace issues
86
87
 
88
+ class V31 < ::Ruby31Parser; end
87
89
  class V30 < ::Ruby30Parser; end
88
90
  class V27 < ::Ruby27Parser; end
89
91
  class V26 < ::Ruby26Parser; end
@@ -767,8 +767,7 @@ rule
767
767
 
768
768
  cpath: tCOLON3 cname
769
769
  {
770
- _, (name, line) = val
771
- result = s(:colon3, name.to_sym).line line
770
+ result = wrap :colon3, val[1]
772
771
  }
773
772
  | cname
774
773
  {
@@ -793,9 +792,7 @@ rule
793
792
 
794
793
  fitem: fname
795
794
  {
796
- (id, line), = val
797
-
798
- result = s(:lit, id.to_sym).line line
795
+ result = wrap :lit, val[0]
799
796
  }
800
797
  | symbol
801
798
 
@@ -864,9 +861,9 @@ rule
864
861
  }
865
862
  | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
866
863
  {
867
- _, (lhs, line), op, rhs = val
864
+ _, lhs, op, rhs = val
868
865
 
869
- lhs = s(:colon3, lhs.to_sym).line line
866
+ lhs = wrap :colon3, lhs
870
867
  result = new_const_op_asgn [lhs, op, rhs]
871
868
  }
872
869
  | backref tOP_ASGN arg_rhs
@@ -1336,9 +1333,7 @@ rule
1336
1333
  }
1337
1334
  | tCOLON3 tCONSTANT
1338
1335
  {
1339
- _, (id, line) = val
1340
-
1341
- result = s(:colon3, id.to_sym).line line
1336
+ result = wrap :colon3, val[1]
1342
1337
  }
1343
1338
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1344
1339
  {
@@ -1362,15 +1357,21 @@ rule
1362
1357
  }
1363
1358
  | kYIELD tLPAREN2 call_args rparen
1364
1359
  {
1365
- result = new_yield val[2]
1360
+ (_, line), _, args, _ = val
1361
+
1362
+ result = new_yield(args).line line
1366
1363
  }
1367
1364
  | kYIELD tLPAREN2 rparen
1368
1365
  {
1369
- result = new_yield
1366
+ (_, line), _, _ = val
1367
+
1368
+ result = new_yield.line line
1370
1369
  }
1371
1370
  | kYIELD
1372
1371
  {
1373
- result = new_yield
1372
+ (_, line), = val
1373
+
1374
+ result = new_yield.line line
1374
1375
  }
1375
1376
  | kDEFINED opt_nl tLPAREN2 expr rparen
1376
1377
  {
@@ -1840,8 +1841,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1840
1841
 
1841
1842
  bvar: tIDENTIFIER
1842
1843
  {
1843
- (id, line), = val
1844
- result = s(:shadow, id.to_sym).line line
1844
+ result = wrap :shadow, val[0]
1845
1845
  }
1846
1846
  | f_bad_arg
1847
1847
 
@@ -2452,9 +2452,7 @@ opt_block_args_tail: tCOMMA block_args_tail
2452
2452
 
2453
2453
  p_kw_label: tLABEL
2454
2454
  {
2455
- (id, line), = val
2456
-
2457
- result = s(:lit, id.to_sym).line line
2455
+ result = wrap :lit, val[0]
2458
2456
  }
2459
2457
 
2460
2458
  p_kwrest: kwrest_mark tIDENTIFIER
@@ -2546,26 +2544,20 @@ opt_block_args_tail: tCOMMA block_args_tail
2546
2544
 
2547
2545
  p_variable: tIDENTIFIER
2548
2546
  {
2549
- (id, line), = val
2550
-
2551
2547
  # TODO: error_duplicate_pattern_variable(p, $1, &@1);
2552
2548
  # TODO: assignable(p, $1, 0, &@$);
2553
- result = s(:lvar, id.to_sym).line line
2549
+ result = wrap :lvar, val[0]
2554
2550
  }
2555
2551
 
2556
2552
  p_var_ref: tCARET tIDENTIFIER
2557
2553
  {
2558
- _, (id, line) = val
2559
-
2560
2554
  # TODO: check id against env for lvar or dvar
2561
-
2562
- result = s(:lvar, id.to_sym).line line
2555
+ result = wrap :lvar, val[1]
2563
2556
  }
2564
2557
 
2565
2558
  p_const: tCOLON3 cname
2566
2559
  {
2567
- _, (id, line) = val
2568
- result = s(:colon3, id.to_sym).line line
2560
+ result = wrap :colon3, val[1]
2569
2561
  }
2570
2562
  | p_const tCOLON2 cname
2571
2563
  {
@@ -2577,8 +2569,7 @@ opt_block_args_tail: tCOMMA block_args_tail
2577
2569
  | tCONSTANT
2578
2570
  {
2579
2571
  # TODO $$ = gettable(p, $1, &@$);
2580
- (id, line), = val
2581
- result = s(:const, id.to_sym).line line
2572
+ result = wrap :const, val[0]
2582
2573
  }
2583
2574
  ######################################################################
2584
2575
  #endif
@@ -2865,18 +2856,15 @@ regexp_contents: none
2865
2856
 
2866
2857
  string_dvar: tGVAR
2867
2858
  {
2868
- (id, line), = val
2869
- result = s(:gvar, id.to_sym).line line
2859
+ result = wrap :gvar, val[0]
2870
2860
  }
2871
2861
  | tIVAR
2872
2862
  {
2873
- (id, line), = val
2874
- result = s(:ivar, id.to_sym).line line
2863
+ result = wrap :ivar, val[0]
2875
2864
  }
2876
2865
  | tCVAR
2877
2866
  {
2878
- (id, line), = val
2879
- result = s(:cvar, id.to_sym).line line
2867
+ result = wrap :cvar, val[0]
2880
2868
  }
2881
2869
  | backref
2882
2870
 
@@ -2885,17 +2873,13 @@ regexp_contents: none
2885
2873
 
2886
2874
  ssym: tSYMBEG sym
2887
2875
  {
2888
- _, (id, line) = val
2889
-
2890
2876
  lexer.lex_state = EXPR_END
2891
- result = s(:lit, id.to_sym).line line
2877
+ result = wrap :lit, val[1]
2892
2878
  }
2893
2879
  | tSYMBOL
2894
2880
  {
2895
- (id, line), = val
2896
-
2897
2881
  lexer.lex_state = EXPR_END
2898
- result = s(:lit, id.to_sym).line line
2882
+ result = wrap :lit, val[0]
2899
2883
  }
2900
2884
 
2901
2885
  sym: fname | tIVAR | tGVAR | tCVAR
@@ -3416,10 +3400,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
3416
3400
  }
3417
3401
  | tLABEL arg_value
3418
3402
  {
3419
- (label, line), arg = val
3403
+ label, arg = val
3420
3404
 
3421
- lit = s(:lit, label.to_sym).line line
3422
- result = s(:array, lit, arg).line line
3405
+ lit = wrap :lit, label
3406
+ result = s(:array, lit, arg).line lit.line
3423
3407
  }
3424
3408
  #if V >= 22
3425
3409
  | tSTRING_BEG string_contents tLABEL_END arg_value
@@ -30,7 +30,7 @@ class Sexp
30
30
  end
31
31
 
32
32
  module RubyParserStuff
33
- VERSION = "3.18.0"
33
+ VERSION = "3.19.1"
34
34
 
35
35
  attr_accessor :lexer, :in_def, :in_single, :file
36
36
  attr_accessor :in_kwarg
@@ -218,11 +218,15 @@ module RubyParserStuff
218
218
  self.args args
219
219
  end
220
220
 
221
+ def attrset_id? id
222
+ id =~ /^\[\]=$|^\w+=$/
223
+ end
224
+
221
225
  def endless_method_name defn_or_defs
222
226
  name = defn_or_defs[1]
223
227
  name = defn_or_defs[2] unless Symbol === name
224
228
 
225
- if name.end_with? "=" then
229
+ if attrset_id? name then
226
230
  yyerror "setter method cannot be defined in an endless method definition"
227
231
  end
228
232
 
@@ -978,6 +982,49 @@ module RubyParserStuff
978
982
  [result, in_def]
979
983
  end
980
984
 
985
+ def new_endless_defn val
986
+ (name, line, in_def), args, _, body, _, resbody = val
987
+
988
+ result =
989
+ if resbody then
990
+ s(:defn, name, args,
991
+ new_rescue(body,
992
+ new_resbody(s(:array).line(line),
993
+ resbody))).line line
994
+ else
995
+ s(:defn, name, args, body).line line
996
+ end
997
+
998
+ local_pop in_def
999
+ endless_method_name result
1000
+
1001
+ result.comments = self.comments.pop
1002
+
1003
+ result
1004
+ end
1005
+
1006
+ def new_endless_defs val
1007
+ (recv, (name, line, in_def)), args, _, body, _, resbody = val
1008
+
1009
+ result =
1010
+ if resbody then
1011
+ s(:defs, recv, name, args,
1012
+ new_rescue(body,
1013
+ new_resbody(s(:array).line(line),
1014
+ resbody))).line line
1015
+ else
1016
+ s(:defs, recv, name, args, body).line(line)
1017
+ end
1018
+
1019
+ self.in_single -= 1
1020
+ local_pop in_def
1021
+ endless_method_name result
1022
+
1023
+ result.comments = self.comments.pop
1024
+
1025
+ result
1026
+ end
1027
+
981
1028
  def new_defs val
982
1029
  _, recv, (name, line), in_def, args, body, _ = val
983
1030
 
@@ -1613,6 +1660,12 @@ module RubyParserStuff
1613
1660
 
1614
1661
  alias remove_whitespace_width whitespace_width
1615
1662
 
1663
+ def wrap type, node
1664
+ value, line = node
1665
+ value = value.to_sym if value.respond_to? :to_sym
1666
+ s(type, value).line line
1667
+ end
1668
+
1616
1669
  class Keyword
1617
1670
  include RubyLexer::State::Values
1618
1671
 
@@ -513,4 +513,14 @@ class Brakeman::BaseCheck < Brakeman::SexpProcessor
513
513
  string_building? exp.target or
514
514
  string_building? exp.first_arg
515
515
  end
516
+
517
+ I18N_CLASS = s(:const, :I18n)
518
+
519
+ def locale_call? exp
520
+ return unless call? exp
521
+
522
+ (exp.target == I18N_CLASS and
523
+ exp.method == :locale) or
524
+ locale_call? exp.target
525
+ end
516
526
  end
@@ -0,0 +1,23 @@
1
+ require_relative 'eol_check'
2
+
3
+ class Brakeman::CheckEOLRails < Brakeman::EOLCheck
4
+ Brakeman::Checks.add self
5
+
6
+ @description = "Checks for unsupported versions of Rails"
7
+
8
+ def run_check
9
+ return unless tracker.config.rails_version
10
+
11
+ check_eol_version :rails, RAILS_EOL_DATES
12
+ end
13
+
14
+ RAILS_EOL_DATES = {
15
+ ['2.0.0', '2.3.99'] => Date.new(2013, 6, 25),
16
+ ['3.0.0', '3.2.99'] => Date.new(2016, 6, 30),
17
+ ['4.0.0', '4.2.99'] => Date.new(2017, 4, 27),
18
+ ['5.0.0', '5.0.99'] => Date.new(2018, 5, 9),
19
+ ['5.1.0', '5.1.99'] => Date.new(2019, 8, 25),
20
+ ['5.2.0', '5.2.99'] => Date.new(2022, 6, 1),
21
+ ['6.0.0', '6.0.99'] => Date.new(2023, 6, 1),
22
+ }
23
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'eol_check'
2
+
3
+ class Brakeman::CheckEOLRuby < Brakeman::EOLCheck
4
+ Brakeman::Checks.add self
5
+
6
+ @description = "Checks for unsupported versions of Ruby"
7
+
8
+ def run_check
9
+ return unless tracker.config.ruby_version
10
+
11
+ check_eol_version :ruby, RUBY_EOL_DATES
12
+ end
13
+
14
+ RUBY_EOL_DATES = {
15
+ ['0.0.0', '1.9.3'] => Date.new(2015, 2, 23),
16
+ ['2.0.0', '2.0.99'] => Date.new(2016, 2, 24),
17
+ ['2.1.0', '2.1.99'] => Date.new(2017, 3, 31),
18
+ ['2.2.0', '2.2.99'] => Date.new(2018, 3, 31),
19
+ ['2.3.0', '2.3.99'] => Date.new(2019, 3, 31),
20
+ ['2.4.0', '2.4.99'] => Date.new(2020, 3, 31),
21
+ ['2.5.0', '2.5.99'] => Date.new(2021, 3, 31),
22
+ ['2.6.0', '2.6.99'] => Date.new(2022, 3, 31),
23
+ ['2.7.0', '2.7.99'] => Date.new(2023, 3, 31),
24
+ ['3.0.0', '2.8.99'] => Date.new(2024, 3, 31),
25
+ }
26
+ end
@@ -405,7 +405,8 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
405
405
  nil
406
406
  end
407
407
 
408
- TO_STRING_METHODS = [:chomp, :to_s, :squish, :strip, :strip_heredoc]
408
+ TO_STRING_METHODS = [:chomp, :chop, :lstrip, :rstrip, :scrub, :squish, :strip,
409
+ :strip_heredoc, :to_s, :tr]
409
410
 
410
411
  #Returns value if interpolated value is not something safe
411
412
  def unsafe_string_interp? exp
@@ -584,7 +585,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
584
585
  end
585
586
 
586
587
  IGNORE_METHODS_IN_SQL = Set[:id, :merge_conditions, :table_name, :quoted_table_name,
587
- :quoted_primary_key, :to_i, :to_f, :sanitize_sql, :sanitize_sql_array, :sanitize_sql_like,
588
+ :quoted_primary_key, :to_i, :to_f, :sanitize_sql, :sanitize_sql_array,
588
589
  :sanitize_sql_for_assignment, :sanitize_sql_for_conditions, :sanitize_sql_hash,
589
590
  :sanitize_sql_hash_for_assignment, :sanitize_sql_hash_for_conditions,
590
591
  :to_sql, :sanitize, :primary_key, :table_name_prefix, :table_name_suffix,
@@ -628,7 +629,8 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
628
629
  arel? exp or
629
630
  exp.method.to_s.end_with? "_id" or
630
631
  number_target? exp or
631
- date_target? exp
632
+ date_target? exp or
633
+ locale_call? exp
632
634
  end
633
635
 
634
636
  QUOTE_METHODS = [:quote, :quote_column_name, :quoted_date, :quote_string, :quote_table_name]
@@ -743,6 +745,6 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
743
745
  date_target? exp.target
744
746
  else
745
747
  false
746
- end
748
+ end
747
749
  end
748
750
  end
@@ -9,7 +9,7 @@ class Brakeman::CheckSymbolDoS < Brakeman::BaseCheck
9
9
 
10
10
  def run_check
11
11
  return if rails_version and rails_version >= "5.0.0"
12
- return if tracker.config.ruby_version >= "2.2"
12
+ return if tracker.config.ruby_version and tracker.config.ruby_version >= "2.2"
13
13
 
14
14
  tracker.find_call(:methods => UNSAFE_METHODS, :nested => true).each do |result|
15
15
  check_unsafe_symbol_creation(result)
@@ -20,7 +20,7 @@ class Brakeman::CheckUnsafeReflection < Brakeman::BaseCheck
20
20
  def check_unsafe_reflection result
21
21
  return unless original? result
22
22
 
23
- call = result[:call]
23
+ call = result[:call]
24
24
  method = call.method
25
25
 
26
26
  case method
@@ -37,7 +37,12 @@ class Brakeman::CheckUnsafeReflection < Brakeman::BaseCheck
37
37
  end
38
38
 
39
39
  if confidence
40
- message = msg("Unsafe reflection method ", msg_code(method), " called with ", msg_input(input))
40
+ case method
41
+ when :constantize, :safe_constantize
42
+ message = msg("Unsafe reflection method ", msg_code(method), " called on ", msg_input(input))
43
+ else
44
+ message = msg("Unsafe reflection method ", msg_code(method), " called with ", msg_input(input))
45
+ end
41
46
 
42
47
  warn :result => result,
43
48
  :warning_type => "Remote Code Execution",
@@ -0,0 +1,47 @@
1
+ require 'date'
2
+ require 'brakeman/checks/base_check'
3
+
4
+ # Not used directly - base check for EOLRails and EOLRuby
5
+ class Brakeman::EOLCheck < Brakeman::BaseCheck
6
+ def check_eol_version library, eol_dates
7
+ version = case library
8
+ when :rails
9
+ tracker.config.rails_version
10
+ when :ruby
11
+ tracker.config.ruby_version
12
+ else
13
+ raise 'Implement using tracker.config.gem_version'
14
+ end
15
+
16
+ eol_dates.each do |(start_version, end_version), eol_date|
17
+ if version_between? start_version, end_version, version
18
+ case
19
+ when Date.today >= eol_date
20
+ warn_about_unsupported_version library, eol_date, version
21
+ when (Date.today + 30) >= eol_date
22
+ warn_about_soon_unsupported_version library, eol_date, version, :medium
23
+ when (Date.today + 60) >= eol_date
24
+ warn_about_soon_unsupported_version library, eol_date, version, :low
25
+ end
26
+
27
+ break
28
+ end
29
+ end
30
+ end
31
+
32
+ def warn_about_soon_unsupported_version library, eol_date, version, confidence
33
+ warn warning_type: 'Unmaintained Dependency',
34
+ warning_code: :"pending_eol_#{library}",
35
+ message: msg("Support for ", msg_version(version, library.capitalize), " ends on #{eol_date}"),
36
+ confidence: confidence,
37
+ gem_info: gemfile_or_environment
38
+ end
39
+
40
+ def warn_about_unsupported_version library, eol_date, version
41
+ warn warning_type: 'Unmaintained Dependency',
42
+ warning_code: :"eol_#{library}",
43
+ message: msg("Support for ", msg_version(version, library.capitalize), " ended on #{eol_date}"),
44
+ confidence: :high,
45
+ gem_info: gemfile_or_environment
46
+ end
47
+ end
@@ -93,6 +93,14 @@ module Brakeman::Options
93
93
  options[:rails6] = true
94
94
  end
95
95
 
96
+ opts.on "-7", "--rails7", "Force Rails 7 mode" do
97
+ options[:rails3] = true
98
+ options[:rails4] = true
99
+ options[:rails5] = true
100
+ options[:rails6] = true
101
+ options[:rails7] = true
102
+ end
103
+
96
104
  opts.separator ""
97
105
  opts.separator "Scanning options:"
98
106
 
@@ -404,7 +404,7 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
404
404
  end
405
405
 
406
406
  def join_item item, join_value
407
- if item.is_a? String
407
+ if item.nil? || item.is_a?(String)
408
408
  "#{item}#{join_value}"
409
409
  elsif string? item or symbol? item or number? item
410
410
  s(:str, "#{item.value}#{join_value}").line(item.line)
@@ -864,6 +864,9 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
864
864
  elsif false? condition
865
865
  no_branch = true
866
866
  exps = [nil, exp.else_clause]
867
+ elsif equality_check? condition and condition.target == condition.first_arg
868
+ no_branch = true
869
+ exps = [exp.then_clause, nil]
867
870
  else
868
871
  no_branch = false
869
872
  exps = [exp.then_clause, exp.else_clause]
@@ -897,6 +900,14 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
897
900
  env.current[var] = safe_literal(var.line)
898
901
  exp[branch_index] = process_if_branch branch
899
902
  env.current[var] = previous_value
903
+ elsif i == 0 and equality_check? condition
904
+ # For conditions like a == b,
905
+ # set a to b inside the true branch
906
+ var = condition.target
907
+ previous_value = env.current[var]
908
+ env.current[var] = condition.first_arg
909
+ exp[branch_index] = process_if_branch branch
910
+ env.current[var] = previous_value
900
911
  elsif i == 1 and hash_or_array_include_all_literals? condition and early_return? branch
901
912
  var = condition.first_arg
902
913
  env.current[var] = safe_literal(var.line)
@@ -931,6 +942,11 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
931
942
  end
932
943
  end
933
944
 
945
+ def equality_check? exp
946
+ call? exp and
947
+ exp.method == :==
948
+ end
949
+
934
950
  def simple_when? exp
935
951
  node_type? exp[1], :array and
936
952
  not node_type? exp[1][1], :splat, :array and
@@ -6,6 +6,7 @@ class Brakeman::GemProcessor < Brakeman::BasicProcessor
6
6
  def initialize *args
7
7
  super
8
8
  @gem_name_version = /^\s*([-_+.A-Za-z0-9]+) \((\w(\.\w+)*)\)/
9
+ @ruby_version = /^\s+ruby (\d\.\d.\d+)/
9
10
  end
10
11
 
11
12
  def process_gems gem_files
@@ -95,6 +96,8 @@ class Brakeman::GemProcessor < Brakeman::BasicProcessor
95
96
  def set_gem_version_and_file line, file, line_num
96
97
  if line =~ @gem_name_version
97
98
  @tracker.config.add_gem $1, $2, file, line_num
99
+ elsif line =~ @ruby_version
100
+ @tracker.config.set_ruby_version $1
98
101
  end
99
102
  end
100
103
  end
@@ -78,6 +78,8 @@ class Brakeman::Rails3RoutesProcessor < Brakeman::BasicProcessor
78
78
 
79
79
  #TODO: Need test for this
80
80
  def process_root exp
81
+ return exp unless hash? exp.first_arg
82
+
81
83
  if value = hash_access(exp.first_arg, :to)
82
84
  if string? value
83
85
  add_route_from_string value
@@ -137,7 +137,9 @@ class Brakeman::Scanner
137
137
  end
138
138
 
139
139
  if @app_tree.exists? ".ruby-version"
140
- tracker.config.set_ruby_version @app_tree.file_path(".ruby-version").read
140
+ if version = @app_tree.file_path(".ruby-version").read[/(\d\.\d.\d+)/]
141
+ tracker.config.set_ruby_version version
142
+ end
141
143
  end
142
144
 
143
145
  tracker.config.load_rails_defaults
@@ -14,7 +14,7 @@ module Brakeman
14
14
  @settings = {}
15
15
  @escape_html = nil
16
16
  @erubis = nil
17
- @ruby_version = ""
17
+ @ruby_version = nil
18
18
  @rails_version = nil
19
19
  end
20
20
 
@@ -106,6 +106,13 @@ module Brakeman
106
106
  tracker.options[:rails5] = true
107
107
  tracker.options[:rails6] = true
108
108
  Brakeman.notify "[Notice] Detected Rails 6 application"
109
+ elsif @rails_version.start_with? "7"
110
+ tracker.options[:rails3] = true
111
+ tracker.options[:rails4] = true
112
+ tracker.options[:rails5] = true
113
+ tracker.options[:rails6] = true
114
+ tracker.options[:rails7] = true
115
+ Brakeman.notify "[Notice] Detected Rails 7 application"
109
116
  end
110
117
  end
111
118
  end
@@ -1,3 +1,3 @@
1
1
  module Brakeman
2
- Version = "5.1.2"
2
+ Version = "5.2.2"
3
3
  end
@@ -121,6 +121,10 @@ module Brakeman::WarningCodes
121
121
  :erb_template_injection => 117,
122
122
  :http_verb_confusion => 118,
123
123
  :unsafe_method_reflection => 119,
124
+ :eol_rails => 120,
125
+ :eol_ruby => 121,
126
+ :pending_eol_rails => 122,
127
+ :pending_eol_ruby => 123,
124
128
 
125
129
  :custom_check => 9090,
126
130
  }