brakeman 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/brakeman +32 -173
- data/lib/brakeman.rb +47 -25
- data/lib/brakeman/call_index.rb +37 -1
- data/lib/brakeman/checks.rb +17 -0
- data/lib/brakeman/checks/base_check.rb +5 -1
- data/lib/brakeman/checks/check_cross_site_scripting.rb +18 -22
- data/lib/brakeman/checks/check_execute.rb +11 -24
- data/lib/brakeman/checks/check_render.rb +15 -26
- data/lib/brakeman/checks/check_sql.rb +48 -3
- data/lib/brakeman/options.rb +204 -0
- data/lib/brakeman/processor.rb +2 -2
- data/lib/brakeman/processors/controller_alias_processor.rb +9 -1
- data/lib/brakeman/processors/lib/find_all_calls.rb +36 -0
- data/lib/brakeman/processors/lib/rails3_route_processor.rb +1 -0
- data/lib/brakeman/processors/model_processor.rb +1 -1
- data/lib/brakeman/report.rb +36 -122
- data/lib/brakeman/rescanner.rb +247 -0
- data/lib/brakeman/scanner.rb +94 -76
- data/lib/brakeman/tracker.rb +103 -2
- data/lib/brakeman/util.rb +106 -0
- data/lib/brakeman/version.rb +1 -1
- data/lib/brakeman/warning.rb +26 -11
- metadata +5 -3
data/bin/brakeman
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'set'
|
4
|
-
|
2
|
+
#Adjust path in case called directly and not through gem
|
5
3
|
$:.unshift "#{File.expand_path(File.dirname(__FILE__))}/../lib"
|
6
4
|
|
7
5
|
require 'brakeman'
|
6
|
+
require 'brakeman/options'
|
8
7
|
require 'brakeman/version'
|
9
8
|
|
10
9
|
trap("INT") do
|
@@ -12,180 +11,40 @@ trap("INT") do
|
|
12
11
|
exit!
|
13
12
|
end
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
opts.on "-q", "--quiet", "Suppress informational messages" do
|
36
|
-
options[:quiet] = true
|
37
|
-
end
|
38
|
-
|
39
|
-
opts.on( "-z", "--exit-on-warn", "Exit code is non-zero if warnings found") do |s|
|
40
|
-
options[:exit_on_warn] = s
|
41
|
-
end
|
42
|
-
|
43
|
-
opts.on "-3", "--rails3", "Force Rails 3 mode" do
|
44
|
-
options[:rails3] = true
|
45
|
-
end
|
46
|
-
|
47
|
-
opts.separator ""
|
48
|
-
opts.separator "Scanning options:"
|
49
|
-
|
50
|
-
opts.on "-a", "--assume-routes", "Assume all controller methods are actions" do
|
51
|
-
options[:assume_all_routes] = true
|
52
|
-
end
|
53
|
-
|
54
|
-
opts.on "--ignore-model-output", "Consider model attributes XSS-safe" do
|
55
|
-
options[:ignore_model_output] = true
|
56
|
-
end
|
57
|
-
|
58
|
-
opts.on "-e", "--escape-html", "Escape HTML by default" do
|
59
|
-
options[:escape_html] = true
|
60
|
-
end
|
61
|
-
|
62
|
-
opts.on "--faster", "Faster, but less accurate scan" do
|
63
|
-
options[:ignore_ifs] = true
|
64
|
-
options[:skip_libs] = true
|
65
|
-
end
|
66
|
-
|
67
|
-
opts.on "--no-branching", "Disable flow sensitivity on conditionals" do
|
68
|
-
options[:ignore_ifs] = true
|
69
|
-
end
|
70
|
-
|
71
|
-
opts.on "-r", "--report-direct", "Only report direct use of untrusted data" do |option|
|
72
|
-
options[:check_arguments] = !option
|
73
|
-
end
|
74
|
-
|
75
|
-
opts.on "-s", "--safe-methods meth1,meth2,etc", Array, "Consider the specified methods safe" do |methods|
|
76
|
-
options[:safe_methods] ||= Set.new
|
77
|
-
options[:safe_methods].merge methods.map {|e| e.to_sym }
|
78
|
-
end
|
79
|
-
|
80
|
-
opts.on "--skip-libs", "Skip processing lib directory" do
|
81
|
-
options[:skip_libs] = true
|
82
|
-
end
|
83
|
-
|
84
|
-
opts.on "-t", "--test Check1,Check2,etc", Array, "Only run the specified checks" do |checks|
|
85
|
-
checks.each_with_index do |s, index|
|
86
|
-
if s[0,5] != "Check"
|
87
|
-
checks[index] = "Check" << s
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
options[:run_checks] ||= Set.new
|
92
|
-
options[:run_checks].merge checks
|
93
|
-
end
|
94
|
-
|
95
|
-
opts.on "-x", "--except Check1,Check2,etc", Array, "Skip the specified checks" do |skip|
|
96
|
-
skip.each do |s|
|
97
|
-
if s[0,5] != "Check"
|
98
|
-
s = "Check" << s
|
99
|
-
end
|
100
|
-
|
101
|
-
options[:skip_checks] ||= Set.new
|
102
|
-
options[:skip_checks] << s
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
opts.separator ""
|
107
|
-
opts.separator "Output options:"
|
108
|
-
|
109
|
-
opts.on "-d", "--debug", "Lots of output" do
|
110
|
-
options[:debug] = true
|
111
|
-
end
|
112
|
-
|
113
|
-
opts.on "-f",
|
114
|
-
"--format TYPE",
|
115
|
-
[:pdf, :text, :html, :csv, :tabs],
|
116
|
-
"Specify output format. Default is text" do |type|
|
117
|
-
|
118
|
-
type = "s" if type == :text
|
119
|
-
options[:output_format] = ("to_" << type.to_s).to_sym
|
120
|
-
end
|
121
|
-
|
122
|
-
opts.on "--css-file CSSFile", "Specify CSS to use for HTML output" do |file|
|
123
|
-
options[:html_style] = File.expand_path file
|
124
|
-
end
|
125
|
-
|
126
|
-
opts.on "-l", "--[no]-combine-locations", "Combine warning locations (Default)" do |combine|
|
127
|
-
options[:combine_locations] = combine
|
128
|
-
end
|
129
|
-
|
130
|
-
opts.on "-m", "--routes", "Report controller information" do
|
131
|
-
options[:report_routes] = true
|
132
|
-
end
|
133
|
-
|
134
|
-
opts.on "--message-limit LENGTH", "Limit message length in HTML report" do |limit|
|
135
|
-
options[:message_limit] = limit.to_i
|
136
|
-
end
|
137
|
-
|
138
|
-
opts.on "-o", "--output FILE", "Specify file for output. Defaults to stdout" do |file|
|
139
|
-
options[:output_file] = file
|
140
|
-
end
|
141
|
-
|
142
|
-
opts.on "--separate-models", "Warn on each model without attr_accessible" do
|
143
|
-
options[:collapse_mass_assignment] = false
|
144
|
-
end
|
145
|
-
|
146
|
-
opts.on "-w",
|
147
|
-
"--confidence-level LEVEL",
|
148
|
-
["1", "2", "3"],
|
149
|
-
"Set minimal confidence level (1 - 3)" do |level|
|
150
|
-
|
151
|
-
options[:min_confidence] = 3 - level.to_i
|
152
|
-
end
|
153
|
-
|
154
|
-
opts.separator ""
|
155
|
-
opts.separator "Configuration files:"
|
156
|
-
|
157
|
-
opts.on "-c", "--config-file FILE", "Use specified configuration file" do |file|
|
158
|
-
options[:config_file] = File.expand_path(file)
|
159
|
-
end
|
160
|
-
|
161
|
-
opts.on "-C", "--create-config [FILE]", "Output configuration file based on options" do |file|
|
162
|
-
if file
|
163
|
-
options[:create_config] = file
|
164
|
-
else
|
165
|
-
options[:create_config] = true
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
opts.separator ""
|
170
|
-
|
171
|
-
opts.on "-k", "--checks", "List all available vulnerability checks" do
|
172
|
-
options[:list_checks] = true
|
173
|
-
end
|
174
|
-
|
175
|
-
opts.on "-v", "--version", "Show Brakeman version" do
|
176
|
-
puts "brakeman #{Brakeman::Version}"
|
177
|
-
exit
|
178
|
-
end
|
14
|
+
#Parse options
|
15
|
+
options, parser = Brakeman::Options.parse! ARGV
|
16
|
+
|
17
|
+
#Exit early for these options
|
18
|
+
if options[:list_checks]
|
19
|
+
Brakeman.list_checks
|
20
|
+
exit
|
21
|
+
elsif options[:create_config]
|
22
|
+
Brakeman.dump_config options
|
23
|
+
exit
|
24
|
+
elsif options[:show_help]
|
25
|
+
puts parser
|
26
|
+
exit
|
27
|
+
elsif options[:show_version]
|
28
|
+
puts "brakeman #{Brakeman::Version}"
|
29
|
+
exit
|
30
|
+
elsif options[:install_rake_task]
|
31
|
+
Brakeman.install_rake_task
|
32
|
+
exit
|
33
|
+
end
|
179
34
|
|
180
|
-
|
181
|
-
|
182
|
-
|
35
|
+
#Set application path according to the commandline arguments
|
36
|
+
unless options[:app_path]
|
37
|
+
if ARGV[-1].nil?
|
38
|
+
options[:app_path] = File.expand_path "."
|
39
|
+
else
|
40
|
+
options[:app_path] = File.expand_path ARGV[-1]
|
183
41
|
end
|
184
|
-
end
|
42
|
+
end
|
185
43
|
|
44
|
+
#Run scan and output a report
|
186
45
|
clean = Brakeman.run options.merge(:print_report => true, :quiet => options[:quiet])
|
187
46
|
|
188
|
-
if
|
47
|
+
#Return error code if --exit-on-warn is used and warnings were found
|
48
|
+
if options[:exit_on_warn] and not clean
|
189
49
|
exit Brakeman::Warnings_Found_Exit_Code
|
190
50
|
end
|
191
|
-
|
data/lib/brakeman.rb
CHANGED
@@ -4,6 +4,10 @@ require 'set'
|
|
4
4
|
|
5
5
|
module Brakeman
|
6
6
|
|
7
|
+
#This exit code is used when warnings are found and the --exit-on-warn
|
8
|
+
#option is set
|
9
|
+
Warnings_Found_Exit_Code = 3
|
10
|
+
|
7
11
|
#Run Brakeman scan. Returns Tracker object.
|
8
12
|
#
|
9
13
|
#Options:
|
@@ -14,12 +18,10 @@ module Brakeman
|
|
14
18
|
# * :collapse_mass_assignment - report unprotected models in single warning (default: true)
|
15
19
|
# * :combine_locations - combine warning locations (default: true)
|
16
20
|
# * :config_file - configuration file
|
17
|
-
# * :create_config - output configuration file
|
18
21
|
# * :escape_html - escape HTML by default (automatic)
|
19
22
|
# * :exit_on_warn - return false if warnings found, true otherwise. Not recommended for library use (default: false)
|
20
23
|
# * :html_style - path to CSS file
|
21
24
|
# * :ignore_model_output - consider models safe (default: false)
|
22
|
-
# * :list_checks - list all checks (does not run scan)
|
23
25
|
# * :message_limit - limit length of messages
|
24
26
|
# * :min_confidence - minimum confidence (0-2, 0 is highest)
|
25
27
|
# * :output_file - file for output
|
@@ -33,18 +35,11 @@ module Brakeman
|
|
33
35
|
# * :safe_methods - array of methods to consider safe
|
34
36
|
# * :skip_libs - do not process lib/ directory (default: false)
|
35
37
|
# * :skip_checks - checks not to run (run all if not specified)
|
38
|
+
# * :summary_only - only output summary section of report
|
39
|
+
# (does not apply to tabs format)
|
36
40
|
#
|
41
|
+
#Alternatively, just supply a path as a string.
|
37
42
|
def self.run options
|
38
|
-
if options[:list_checks]
|
39
|
-
list_checks
|
40
|
-
exit
|
41
|
-
end
|
42
|
-
|
43
|
-
if options[:create_config]
|
44
|
-
dump_config options
|
45
|
-
exit
|
46
|
-
end
|
47
|
-
|
48
43
|
options = set_options options
|
49
44
|
|
50
45
|
if options[:quiet]
|
@@ -55,22 +50,17 @@ module Brakeman
|
|
55
50
|
scan options
|
56
51
|
end
|
57
52
|
|
58
|
-
private
|
59
|
-
|
60
53
|
def self.set_options options
|
54
|
+
if options.is_a? String
|
55
|
+
options = { :app_path => options }
|
56
|
+
end
|
57
|
+
|
58
|
+
options[:app_path] = File.expand_path(options[:app_path])
|
59
|
+
|
61
60
|
options = load_options(options[:config_file]).merge! options
|
62
61
|
options = get_defaults.merge! options
|
63
62
|
options[:output_format] = get_output_format options
|
64
63
|
|
65
|
-
#Check application path
|
66
|
-
unless options[:app_path]
|
67
|
-
if ARGV[-1].nil?
|
68
|
-
options[:app_path] = File.expand_path "."
|
69
|
-
else
|
70
|
-
options[:app_path] = File.expand_path ARGV[-1]
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
64
|
app_path = options[:app_path]
|
75
65
|
|
76
66
|
abort("Please supply the path to a Rails application.") unless app_path and File.exist? app_path + "/app"
|
@@ -86,7 +76,7 @@ module Brakeman
|
|
86
76
|
def self.load_options config_file
|
87
77
|
config_file ||= ""
|
88
78
|
|
89
|
-
#Load
|
79
|
+
#Load configuration file
|
90
80
|
[File.expand_path(config_file),
|
91
81
|
File.expand_path("./config.yaml"),
|
92
82
|
File.expand_path("~/.brakeman/config.yaml"),
|
@@ -161,7 +151,33 @@ module Brakeman
|
|
161
151
|
require 'brakeman/scanner'
|
162
152
|
$stderr.puts "Available Checks:"
|
163
153
|
$stderr.puts "-" * 30
|
164
|
-
$stderr.puts Checks.checks.map { |c| c.to_s }.sort.join "\n"
|
154
|
+
$stderr.puts Checks.checks.map { |c| c.to_s.match(/^Brakeman::(.*)$/)[1] }.sort.join "\n"
|
155
|
+
end
|
156
|
+
|
157
|
+
def self.install_rake_task
|
158
|
+
if not File.exists? "Rakefile"
|
159
|
+
abort "No Rakefile detected"
|
160
|
+
elsif File.exists? "lib/tasks/brakeman.rake"
|
161
|
+
abort "Task already exists"
|
162
|
+
end
|
163
|
+
|
164
|
+
require 'fileutils'
|
165
|
+
|
166
|
+
if not File.exists? "lib/tasks"
|
167
|
+
warn "Creating lib/tasks"
|
168
|
+
FileUtils.mkdir_p "lib/tasks"
|
169
|
+
end
|
170
|
+
|
171
|
+
path = File.expand_path(File.dirname(__FILE__))
|
172
|
+
|
173
|
+
FileUtils.cp "#{path}/brakeman/brakeman.rake", "lib/tasks/brakeman.rake"
|
174
|
+
|
175
|
+
if File.exists? "lib/tasks/brakeman.rake"
|
176
|
+
warn "Task created in lib/tasks/brakeman.rake"
|
177
|
+
warn "Usage: rake brakeman:run[output_file]"
|
178
|
+
else
|
179
|
+
warn "Could not create task"
|
180
|
+
end
|
165
181
|
end
|
166
182
|
|
167
183
|
def self.dump_config options
|
@@ -239,4 +255,10 @@ module Brakeman
|
|
239
255
|
|
240
256
|
tracker
|
241
257
|
end
|
258
|
+
|
259
|
+
def self.rescan tracker, files
|
260
|
+
require 'brakeman/rescanner'
|
261
|
+
|
262
|
+
Rescanner.new(tracker.options, tracker.processor, files).recheck
|
263
|
+
end
|
242
264
|
end
|
data/lib/brakeman/call_index.rb
CHANGED
@@ -67,7 +67,41 @@ class Brakeman::CallIndex
|
|
67
67
|
calls
|
68
68
|
end
|
69
69
|
|
70
|
-
|
70
|
+
def remove_template_indexes
|
71
|
+
@calls_by_method.each do |name, calls|
|
72
|
+
calls.delete_if do |call|
|
73
|
+
call[:location][0] == :template
|
74
|
+
end
|
75
|
+
|
76
|
+
@methods.delete name.to_s if calls.empty?
|
77
|
+
end
|
78
|
+
|
79
|
+
@calls_by_target.each do |name, calls|
|
80
|
+
calls.delete_if do |call|
|
81
|
+
call[:location][0] == :template
|
82
|
+
end
|
83
|
+
|
84
|
+
@targets.delete name.to_s if calls.empty?
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def remove_indexes_by_class classes
|
89
|
+
@calls_by_method.each do |name, calls|
|
90
|
+
calls.delete_if do |call|
|
91
|
+
call[:location][0] == :class and classes.include? call[:location][1]
|
92
|
+
end
|
93
|
+
|
94
|
+
@methods.delete name.to_s if calls.empty?
|
95
|
+
end
|
96
|
+
|
97
|
+
@calls_by_target.each do |name, calls|
|
98
|
+
calls.delete_if do |call|
|
99
|
+
call[:location][0] == :class and classes.include? call[:location][1]
|
100
|
+
end
|
101
|
+
|
102
|
+
@targets.delete name.to_s if calls.empty?
|
103
|
+
end
|
104
|
+
end
|
71
105
|
|
72
106
|
def index_calls calls
|
73
107
|
calls.each do |call|
|
@@ -78,6 +112,8 @@ class Brakeman::CallIndex
|
|
78
112
|
end
|
79
113
|
end
|
80
114
|
|
115
|
+
private
|
116
|
+
|
81
117
|
def find_chain options
|
82
118
|
target = options[:target] || options[:targets]
|
83
119
|
method = options[:method] || options[:methods]
|
data/lib/brakeman/checks.rb
CHANGED
@@ -46,6 +46,23 @@ class Brakeman::Checks
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
+
#Return a hash of arrays of new and fixed warnings
|
50
|
+
#
|
51
|
+
# diff = checks.diff old_checks
|
52
|
+
# diff[:fixed] # [...]
|
53
|
+
# diff[:new] # [...]
|
54
|
+
def diff other_checks
|
55
|
+
my_warnings = self.all_warnings
|
56
|
+
other_warnings = other_checks.all_warnings
|
57
|
+
|
58
|
+
diff = {}
|
59
|
+
|
60
|
+
diff[:fixed] = other_warnings - my_warnings
|
61
|
+
diff[:new] = my_warnings - other_warnings
|
62
|
+
|
63
|
+
diff
|
64
|
+
end
|
65
|
+
|
49
66
|
#Return an array of all warnings found.
|
50
67
|
def all_warnings
|
51
68
|
@warnings + @template_warnings + @controller_warnings + @model_warnings
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'sexp_processor'
|
2
2
|
require 'brakeman/processors/output_processor'
|
3
|
+
require 'brakeman/processors/lib/processor_helper'
|
3
4
|
require 'brakeman/warning'
|
4
5
|
require 'brakeman/util'
|
5
6
|
|
@@ -91,7 +92,10 @@ class Brakeman::BaseCheck < SexpProcessor
|
|
91
92
|
|
92
93
|
#Report a warning
|
93
94
|
def warn options
|
94
|
-
|
95
|
+
warning = Brakeman::Warning.new(options.merge({ :check => self.class.to_s }))
|
96
|
+
warning.file = file_for warning
|
97
|
+
|
98
|
+
@warnings << warning
|
95
99
|
end
|
96
100
|
|
97
101
|
#Run _exp_ through OutputProcessor to get a nice String.
|
@@ -14,22 +14,9 @@ require 'set'
|
|
14
14
|
class Brakeman::CheckCrossSiteScripting < Brakeman::BaseCheck
|
15
15
|
Brakeman::Checks.add self
|
16
16
|
|
17
|
-
#Ignore these methods and their arguments.
|
18
|
-
#It is assumed they will take care of escaping their output.
|
19
|
-
IGNORE_METHODS = Set.new([:button_to, :check_box, :escapeHTML, :escape_once,
|
20
|
-
:field_field, :fields_for, :h, :hidden_field,
|
21
|
-
:hidden_field, :hidden_field_tag, :image_tag, :label,
|
22
|
-
:link_to, :mail_to, :radio_button, :select,
|
23
|
-
:submit_tag, :text_area, :text_field,
|
24
|
-
:text_field_tag, :url_encode, :url_for,
|
25
|
-
:will_paginate] )
|
26
|
-
|
27
17
|
#Model methods which are known to be harmless
|
28
18
|
IGNORE_MODEL_METHODS = Set.new([:average, :count, :maximum, :minimum, :sum])
|
29
19
|
|
30
|
-
#Methods known to not escape their input
|
31
|
-
KNOWN_DANGEROUS = Set.new([:truncate, :concat])
|
32
|
-
|
33
20
|
MODEL_METHODS = Set.new([:all, :find, :first, :last, :new])
|
34
21
|
|
35
22
|
IGNORE_LIKE = /^link_to_|(_path|_tag|_url)$/
|
@@ -46,7 +33,14 @@ class Brakeman::CheckCrossSiteScripting < Brakeman::BaseCheck
|
|
46
33
|
|
47
34
|
#Run check
|
48
35
|
def run_check
|
49
|
-
|
36
|
+
@ignore_methods = Set.new([:button_to, :check_box, :escapeHTML, :escape_once,
|
37
|
+
:field_field, :fields_for, :h, :hidden_field,
|
38
|
+
:hidden_field, :hidden_field_tag, :image_tag, :label,
|
39
|
+
:link_to, :mail_to, :radio_button, :select,
|
40
|
+
:submit_tag, :text_area, :text_field,
|
41
|
+
:text_field_tag, :url_encode, :url_for,
|
42
|
+
:will_paginate] ).merge tracker.options[:safe_methods]
|
43
|
+
|
50
44
|
@models = tracker.models.keys
|
51
45
|
@inspect_arguments = tracker.options[:check_arguments]
|
52
46
|
|
@@ -54,10 +48,12 @@ class Brakeman::CheckCrossSiteScripting < Brakeman::BaseCheck
|
|
54
48
|
link_to_check.run_check
|
55
49
|
warnings.concat link_to_check.warnings unless link_to_check.warnings.empty?
|
56
50
|
|
51
|
+
@known_dangerous = Set.new([:truncate, :concat])
|
52
|
+
|
57
53
|
if version_between? "2.0.0", "3.0.5"
|
58
|
-
|
54
|
+
@known_dangerous << :auto_link
|
59
55
|
elsif version_between? "3.0.6", "3.0.99"
|
60
|
-
|
56
|
+
@ignore_methods << :auto_link
|
61
57
|
end
|
62
58
|
|
63
59
|
tracker.each_template do |name, template|
|
@@ -170,7 +166,7 @@ class Brakeman::CheckCrossSiteScripting < Brakeman::BaseCheck
|
|
170
166
|
if message and not duplicate? exp
|
171
167
|
add_result exp
|
172
168
|
|
173
|
-
if exp[1].nil? and
|
169
|
+
if exp[1].nil? and @known_dangerous.include? exp[2]
|
174
170
|
confidence = CONFIDENCE[:high]
|
175
171
|
else
|
176
172
|
confidence = CONFIDENCE[:low]
|
@@ -201,15 +197,15 @@ class Brakeman::CheckCrossSiteScripting < Brakeman::BaseCheck
|
|
201
197
|
args = exp[3]
|
202
198
|
|
203
199
|
#Ignore safe items
|
204
|
-
if (target.nil? and (
|
200
|
+
if (target.nil? and (@ignore_methods.include? method or method.to_s =~ IGNORE_LIKE)) or
|
205
201
|
(@matched == :model and IGNORE_MODEL_METHODS.include? method) or
|
206
202
|
(target == HAML_HELPERS and method == :html_escape) or
|
207
203
|
((target == URI or target == CGI) and method == :escape) or
|
208
204
|
(target == XML_HELPER and method == :escape_xml) or
|
209
|
-
(target == FORM_BUILDER and
|
205
|
+
(target == FORM_BUILDER and @ignore_methods.include? method) or
|
210
206
|
(method.to_s[-1,1] == "?")
|
211
207
|
|
212
|
-
exp[0] = :ignore
|
208
|
+
#exp[0] = :ignore #should not be necessary
|
213
209
|
@matched = false
|
214
210
|
elsif sexp? exp[1] and model_name? exp[1][1]
|
215
211
|
@matched = :model
|
@@ -269,9 +265,9 @@ end
|
|
269
265
|
|
270
266
|
#This _only_ checks calls to link_to
|
271
267
|
class Brakeman::CheckLinkTo < Brakeman::CheckCrossSiteScripting
|
272
|
-
IGNORE_METHODS = IGNORE_METHODS - [:link_to]
|
273
|
-
|
274
268
|
def run_check
|
269
|
+
@ignore_methods = []
|
270
|
+
@known_dangerous = []
|
275
271
|
#Ideally, I think this should also check to see if people are setting
|
276
272
|
#:escape => false
|
277
273
|
methods = tracker.find_call :target => false, :method => :link_to
|