brakeman 4.10.0 → 5.0.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +10 -0
- data/README.md +1 -1
- data/bundle/load.rb +8 -8
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/CHANGELOG.md +9 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/FAQ.md +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/Gemfile +1 -4
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/MIT-LICENSE +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/README.md +2 -3
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/REFERENCE.md +20 -2
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/TODO +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/haml.gemspec +2 -1
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/attribute_builder.rb +3 -3
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/attribute_compiler.rb +42 -31
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/attribute_parser.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/buffer.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/compiler.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/engine.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/error.rb +0 -0
- data/bundle/ruby/2.7.0/gems/haml-5.2.0/lib/haml/escapable.rb +77 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/exec.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/filters.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/generator.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/helpers.rb +7 -1
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/helpers/action_view_extensions.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/helpers/action_view_mods.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/helpers/action_view_xss_mods.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/helpers/safe_erubi_template.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/helpers/safe_erubis_template.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/helpers/xss_mods.rb +6 -3
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/options.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/parser.rb +1 -1
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/plugin.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/railtie.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/sass_rails_filter.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/template.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/template/options.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/temple_engine.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/temple_line_counter.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/util.rb +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/version.rb +1 -1
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/yard/default/fulldoc/html/css/common.sass +0 -0
- data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/yard/default/layout/html/footer.erb +0 -0
- data/lib/brakeman.rb +6 -0
- data/lib/brakeman/app_tree.rb +36 -3
- data/lib/brakeman/checks/check_unsafe_reflection_methods.rb +68 -0
- data/lib/brakeman/checks/check_verb_confusion.rb +75 -0
- data/lib/brakeman/file_parser.rb +19 -18
- data/lib/brakeman/options.rb +5 -1
- data/lib/brakeman/parsers/template_parser.rb +2 -3
- data/lib/brakeman/processors/haml_template_processor.rb +8 -1
- data/lib/brakeman/processors/lib/file_type_detector.rb +64 -0
- data/lib/brakeman/report.rb +8 -0
- data/lib/brakeman/report/report_sonar.rb +38 -0
- data/lib/brakeman/rescanner.rb +7 -5
- data/lib/brakeman/scanner.rb +42 -18
- data/lib/brakeman/tracker.rb +6 -0
- data/lib/brakeman/util.rb +7 -2
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman/warning_codes.rb +2 -0
- metadata +49 -45
- data/bundle/ruby/2.7.0/gems/haml-5.1.2/lib/haml/escapable.rb +0 -50
data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/helpers/action_view_extensions.rb
RENAMED
File without changes
|
File without changes
|
data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/helpers/action_view_xss_mods.rb
RENAMED
File without changes
|
data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/helpers/safe_erubi_template.rb
RENAMED
File without changes
|
data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/lib/haml/helpers/safe_erubis_template.rb
RENAMED
File without changes
|
@@ -8,12 +8,15 @@ module Haml
|
|
8
8
|
# to work with Rails' XSS protection methods.
|
9
9
|
module XssMods
|
10
10
|
def self.included(base)
|
11
|
-
%w[
|
12
|
-
precede succeed capture_haml haml_concat haml_internal_concat haml_indent
|
13
|
-
escape_once].each do |name|
|
11
|
+
%w[find_and_preserve preserve list_of surround
|
12
|
+
precede succeed capture_haml haml_concat haml_internal_concat haml_indent].each do |name|
|
14
13
|
base.send(:alias_method, "#{name}_without_haml_xss", name)
|
15
14
|
base.send(:alias_method, name, "#{name}_with_haml_xss")
|
16
15
|
end
|
16
|
+
# Those two always have _without_haml_xss
|
17
|
+
%w[html_escape escape_once].each do |name|
|
18
|
+
base.send(:alias_method, name, "#{name}_with_haml_xss")
|
19
|
+
end
|
17
20
|
end
|
18
21
|
|
19
22
|
# Don't escape text that's already safe,
|
File without changes
|
@@ -307,7 +307,7 @@ module Haml
|
|
307
307
|
return ParseNode.new(:plain, line.index + 1, :text => line.text)
|
308
308
|
end
|
309
309
|
|
310
|
-
escape_html = @options.escape_html if escape_html.nil?
|
310
|
+
escape_html = @options.escape_html && @options.mime_type != 'text/plain' if escape_html.nil?
|
311
311
|
line.text = unescape_interpolation(line.text, escape_html)
|
312
312
|
script(line, false)
|
313
313
|
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/bundle/ruby/2.7.0/gems/{haml-5.1.2 → haml-5.2.0}/yard/default/fulldoc/html/css/common.sass
RENAMED
File without changes
|
File without changes
|
data/lib/brakeman.rb
CHANGED
@@ -66,6 +66,7 @@ module Brakeman
|
|
66
66
|
# * :run_checks - array of checks to run (run all if not specified)
|
67
67
|
# * :safe_methods - array of methods to consider safe
|
68
68
|
# * :skip_libs - do not process lib/ directory (default: false)
|
69
|
+
# * :skip_vendor - do not process vendor/ directory (default: true)
|
69
70
|
# * :skip_checks - checks not to run (run all if not specified)
|
70
71
|
# * :absolute_paths - show absolute path of each file (default: false)
|
71
72
|
# * :summary_only - only output summary section of report for plain/table (:summary_only, :no_summary, true)
|
@@ -191,6 +192,7 @@ module Brakeman
|
|
191
192
|
:report_progress => true,
|
192
193
|
:safe_methods => Set.new,
|
193
194
|
:skip_checks => Set.new,
|
195
|
+
:skip_vendor => true,
|
194
196
|
}
|
195
197
|
end
|
196
198
|
|
@@ -239,6 +241,8 @@ module Brakeman
|
|
239
241
|
[:to_junit]
|
240
242
|
when :sarif, :to_sarif
|
241
243
|
[:to_sarif]
|
244
|
+
when :sonar, :to_sonar
|
245
|
+
[:to_sonar]
|
242
246
|
else
|
243
247
|
[:to_text]
|
244
248
|
end
|
@@ -270,6 +274,8 @@ module Brakeman
|
|
270
274
|
:to_junit
|
271
275
|
when /\.sarif$/i
|
272
276
|
:to_sarif
|
277
|
+
when /\.sonar$/i
|
278
|
+
:to_sonar
|
273
279
|
else
|
274
280
|
:to_text
|
275
281
|
end
|
data/lib/brakeman/app_tree.rb
CHANGED
@@ -21,6 +21,7 @@ module Brakeman
|
|
21
21
|
end
|
22
22
|
init_options[:additional_libs_path] = options[:additional_libs_path]
|
23
23
|
init_options[:engine_paths] = options[:engine_paths]
|
24
|
+
init_options[:skip_vendor] = options[:skip_vendor]
|
24
25
|
new(root, init_options)
|
25
26
|
end
|
26
27
|
|
@@ -62,6 +63,7 @@ module Brakeman
|
|
62
63
|
@engine_paths = init_options[:engine_paths] || []
|
63
64
|
@absolute_engine_paths = @engine_paths.select { |path| path.start_with?(File::SEPARATOR) }
|
64
65
|
@relative_engine_paths = @engine_paths - @absolute_engine_paths
|
66
|
+
@skip_vendor = init_options[:skip_vendor]
|
65
67
|
@gemspec = nil
|
66
68
|
@root_search_pattern = nil
|
67
69
|
end
|
@@ -96,6 +98,10 @@ module Brakeman
|
|
96
98
|
end
|
97
99
|
end
|
98
100
|
|
101
|
+
def ruby_file_paths
|
102
|
+
find_paths(".").uniq
|
103
|
+
end
|
104
|
+
|
99
105
|
def initializer_paths
|
100
106
|
@initializer_paths ||= prioritize_concerns(find_paths("config/initializers"))
|
101
107
|
end
|
@@ -109,8 +115,8 @@ module Brakeman
|
|
109
115
|
end
|
110
116
|
|
111
117
|
def template_paths
|
112
|
-
@template_paths ||= find_paths("
|
113
|
-
|
118
|
+
@template_paths ||= find_paths(".", "*.{#{VIEW_EXTENSIONS}}") +
|
119
|
+
find_paths("**", "*.{erb,haml,slim}").reject { |path| File.basename(path).count(".") > 1 }
|
114
120
|
end
|
115
121
|
|
116
122
|
def layout_exists?(name)
|
@@ -163,7 +169,8 @@ module Brakeman
|
|
163
169
|
def select_files(paths)
|
164
170
|
paths = select_only_files(paths)
|
165
171
|
paths = reject_skipped_files(paths)
|
166
|
-
convert_to_file_paths(paths)
|
172
|
+
paths = convert_to_file_paths(paths)
|
173
|
+
reject_global_excludes(paths)
|
167
174
|
end
|
168
175
|
|
169
176
|
def select_only_files(paths)
|
@@ -182,6 +189,32 @@ module Brakeman
|
|
182
189
|
end
|
183
190
|
end
|
184
191
|
|
192
|
+
EXCLUDED_PATHS = %w[
|
193
|
+
/generators/
|
194
|
+
lib/tasks/
|
195
|
+
lib/templates/
|
196
|
+
db/
|
197
|
+
spec/
|
198
|
+
test/
|
199
|
+
tmp/
|
200
|
+
public/
|
201
|
+
log/
|
202
|
+
]
|
203
|
+
|
204
|
+
def reject_global_excludes(paths)
|
205
|
+
paths.reject do |path|
|
206
|
+
relative_path = path.relative
|
207
|
+
|
208
|
+
if @skip_vendor and relative_path.include? 'vendor/'
|
209
|
+
true
|
210
|
+
else
|
211
|
+
EXCLUDED_PATHS.any? do |excluded|
|
212
|
+
relative_path.include? excluded
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
185
218
|
def match_path files, path
|
186
219
|
absolute_path = Pathname.new(path)
|
187
220
|
# relative root never has a leading separator. But, we use a leading
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'brakeman/checks/base_check'
|
2
|
+
|
3
|
+
class Brakeman::CheckUnsafeReflectionMethods < Brakeman::BaseCheck
|
4
|
+
Brakeman::Checks.add self
|
5
|
+
|
6
|
+
@description = "Checks for unsafe reflection to access methods"
|
7
|
+
|
8
|
+
def run_check
|
9
|
+
check_method
|
10
|
+
check_tap
|
11
|
+
check_to_proc
|
12
|
+
end
|
13
|
+
|
14
|
+
def check_method
|
15
|
+
tracker.find_call(method: :method, nested: true).each do |result|
|
16
|
+
argument = result[:call].first_arg
|
17
|
+
|
18
|
+
if user_input = include_user_input?(argument)
|
19
|
+
warn_unsafe_reflection(result, user_input)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def check_tap
|
25
|
+
tracker.find_call(method: :tap, nested: true).each do |result|
|
26
|
+
argument = result[:call].first_arg
|
27
|
+
|
28
|
+
# Argument is passed like a.tap(&argument)
|
29
|
+
if node_type? argument, :block_pass
|
30
|
+
argument = argument.value
|
31
|
+
end
|
32
|
+
|
33
|
+
if user_input = include_user_input?(argument)
|
34
|
+
warn_unsafe_reflection(result, user_input)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def check_to_proc
|
40
|
+
tracker.find_call(method: :to_proc, nested: true).each do |result|
|
41
|
+
target = result[:call].target
|
42
|
+
|
43
|
+
if user_input = include_user_input?(target)
|
44
|
+
warn_unsafe_reflection(result, user_input)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def warn_unsafe_reflection result, input
|
50
|
+
return unless original? result
|
51
|
+
method = result[:call].method
|
52
|
+
|
53
|
+
confidence = if input.type == :params
|
54
|
+
:high
|
55
|
+
else
|
56
|
+
:medium
|
57
|
+
end
|
58
|
+
|
59
|
+
message = msg("Unsafe reflection method ", msg_code(method), " called with ", msg_input(input))
|
60
|
+
|
61
|
+
warn :result => result,
|
62
|
+
:warning_type => "Remote Code Execution",
|
63
|
+
:warning_code => :unsafe_method_reflection,
|
64
|
+
:message => message,
|
65
|
+
:user_input => input,
|
66
|
+
:confidence => confidence
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'brakeman/checks/base_check'
|
2
|
+
|
3
|
+
class Brakeman::CheckVerbConfusion < Brakeman::BaseCheck
|
4
|
+
Brakeman::Checks.add self
|
5
|
+
|
6
|
+
@description = "Check for uses of `request.get?` that might have unintentional behavior"
|
7
|
+
|
8
|
+
#Process calls
|
9
|
+
def run_check
|
10
|
+
calls = tracker.find_call(target: :request, methods: [:get?])
|
11
|
+
|
12
|
+
calls.each do |call|
|
13
|
+
process_result call
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def process_result result
|
18
|
+
@current_result = result
|
19
|
+
@matched_call = result[:call]
|
20
|
+
klass = tracker.find_class(result[:location][:class])
|
21
|
+
|
22
|
+
# TODO: abstract into tracker.find_location ?
|
23
|
+
if klass.nil?
|
24
|
+
Brakeman.debug "No class found: #{result[:location][:class]}"
|
25
|
+
return
|
26
|
+
end
|
27
|
+
|
28
|
+
method = klass.get_method(result[:location][:method])
|
29
|
+
|
30
|
+
if method.nil?
|
31
|
+
Brakeman.debug "No method found: #{result[:location][:method]}"
|
32
|
+
return
|
33
|
+
end
|
34
|
+
|
35
|
+
process method[:src]
|
36
|
+
end
|
37
|
+
|
38
|
+
def process_if exp
|
39
|
+
if exp.condition == @matched_call
|
40
|
+
# Found `if request.get?`
|
41
|
+
|
42
|
+
# Do not warn if there is an `elsif` clause
|
43
|
+
if node_type? exp.else_clause, :if
|
44
|
+
return exp
|
45
|
+
end
|
46
|
+
|
47
|
+
warn_about_result @current_result, exp
|
48
|
+
end
|
49
|
+
|
50
|
+
exp
|
51
|
+
end
|
52
|
+
|
53
|
+
def warn_about_result result, code
|
54
|
+
return unless original? result
|
55
|
+
|
56
|
+
confidence = :weak
|
57
|
+
message = msg('Potential HTTP verb confusion. ',
|
58
|
+
msg_code('HEAD'),
|
59
|
+
' is routed like ',
|
60
|
+
msg_code('GET'),
|
61
|
+
' but ',
|
62
|
+
msg_code('request.get?'),
|
63
|
+
' will return ',
|
64
|
+
msg_code('false')
|
65
|
+
)
|
66
|
+
|
67
|
+
warn :result => result,
|
68
|
+
:warning_type => "HTTP Verb Confusion",
|
69
|
+
:warning_code => :http_verb_confusion,
|
70
|
+
:message => message,
|
71
|
+
:code => code,
|
72
|
+
:user_input => result[:call],
|
73
|
+
:confidence => confidence
|
74
|
+
end
|
75
|
+
end
|
data/lib/brakeman/file_parser.rb
CHANGED
@@ -3,32 +3,31 @@ module Brakeman
|
|
3
3
|
|
4
4
|
# This class handles reading and parsing files.
|
5
5
|
class FileParser
|
6
|
-
attr_reader :file_list
|
6
|
+
attr_reader :file_list, :errors
|
7
7
|
|
8
|
-
def initialize
|
9
|
-
@
|
10
|
-
@timeout =
|
11
|
-
@
|
12
|
-
@
|
8
|
+
def initialize app_tree, timeout
|
9
|
+
@app_tree = app_tree
|
10
|
+
@timeout = timeout
|
11
|
+
@file_list = []
|
12
|
+
@errors = []
|
13
13
|
end
|
14
14
|
|
15
|
-
def parse_files list
|
16
|
-
read_files list
|
15
|
+
def parse_files list
|
16
|
+
read_files list do |path, contents|
|
17
17
|
if ast = parse_ruby(contents, path.relative)
|
18
18
|
ASTFile.new(path, ast)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
def read_files list
|
24
|
-
@file_list[type] ||= []
|
25
|
-
|
23
|
+
def read_files list
|
26
24
|
list.each do |path|
|
27
25
|
file = @app_tree.file_path(path)
|
28
26
|
|
29
27
|
result = yield file, file.read
|
28
|
+
|
30
29
|
if result
|
31
|
-
@file_list
|
30
|
+
@file_list << result
|
32
31
|
end
|
33
32
|
end
|
34
33
|
end
|
@@ -38,15 +37,17 @@ module Brakeman
|
|
38
37
|
Brakeman.debug "Parsing #{path}"
|
39
38
|
RubyParser.new.parse input, path, @timeout
|
40
39
|
rescue Racc::ParseError => e
|
41
|
-
|
42
|
-
nil
|
40
|
+
error e.exception(e.message + "\nCould not parse #{path}")
|
43
41
|
rescue Timeout::Error => e
|
44
|
-
|
45
|
-
nil
|
42
|
+
error Exception.new("Parsing #{path} took too long (> #{@timeout} seconds). Try increasing the limit with --parser-timeout")
|
46
43
|
rescue => e
|
47
|
-
|
48
|
-
nil
|
44
|
+
error e.exception(e.message + "\nWhile processing #{path}")
|
49
45
|
end
|
50
46
|
end
|
47
|
+
|
48
|
+
def error exception
|
49
|
+
@errors << exception
|
50
|
+
nil
|
51
|
+
end
|
51
52
|
end
|
52
53
|
end
|
data/lib/brakeman/options.rb
CHANGED
@@ -166,6 +166,10 @@ module Brakeman::Options
|
|
166
166
|
options[:only_files].merge files
|
167
167
|
end
|
168
168
|
|
169
|
+
opts.on "--[no-]skip-vendor", "Skip processing vendor directory (Default)" do |skip|
|
170
|
+
options[:skip_vendor] = skip
|
171
|
+
end
|
172
|
+
|
169
173
|
opts.on "--skip-libs", "Skip processing lib directory" do
|
170
174
|
options[:skip_libs] = true
|
171
175
|
end
|
@@ -229,7 +233,7 @@ module Brakeman::Options
|
|
229
233
|
|
230
234
|
opts.on "-f",
|
231
235
|
"--format TYPE",
|
232
|
-
[:pdf, :text, :html, :csv, :tabs, :json, :markdown, :codeclimate, :cc, :plain, :table, :junit, :sarif],
|
236
|
+
[:pdf, :text, :html, :csv, :tabs, :json, :markdown, :codeclimate, :cc, :plain, :table, :junit, :sarif, :sonar],
|
233
237
|
"Specify output formats. Default is text" do |type|
|
234
238
|
|
235
239
|
type = "s" if type == :text
|
@@ -9,7 +9,6 @@ module Brakeman
|
|
9
9
|
def initialize tracker, file_parser
|
10
10
|
@tracker = tracker
|
11
11
|
@file_parser = file_parser
|
12
|
-
@file_parser.file_list[:templates] ||= []
|
13
12
|
end
|
14
13
|
|
15
14
|
def parse_template path, text
|
@@ -33,7 +32,7 @@ module Brakeman
|
|
33
32
|
end
|
34
33
|
|
35
34
|
if src and ast = @file_parser.parse_ruby(src, path)
|
36
|
-
@file_parser.file_list
|
35
|
+
@file_parser.file_list << TemplateFile.new(path, ast, name, type)
|
37
36
|
end
|
38
37
|
rescue Racc::ParseError => e
|
39
38
|
tracker.error e, "Could not parse #{path}"
|
@@ -97,7 +96,7 @@ module Brakeman
|
|
97
96
|
end
|
98
97
|
|
99
98
|
def self.parse_inline_erb tracker, text
|
100
|
-
fp = Brakeman::FileParser.new(tracker)
|
99
|
+
fp = Brakeman::FileParser.new(tracker.app_tree, tracker.options[:parser_timeout])
|
101
100
|
tp = self.new(tracker, fp)
|
102
101
|
src = tp.parse_erb '_inline_', text
|
103
102
|
type = tp.erubis? ? :erubis : :erb
|
@@ -76,6 +76,13 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
|
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
+
ESCAPE_METHODS = [
|
80
|
+
:html_escape,
|
81
|
+
:html_escape_without_haml_xss,
|
82
|
+
:escape_once,
|
83
|
+
:escape_once_without_haml_xss
|
84
|
+
]
|
85
|
+
|
79
86
|
def get_pushed_value exp, default = :output
|
80
87
|
return exp unless sexp? exp
|
81
88
|
|
@@ -105,7 +112,7 @@ class Brakeman::HamlTemplateProcessor < Brakeman::TemplateProcessor
|
|
105
112
|
when :call
|
106
113
|
if exp.method == :to_s or exp.method == :strip
|
107
114
|
get_pushed_value(exp.target, default)
|
108
|
-
elsif haml_helpers? exp.target and exp.method
|
115
|
+
elsif haml_helpers? exp.target and ESCAPE_METHODS.include? exp.method
|
109
116
|
get_pushed_value(exp.first_arg, :escaped_output)
|
110
117
|
elsif @javascript and (exp.method == :j or exp.method == :escape_javascript) # TODO: Remove - this is not safe
|
111
118
|
get_pushed_value(exp.first_arg, :escaped_output)
|