brakeman-lib 4.4.0 → 4.5.0
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 +4 -4
- data/CHANGES.md +17 -0
- data/lib/brakeman/checks/base_check.rb +16 -0
- data/lib/brakeman/checks/check_content_tag.rb +12 -0
- data/lib/brakeman/checks/check_cross_site_scripting.rb +6 -6
- data/lib/brakeman/checks/check_evaluation.rb +0 -1
- data/lib/brakeman/checks/check_execute.rb +18 -0
- data/lib/brakeman/checks/check_send.rb +0 -1
- data/lib/brakeman/checks/check_session_manipulation.rb +0 -1
- data/lib/brakeman/checks/check_sql.rb +12 -3
- data/lib/brakeman/file_parser.rb +8 -4
- data/lib/brakeman/parsers/haml_embedded.rb +44 -0
- data/lib/brakeman/parsers/slim_embedded.rb +44 -0
- data/lib/brakeman/parsers/template_parser.rb +2 -4
- data/lib/brakeman/processors/alias_processor.rb +23 -1
- data/lib/brakeman/processors/lib/call_conversion_helper.rb +4 -0
- data/lib/brakeman/processors/slim_template_processor.rb +16 -0
- data/lib/brakeman/processors/template_alias_processor.rb +2 -2
- data/lib/brakeman/scanner.rb +11 -10
- data/lib/brakeman/tracker.rb +5 -1
- data/lib/brakeman/tracker/config.rb +32 -7
- data/lib/brakeman/util.rb +17 -0
- data/lib/brakeman/version.rb +1 -1
- metadata +35 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 142b7260d9ae378b1dd4126d00979b892c6931b601865e20a883a0e8444cd225
|
4
|
+
data.tar.gz: 53d73341cd37a589a8483c9bdf59be6f5b8c350c48466e02479609c66d4da264
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b555893cb7d94bddab5f9a3f824024050b098e08706fdb40e8a3f2ce9b7f3dc31bae1235bb998e71e09170eedcae508c3fae20900e58e57b0ce095e99ff5022
|
7
|
+
data.tar.gz: 78bb4ca1c4892027cec86157bf96dbf7ac8dcf84fde1a5585181304f72d575fd935a990cf8027985e5e756ce8cd4fe8bac40573911bd903434b886e1d1a3ca94
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
# 4.5.0
|
2
|
+
|
3
|
+
* Update `ruby_parser`, use `ruby_parser-legacy`
|
4
|
+
* More thoroughly handle `Shellwords` escaping
|
5
|
+
* Handle non-integer version number comparisons
|
6
|
+
* Use `FileParser` in `Scanner` to parse files
|
7
|
+
* Add original exception to `Tracker#errors` list
|
8
|
+
* Add support for CoffeeScript in Slim templates
|
9
|
+
* Improve support for embedded template "filters"
|
10
|
+
* Remove Sass dependency
|
11
|
+
* Set location information in `CheckContentTag`
|
12
|
+
* Stop swallowing exceptions in `AliasProcessor`
|
13
|
+
* Avoid joining strings with different encodings
|
14
|
+
* Handle `**` inside Hash literals
|
15
|
+
* Better handling of splat/kwsplat arguments
|
16
|
+
* Improve "user input" reported for SQL injection
|
17
|
+
|
1
18
|
# 4.4.0
|
2
19
|
|
3
20
|
* Set default encoding to UTF-8
|
@@ -348,6 +348,22 @@ class Brakeman::BaseCheck < Brakeman::SexpProcessor
|
|
348
348
|
when :or
|
349
349
|
has_immediate_user_input? exp.lhs or
|
350
350
|
has_immediate_user_input? exp.rhs
|
351
|
+
when :splat, :kwsplat
|
352
|
+
exp.each_sexp do |e|
|
353
|
+
match = has_immediate_user_input?(e)
|
354
|
+
return match if match
|
355
|
+
end
|
356
|
+
|
357
|
+
false
|
358
|
+
when :hash
|
359
|
+
if kwsplat? exp
|
360
|
+
exp[1].each_sexp do |e|
|
361
|
+
match = has_immediate_user_input?(e)
|
362
|
+
return match if match
|
363
|
+
end
|
364
|
+
|
365
|
+
false
|
366
|
+
end
|
351
367
|
else
|
352
368
|
false
|
353
369
|
end
|
@@ -45,6 +45,16 @@ class Brakeman::CheckContentTag < Brakeman::CheckCrossSiteScripting
|
|
45
45
|
def process_result result
|
46
46
|
return if duplicate? result
|
47
47
|
|
48
|
+
case result[:location][:type]
|
49
|
+
when :template
|
50
|
+
@current_template = result[:location][:template]
|
51
|
+
when :class
|
52
|
+
@current_class = result[:location][:class]
|
53
|
+
@current_method = result[:location][:method]
|
54
|
+
end
|
55
|
+
|
56
|
+
@current_file = result[:location][:file]
|
57
|
+
|
48
58
|
call = result[:call] = result[:call].dup
|
49
59
|
|
50
60
|
args = call.arglist
|
@@ -85,6 +95,8 @@ class Brakeman::CheckContentTag < Brakeman::CheckCrossSiteScripting
|
|
85
95
|
end
|
86
96
|
end
|
87
97
|
end
|
98
|
+
ensure
|
99
|
+
@current_template = @current_class = @current_method = @current_file = nil
|
88
100
|
end
|
89
101
|
|
90
102
|
def check_argument result, exp
|
@@ -57,12 +57,12 @@ class Brakeman::CheckCrossSiteScripting < Brakeman::BaseCheck
|
|
57
57
|
|
58
58
|
if exp.node_type == :output
|
59
59
|
out = exp.value
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
60
|
+
end
|
61
|
+
|
62
|
+
if raw_call? exp
|
63
|
+
out = exp.value.first_arg
|
64
|
+
elsif html_safe_call? exp
|
65
|
+
out = exp.value.target
|
66
66
|
end
|
67
67
|
|
68
68
|
return if call? out and ignore_call? out.target, out.method
|
@@ -90,6 +90,24 @@ class Brakeman::CheckExecute < Brakeman::BaseCheck
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
+
def include_user_input? exp
|
94
|
+
if node_type? exp, :arglist, :dstr, :evstr, :dxstr
|
95
|
+
exp.each_sexp do |e|
|
96
|
+
if res = include_user_input?(e)
|
97
|
+
return res
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
false
|
102
|
+
else
|
103
|
+
if shell_escape? exp
|
104
|
+
false
|
105
|
+
else
|
106
|
+
super exp
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
93
111
|
def dangerous_open_arg? exp
|
94
112
|
if string_interp? exp
|
95
113
|
# Check for input at start of string
|
@@ -27,7 +27,6 @@ class Brakeman::CheckSessionManipulation < Brakeman::BaseCheck
|
|
27
27
|
:warning_type => "Session Manipulation",
|
28
28
|
:warning_code => :session_key_manipulation,
|
29
29
|
:message => msg(msg_input(input), " used as key in session hash"),
|
30
|
-
:code => result[:call],
|
31
30
|
:user_input => input,
|
32
31
|
:confidence => confidence
|
33
32
|
end
|
@@ -14,7 +14,9 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
14
14
|
@description = "Check for SQL injection"
|
15
15
|
|
16
16
|
def run_check
|
17
|
-
|
17
|
+
# Avoid reporting `user_input` on silly values when generating warning.
|
18
|
+
# Note that we retroactively find `user_input` inside the "dangerous" value.
|
19
|
+
@safe_input_attributes.merge IGNORE_METHODS_IN_SQL
|
18
20
|
|
19
21
|
@sql_targets = [:average, :calculate, :count, :count_by_sql, :delete_all, :destroy_all,
|
20
22
|
:find_by_sql, :maximum, :minimum, :pluck, :sum, :update_all]
|
@@ -43,6 +45,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
43
45
|
Brakeman.debug "Finding possible SQL calls on models"
|
44
46
|
calls = tracker.find_call(:methods => @sql_targets, :nested => true)
|
45
47
|
|
48
|
+
narrow_targets = [:exists?, :select]
|
46
49
|
calls.concat tracker.find_call(:targets => active_record_models.keys, :methods => narrow_targets, :chained => true)
|
47
50
|
|
48
51
|
Brakeman.debug "Finding possible SQL calls with no target"
|
@@ -294,7 +297,7 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
294
297
|
# Model.where(params[:where])
|
295
298
|
arg
|
296
299
|
end
|
297
|
-
elsif hash? arg
|
300
|
+
elsif hash? arg and not kwsplat? arg
|
298
301
|
#This is generally going to be a hash of column names and values, which
|
299
302
|
#would escape the values. But the keys _could_ be user input.
|
300
303
|
check_hash_keys arg
|
@@ -452,7 +455,13 @@ class Brakeman::CheckSQL < Brakeman::BaseCheck
|
|
452
455
|
when :dstr
|
453
456
|
check_string_interp exp
|
454
457
|
when :hash
|
455
|
-
|
458
|
+
if kwsplat? exp and has_immediate_user_input? exp
|
459
|
+
exp
|
460
|
+
elsif not ignore_hash
|
461
|
+
check_hash_values exp
|
462
|
+
else
|
463
|
+
nil
|
464
|
+
end
|
456
465
|
when :if
|
457
466
|
unsafe_sql? exp.then_clause or unsafe_sql? exp.else_clause
|
458
467
|
when :call
|
data/lib/brakeman/file_parser.rb
CHANGED
@@ -31,13 +31,17 @@ module Brakeman
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
def parse_ruby input, path
|
34
|
+
def parse_ruby input, path, parser = RubyParser.new
|
35
35
|
begin
|
36
36
|
Brakeman.debug "Parsing #{path}"
|
37
|
-
|
37
|
+
parser.parse input, path, @timeout
|
38
38
|
rescue Racc::ParseError => e
|
39
|
-
|
40
|
-
|
39
|
+
if parser.class == RubyParser
|
40
|
+
return parse_ruby(input, path, RubyParser.latest)
|
41
|
+
else
|
42
|
+
@tracker.error e, "Could not parse #{path}"
|
43
|
+
nil
|
44
|
+
end
|
41
45
|
rescue Timeout::Error => e
|
42
46
|
@tracker.error Exception.new("Parsing #{path} took too long (> #{@timeout} seconds). Try increasing the limit with --parser-timeout"), caller
|
43
47
|
nil
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Brakeman
|
2
|
+
module FakeHamlFilter
|
3
|
+
# Copied from Haml - force delayed compilation
|
4
|
+
def compile(compiler, text)
|
5
|
+
filter = self
|
6
|
+
compiler.instance_eval do
|
7
|
+
text = unescape_interpolation(text).gsub(/(\\+)n/) do |s|
|
8
|
+
escapes = $1.size
|
9
|
+
next s if escapes % 2 == 0
|
10
|
+
("\\" * (escapes - 1)) + "\n"
|
11
|
+
end
|
12
|
+
# We need to add a newline at the beginning to get the
|
13
|
+
# filter lines to line up (since the Haml filter contains
|
14
|
+
# a line that doesn't show up in the source, namely the
|
15
|
+
# filter name). Then we need to escape the trailing
|
16
|
+
# newline so that the whole filter block doesn't take up
|
17
|
+
# too many.
|
18
|
+
text = "\n" + text.sub(/\n"\Z/, "\\n\"")
|
19
|
+
push_script <<RUBY.rstrip, :escape_html => false
|
20
|
+
find_and_preserve(#{filter.inspect}.render_with_options(#{text}, _hamlout.options))
|
21
|
+
RUBY
|
22
|
+
return
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Fake CoffeeScript filter for Haml
|
29
|
+
module Haml::Filters::Coffee
|
30
|
+
include Haml::Filters::Base
|
31
|
+
extend Brakeman::FakeHamlFilter
|
32
|
+
end
|
33
|
+
|
34
|
+
# Fake Markdown filter for Haml
|
35
|
+
module Haml::Filters::Markdown
|
36
|
+
include Haml::Filters::Base
|
37
|
+
extend Brakeman::FakeHamlFilter
|
38
|
+
end
|
39
|
+
|
40
|
+
# Fake Sass filter for Haml
|
41
|
+
module Haml::Filters::Sass
|
42
|
+
include Haml::Filters::Base
|
43
|
+
extend Brakeman::FakeHamlFilter
|
44
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# Fake filters for Slim
|
2
|
+
module Slim
|
3
|
+
class Embedded
|
4
|
+
class TiltEngine
|
5
|
+
def on_slim_embedded(engine, body, attrs)
|
6
|
+
# Override this method to avoid Slim trying to load sass/scss and failing
|
7
|
+
case engine
|
8
|
+
when :sass, :scss, :coffee
|
9
|
+
tilt_engine = nil # Doesn't really matter, ignored below
|
10
|
+
else
|
11
|
+
# Original Slim code
|
12
|
+
tilt_engine = Tilt[engine] || raise(Temple::FilterError, "Tilt engine #{engine} is not available.")
|
13
|
+
end
|
14
|
+
|
15
|
+
tilt_options = options[engine.to_sym] || {}
|
16
|
+
tilt_options[:default_encoding] ||= 'utf-8'
|
17
|
+
|
18
|
+
[:multi, tilt_render(tilt_engine, tilt_options, collect_text(body)), collect_newlines(body)]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class SassEngine
|
23
|
+
protected
|
24
|
+
|
25
|
+
def tilt_render(tilt_engine, tilt_options, text)
|
26
|
+
[:dynamic,
|
27
|
+
"BrakemanFilter.render(#{text.inspect}, #{self.class})"]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class CoffeeEngine < TiltEngine
|
32
|
+
protected
|
33
|
+
|
34
|
+
def tilt_render(tilt_engine, tilt_options, text)
|
35
|
+
[:dynamic,
|
36
|
+
"BrakemanFilter.render(#{text.inspect}, #{self.class})"]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Override the engine for CoffeeScript, because Slim doesn't have
|
41
|
+
# one, it just uses Tilt's
|
42
|
+
register :coffee, JavaScriptEngine, engine: CoffeeEngine
|
43
|
+
end
|
44
|
+
end
|
@@ -75,7 +75,7 @@ module Brakeman
|
|
75
75
|
|
76
76
|
def parse_haml path, text
|
77
77
|
Brakeman.load_brakeman_dependency 'haml'
|
78
|
-
|
78
|
+
require_relative 'haml_embedded'
|
79
79
|
|
80
80
|
Haml::Engine.new(text,
|
81
81
|
:filename => path,
|
@@ -83,13 +83,11 @@ module Brakeman
|
|
83
83
|
rescue Haml::Error => e
|
84
84
|
tracker.error e, ["While compiling HAML in #{path}"] << e.backtrace
|
85
85
|
nil
|
86
|
-
rescue Sass::SyntaxError => e
|
87
|
-
tracker.error e, "While processing #{path}"
|
88
|
-
nil
|
89
86
|
end
|
90
87
|
|
91
88
|
def parse_slim path, text
|
92
89
|
Brakeman.load_brakeman_dependency 'slim'
|
90
|
+
require_relative 'slim_embedded'
|
93
91
|
|
94
92
|
Slim::Template.new(path,
|
95
93
|
:disable_capture => true,
|
@@ -66,7 +66,11 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
rescue => err
|
69
|
-
|
69
|
+
if @tracker
|
70
|
+
@tracker.error err
|
71
|
+
else
|
72
|
+
raise err
|
73
|
+
end
|
70
74
|
end
|
71
75
|
|
72
76
|
result = replace(exp)
|
@@ -585,6 +589,24 @@ class Brakeman::AliasProcessor < Brakeman::SexpProcessor
|
|
585
589
|
exp
|
586
590
|
end
|
587
591
|
|
592
|
+
def process_hash exp
|
593
|
+
exp = process_default(exp)
|
594
|
+
|
595
|
+
# Handle { **kw }
|
596
|
+
if node_type? exp, :hash
|
597
|
+
if exp.any? { |e| node_type? e, :kwsplat and node_type? e.value, :hash }
|
598
|
+
kwsplats, rest = exp.partition { |e| node_type? e, :kwsplat and node_type? e.value, :hash }
|
599
|
+
exp = Sexp.new.concat(rest).line(exp)
|
600
|
+
|
601
|
+
kwsplats.each do |e|
|
602
|
+
exp = process_hash_merge! exp, e.value
|
603
|
+
end
|
604
|
+
end
|
605
|
+
end
|
606
|
+
|
607
|
+
exp
|
608
|
+
end
|
609
|
+
|
588
610
|
#Merge values into hash when processing
|
589
611
|
#
|
590
612
|
# h.merge! :something => "value"
|
@@ -40,6 +40,10 @@ module Brakeman
|
|
40
40
|
else
|
41
41
|
original_exp
|
42
42
|
end
|
43
|
+
rescue Encoding::CompatibilityError => e
|
44
|
+
# If the two strings are different encodings, we can't join them.
|
45
|
+
Brakeman.debug e.inspect
|
46
|
+
original_exp
|
43
47
|
end
|
44
48
|
|
45
49
|
def math_op op, lhs, rhs, original_exp = nil
|
@@ -8,6 +8,7 @@ class Brakeman::SlimTemplateProcessor < Brakeman::TemplateProcessor
|
|
8
8
|
OUTPUT_BUFFER = s(:ivar, :@output_buffer)
|
9
9
|
TEMPLE_UTILS = s(:colon2, s(:colon3, :Temple), :Utils)
|
10
10
|
ATTR_MERGE = s(:call, s(:call, s(:array), :reject, s(:block_pass, s(:lit, :empty?))), :join, s(:str, " "))
|
11
|
+
EMBEDDED_FILTER = s(:const, :BrakemanFilter)
|
11
12
|
|
12
13
|
def process_call exp
|
13
14
|
target = exp.target
|
@@ -44,6 +45,21 @@ class Brakeman::SlimTemplateProcessor < Brakeman::TemplateProcessor
|
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
48
|
+
def normalize_output arg
|
49
|
+
arg = super(arg)
|
50
|
+
|
51
|
+
if embedded_filter? arg
|
52
|
+
super(arg.first_arg)
|
53
|
+
else
|
54
|
+
arg
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Handle our "fake" embedded filters
|
59
|
+
def embedded_filter? arg
|
60
|
+
call? arg and arg.method == :render and arg.target == EMBEDDED_FILTER
|
61
|
+
end
|
62
|
+
|
47
63
|
#Slim likes to interpolate output into strings then pass them to safe_concat.
|
48
64
|
#Better to pull those values out directly.
|
49
65
|
def process_inside_interp exp
|
@@ -27,9 +27,9 @@ class Brakeman::TemplateAliasProcessor < Brakeman::AliasProcessor
|
|
27
27
|
return
|
28
28
|
end
|
29
29
|
|
30
|
-
super name, args, @called_from.dup.add_template_render(@template.name, line, @file_name)
|
30
|
+
super name, args, @called_from.dup.add_template_render(@template.name, line, @file_name), line
|
31
31
|
else
|
32
|
-
super name, args, Brakeman::RenderPath.new.add_template_render(@template.name, line, @file_name)
|
32
|
+
super name, args, Brakeman::RenderPath.new.add_template_render(@template.name, line, @file_name), line
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
data/lib/brakeman/scanner.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
begin
|
2
2
|
Brakeman.load_brakeman_dependency 'ruby_parser'
|
3
|
+
Brakeman.load_brakeman_dependency 'ruby_parser/legacy'
|
3
4
|
require 'ruby_parser/bm_sexp.rb'
|
4
5
|
require 'ruby_parser/bm_sexp_processor.rb'
|
5
6
|
require 'brakeman/processor'
|
@@ -118,7 +119,7 @@ class Brakeman::Scanner
|
|
118
119
|
path = "config/#{file}"
|
119
120
|
|
120
121
|
if @app_tree.exists?(path)
|
121
|
-
@processor.process_config(
|
122
|
+
@processor.process_config(parse_ruby_file(path), path)
|
122
123
|
end
|
123
124
|
|
124
125
|
rescue => e
|
@@ -132,9 +133,9 @@ class Brakeman::Scanner
|
|
132
133
|
def process_gems
|
133
134
|
gem_files = {}
|
134
135
|
if @app_tree.exists? "Gemfile"
|
135
|
-
gem_files[:gemfile] = { :src =>
|
136
|
+
gem_files[:gemfile] = { :src => parse_ruby_file("Gemfile"), :file => "Gemfile" }
|
136
137
|
elsif @app_tree.exists? "gems.rb"
|
137
|
-
gem_files[:gemfile] = { :src =>
|
138
|
+
gem_files[:gemfile] = { :src => parse_ruby_file("gems.rb"), :file => "gems.rb" }
|
138
139
|
end
|
139
140
|
|
140
141
|
if @app_tree.exists? "Gemfile.lock"
|
@@ -144,7 +145,7 @@ class Brakeman::Scanner
|
|
144
145
|
end
|
145
146
|
|
146
147
|
if @app_tree.gemspec
|
147
|
-
gem_files[:gemspec] = { :src =>
|
148
|
+
gem_files[:gemspec] = { :src => parse_ruby_file(@app_tree.gemspec), :file => @app_tree.gemspec }
|
148
149
|
end
|
149
150
|
|
150
151
|
if not gem_files.empty?
|
@@ -214,10 +215,9 @@ class Brakeman::Scanner
|
|
214
215
|
#Adds parsed information to tracker.routes
|
215
216
|
def process_routes
|
216
217
|
if @app_tree.exists?("config/routes.rb")
|
217
|
-
|
218
|
-
@processor.process_routes
|
219
|
-
|
220
|
-
tracker.error e.exception(e.message + "\nWhile processing routes.rb"), e.backtrace
|
218
|
+
if routes_sexp = parse_ruby_file("config/routes.rb")
|
219
|
+
@processor.process_routes routes_sexp
|
220
|
+
else
|
221
221
|
Brakeman.notify "[Notice] Error while processing routes - assuming all public controller methods are actions."
|
222
222
|
options[:assume_all_routes] = true
|
223
223
|
end
|
@@ -316,8 +316,9 @@ class Brakeman::Scanner
|
|
316
316
|
tracker.index_call_sites
|
317
317
|
end
|
318
318
|
|
319
|
-
def
|
320
|
-
|
319
|
+
def parse_ruby_file path
|
320
|
+
fp = Brakeman::FileParser.new(self.tracker, @app_tree)
|
321
|
+
fp.parse_ruby(@app_tree.read(path), path)
|
321
322
|
end
|
322
323
|
end
|
323
324
|
|
data/lib/brakeman/tracker.rb
CHANGED
@@ -61,7 +61,11 @@ class Brakeman::Tracker
|
|
61
61
|
Brakeman.debug exception
|
62
62
|
Brakeman.debug backtrace
|
63
63
|
|
64
|
-
@errors << {
|
64
|
+
@errors << {
|
65
|
+
:exception => exception,
|
66
|
+
:error => exception.to_s.gsub("\n", " "),
|
67
|
+
:backtrace => backtrace
|
68
|
+
}
|
65
69
|
end
|
66
70
|
|
67
71
|
#Run a set of checks on the current information. Results will be stored
|
@@ -122,22 +122,22 @@ module Brakeman
|
|
122
122
|
current_version ||= rails_version
|
123
123
|
return false unless current_version
|
124
124
|
|
125
|
-
version = current_version.split(".").map!
|
126
|
-
low_version = low_version.split(".").map!
|
127
|
-
high_version = high_version.split(".").map!
|
125
|
+
version = current_version.split(".").map! { |v| convert_version_number v }
|
126
|
+
low_version = low_version.split(".").map! { |v| convert_version_number v }
|
127
|
+
high_version = high_version.split(".").map! { |v| convert_version_number v }
|
128
128
|
|
129
129
|
version.each_with_index do |v, i|
|
130
|
-
if v
|
130
|
+
if lower? v, low_version.fetch(i, 0)
|
131
131
|
return false
|
132
|
-
elsif v
|
132
|
+
elsif higher? v, low_version.fetch(i, 0)
|
133
133
|
break
|
134
134
|
end
|
135
135
|
end
|
136
136
|
|
137
137
|
version.each_with_index do |v, i|
|
138
|
-
if v
|
138
|
+
if higher? v, high_version.fetch(i, 0)
|
139
139
|
return false
|
140
|
-
elsif v
|
140
|
+
elsif lower? v, high_version.fetch(i, 0)
|
141
141
|
break
|
142
142
|
end
|
143
143
|
end
|
@@ -150,5 +150,30 @@ module Brakeman
|
|
150
150
|
@rails[:action_controller][:session]
|
151
151
|
end
|
152
152
|
|
153
|
+
private
|
154
|
+
|
155
|
+
def convert_version_number value
|
156
|
+
if value.match(/\A\d+\z/)
|
157
|
+
value.to_i
|
158
|
+
else
|
159
|
+
value
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def lower? lhs, rhs
|
164
|
+
if lhs.class == rhs.class
|
165
|
+
lhs < rhs
|
166
|
+
else
|
167
|
+
false
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def higher? lhs, rhs
|
172
|
+
if lhs.class == rhs.class
|
173
|
+
lhs > rhs
|
174
|
+
else
|
175
|
+
false
|
176
|
+
end
|
177
|
+
end
|
153
178
|
end
|
154
179
|
end
|
data/lib/brakeman/util.rb
CHANGED
@@ -94,11 +94,21 @@ module Brakeman::Util
|
|
94
94
|
# end
|
95
95
|
# names #["bob"]
|
96
96
|
def hash_iterate hash
|
97
|
+
hash = remove_kwsplat(hash)
|
98
|
+
|
97
99
|
1.step(hash.length - 1, 2) do |i|
|
98
100
|
yield hash[i], hash[i + 1]
|
99
101
|
end
|
100
102
|
end
|
101
103
|
|
104
|
+
def remove_kwsplat exp
|
105
|
+
if exp.any? { |e| node_type? e, :kwsplat }
|
106
|
+
exp.reject { |e| node_type? e, :kwsplat }
|
107
|
+
else
|
108
|
+
exp
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
102
112
|
#Insert value into Hash Sexp
|
103
113
|
def hash_insert hash, key, value
|
104
114
|
index = 1
|
@@ -264,6 +274,13 @@ module Brakeman::Util
|
|
264
274
|
node_type? exp, :const, :colon2, :colon3
|
265
275
|
end
|
266
276
|
|
277
|
+
def kwsplat? exp
|
278
|
+
exp.is_a? Sexp and
|
279
|
+
exp.node_type == :hash and
|
280
|
+
exp[1].is_a? Sexp and
|
281
|
+
exp[1].node_type == :kwsplat
|
282
|
+
end
|
283
|
+
|
267
284
|
#Check if _exp_ is a Sexp.
|
268
285
|
def sexp? exp
|
269
286
|
exp.is_a? Sexp
|
data/lib/brakeman/version.rb
CHANGED
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: 4.
|
4
|
+
version: 4.5.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: 2019-
|
12
|
+
date: 2019-03-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: minitest
|
@@ -25,20 +25,48 @@ dependencies:
|
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: minitest-ci
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
28
42
|
- !ruby/object:Gem::Dependency
|
29
43
|
name: ruby_parser
|
30
44
|
requirement: !ruby/object:Gem::Requirement
|
31
45
|
requirements:
|
32
46
|
- - "~>"
|
33
47
|
- !ruby/object:Gem::Version
|
34
|
-
version: '3.
|
48
|
+
version: '3.13'
|
35
49
|
type: :runtime
|
36
50
|
prerelease: false
|
37
51
|
version_requirements: !ruby/object:Gem::Requirement
|
38
52
|
requirements:
|
39
53
|
- - "~>"
|
40
54
|
- !ruby/object:Gem::Version
|
41
|
-
version: '3.
|
55
|
+
version: '3.13'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: ruby_parser-legacy
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - "~>"
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '1.0'
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.0'
|
42
70
|
- !ruby/object:Gem::Dependency
|
43
71
|
name: sexp_processor
|
44
72
|
requirement: !ruby/object:Gem::Requirement
|
@@ -149,26 +177,6 @@ dependencies:
|
|
149
177
|
- - "<"
|
150
178
|
- !ruby/object:Gem::Version
|
151
179
|
version: '5.0'
|
152
|
-
- !ruby/object:Gem::Dependency
|
153
|
-
name: sass
|
154
|
-
requirement: !ruby/object:Gem::Requirement
|
155
|
-
requirements:
|
156
|
-
- - "~>"
|
157
|
-
- !ruby/object:Gem::Version
|
158
|
-
version: '3.0'
|
159
|
-
- - "<"
|
160
|
-
- !ruby/object:Gem::Version
|
161
|
-
version: 3.5.0
|
162
|
-
type: :runtime
|
163
|
-
prerelease: false
|
164
|
-
version_requirements: !ruby/object:Gem::Requirement
|
165
|
-
requirements:
|
166
|
-
- - "~>"
|
167
|
-
- !ruby/object:Gem::Version
|
168
|
-
version: '3.0'
|
169
|
-
- - "<"
|
170
|
-
- !ruby/object:Gem::Version
|
171
|
-
version: 3.5.0
|
172
180
|
- !ruby/object:Gem::Dependency
|
173
181
|
name: slim
|
174
182
|
requirement: !ruby/object:Gem::Requirement
|
@@ -284,9 +292,11 @@ files:
|
|
284
292
|
- lib/brakeman/format/style.css
|
285
293
|
- lib/brakeman/messages.rb
|
286
294
|
- lib/brakeman/options.rb
|
295
|
+
- lib/brakeman/parsers/haml_embedded.rb
|
287
296
|
- lib/brakeman/parsers/rails2_erubis.rb
|
288
297
|
- lib/brakeman/parsers/rails2_xss_plugin_erubis.rb
|
289
298
|
- lib/brakeman/parsers/rails3_erubis.rb
|
299
|
+
- lib/brakeman/parsers/slim_embedded.rb
|
290
300
|
- lib/brakeman/parsers/template_parser.rb
|
291
301
|
- lib/brakeman/processor.rb
|
292
302
|
- lib/brakeman/processors/alias_processor.rb
|
@@ -366,7 +376,7 @@ files:
|
|
366
376
|
- lib/ruby_parser/bm_sexp_processor.rb
|
367
377
|
homepage: http://brakemanscanner.org
|
368
378
|
licenses:
|
369
|
-
-
|
379
|
+
- Brakeman Public Use License
|
370
380
|
metadata: {}
|
371
381
|
post_install_message:
|
372
382
|
rdoc_options: []
|