brakeman-lib 3.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.
- checksums.yaml +7 -0
- data/CHANGES +872 -0
- data/FEATURES +16 -0
- data/README.md +169 -0
- data/WARNING_TYPES +95 -0
- data/bin/brakeman +89 -0
- data/lib/brakeman.rb +495 -0
- data/lib/brakeman/app_tree.rb +161 -0
- data/lib/brakeman/brakeman.rake +17 -0
- data/lib/brakeman/call_index.rb +219 -0
- data/lib/brakeman/checks.rb +191 -0
- data/lib/brakeman/checks/base_check.rb +518 -0
- data/lib/brakeman/checks/check_basic_auth.rb +88 -0
- data/lib/brakeman/checks/check_basic_auth_timing_attack.rb +33 -0
- data/lib/brakeman/checks/check_content_tag.rb +160 -0
- data/lib/brakeman/checks/check_create_with.rb +75 -0
- data/lib/brakeman/checks/check_cross_site_scripting.rb +385 -0
- data/lib/brakeman/checks/check_default_routes.rb +86 -0
- data/lib/brakeman/checks/check_deserialize.rb +57 -0
- data/lib/brakeman/checks/check_detailed_exceptions.rb +55 -0
- data/lib/brakeman/checks/check_digest_dos.rb +38 -0
- data/lib/brakeman/checks/check_dynamic_finders.rb +49 -0
- data/lib/brakeman/checks/check_escape_function.rb +21 -0
- data/lib/brakeman/checks/check_evaluation.rb +36 -0
- data/lib/brakeman/checks/check_execute.rb +167 -0
- data/lib/brakeman/checks/check_file_access.rb +63 -0
- data/lib/brakeman/checks/check_file_disclosure.rb +35 -0
- data/lib/brakeman/checks/check_filter_skipping.rb +31 -0
- data/lib/brakeman/checks/check_forgery_setting.rb +74 -0
- data/lib/brakeman/checks/check_header_dos.rb +31 -0
- data/lib/brakeman/checks/check_i18n_xss.rb +48 -0
- data/lib/brakeman/checks/check_jruby_xml.rb +38 -0
- data/lib/brakeman/checks/check_json_encoding.rb +47 -0
- data/lib/brakeman/checks/check_json_parsing.rb +107 -0
- data/lib/brakeman/checks/check_link_to.rb +132 -0
- data/lib/brakeman/checks/check_link_to_href.rb +115 -0
- data/lib/brakeman/checks/check_mail_to.rb +49 -0
- data/lib/brakeman/checks/check_mass_assignment.rb +198 -0
- data/lib/brakeman/checks/check_mime_type_dos.rb +39 -0
- data/lib/brakeman/checks/check_model_attr_accessible.rb +55 -0
- data/lib/brakeman/checks/check_model_attributes.rb +119 -0
- data/lib/brakeman/checks/check_model_serialize.rb +67 -0
- data/lib/brakeman/checks/check_nested_attributes.rb +38 -0
- data/lib/brakeman/checks/check_nested_attributes_bypass.rb +58 -0
- data/lib/brakeman/checks/check_number_to_currency.rb +74 -0
- data/lib/brakeman/checks/check_quote_table_name.rb +40 -0
- data/lib/brakeman/checks/check_redirect.rb +215 -0
- data/lib/brakeman/checks/check_regex_dos.rb +69 -0
- data/lib/brakeman/checks/check_render.rb +92 -0
- data/lib/brakeman/checks/check_render_dos.rb +37 -0
- data/lib/brakeman/checks/check_render_inline.rb +54 -0
- data/lib/brakeman/checks/check_response_splitting.rb +21 -0
- data/lib/brakeman/checks/check_route_dos.rb +42 -0
- data/lib/brakeman/checks/check_safe_buffer_manipulation.rb +31 -0
- data/lib/brakeman/checks/check_sanitize_methods.rb +79 -0
- data/lib/brakeman/checks/check_secrets.rb +40 -0
- data/lib/brakeman/checks/check_select_tag.rb +60 -0
- data/lib/brakeman/checks/check_select_vulnerability.rb +60 -0
- data/lib/brakeman/checks/check_send.rb +48 -0
- data/lib/brakeman/checks/check_send_file.rb +19 -0
- data/lib/brakeman/checks/check_session_manipulation.rb +36 -0
- data/lib/brakeman/checks/check_session_settings.rb +170 -0
- data/lib/brakeman/checks/check_simple_format.rb +59 -0
- data/lib/brakeman/checks/check_single_quotes.rb +101 -0
- data/lib/brakeman/checks/check_skip_before_filter.rb +60 -0
- data/lib/brakeman/checks/check_sql.rb +660 -0
- data/lib/brakeman/checks/check_sql_cves.rb +101 -0
- data/lib/brakeman/checks/check_ssl_verify.rb +49 -0
- data/lib/brakeman/checks/check_strip_tags.rb +89 -0
- data/lib/brakeman/checks/check_symbol_dos.rb +64 -0
- data/lib/brakeman/checks/check_symbol_dos_cve.rb +30 -0
- data/lib/brakeman/checks/check_translate_bug.rb +45 -0
- data/lib/brakeman/checks/check_unsafe_reflection.rb +51 -0
- data/lib/brakeman/checks/check_unscoped_find.rb +41 -0
- data/lib/brakeman/checks/check_validation_regex.rb +116 -0
- data/lib/brakeman/checks/check_weak_hash.rb +151 -0
- data/lib/brakeman/checks/check_without_protection.rb +80 -0
- data/lib/brakeman/checks/check_xml_dos.rb +51 -0
- data/lib/brakeman/checks/check_yaml_parsing.rb +121 -0
- data/lib/brakeman/differ.rb +66 -0
- data/lib/brakeman/file_parser.rb +50 -0
- data/lib/brakeman/format/style.css +133 -0
- data/lib/brakeman/options.rb +301 -0
- data/lib/brakeman/parsers/rails2_erubis.rb +6 -0
- data/lib/brakeman/parsers/rails2_xss_plugin_erubis.rb +48 -0
- data/lib/brakeman/parsers/rails3_erubis.rb +74 -0
- data/lib/brakeman/parsers/template_parser.rb +89 -0
- data/lib/brakeman/processor.rb +102 -0
- data/lib/brakeman/processors/alias_processor.rb +1013 -0
- data/lib/brakeman/processors/base_processor.rb +277 -0
- data/lib/brakeman/processors/config_processor.rb +14 -0
- data/lib/brakeman/processors/controller_alias_processor.rb +273 -0
- data/lib/brakeman/processors/controller_processor.rb +326 -0
- data/lib/brakeman/processors/erb_template_processor.rb +80 -0
- data/lib/brakeman/processors/erubis_template_processor.rb +104 -0
- data/lib/brakeman/processors/gem_processor.rb +57 -0
- data/lib/brakeman/processors/haml_template_processor.rb +190 -0
- data/lib/brakeman/processors/lib/basic_processor.rb +37 -0
- data/lib/brakeman/processors/lib/find_all_calls.rb +223 -0
- data/lib/brakeman/processors/lib/find_call.rb +183 -0
- data/lib/brakeman/processors/lib/find_return_value.rb +134 -0
- data/lib/brakeman/processors/lib/processor_helper.rb +75 -0
- data/lib/brakeman/processors/lib/rails2_config_processor.rb +145 -0
- data/lib/brakeman/processors/lib/rails2_route_processor.rb +313 -0
- data/lib/brakeman/processors/lib/rails3_config_processor.rb +132 -0
- data/lib/brakeman/processors/lib/rails3_route_processor.rb +308 -0
- data/lib/brakeman/processors/lib/render_helper.rb +181 -0
- data/lib/brakeman/processors/lib/render_path.rb +107 -0
- data/lib/brakeman/processors/lib/route_helper.rb +68 -0
- data/lib/brakeman/processors/lib/safe_call_helper.rb +16 -0
- data/lib/brakeman/processors/library_processor.rb +119 -0
- data/lib/brakeman/processors/model_processor.rb +191 -0
- data/lib/brakeman/processors/output_processor.rb +171 -0
- data/lib/brakeman/processors/route_processor.rb +17 -0
- data/lib/brakeman/processors/slim_template_processor.rb +107 -0
- data/lib/brakeman/processors/template_alias_processor.rb +116 -0
- data/lib/brakeman/processors/template_processor.rb +74 -0
- data/lib/brakeman/report.rb +78 -0
- data/lib/brakeman/report/config/remediation.yml +71 -0
- data/lib/brakeman/report/ignore/config.rb +135 -0
- data/lib/brakeman/report/ignore/interactive.rb +311 -0
- data/lib/brakeman/report/renderer.rb +24 -0
- data/lib/brakeman/report/report_base.rb +286 -0
- data/lib/brakeman/report/report_codeclimate.rb +70 -0
- data/lib/brakeman/report/report_csv.rb +55 -0
- data/lib/brakeman/report/report_hash.rb +23 -0
- data/lib/brakeman/report/report_html.rb +216 -0
- data/lib/brakeman/report/report_json.rb +42 -0
- data/lib/brakeman/report/report_markdown.rb +156 -0
- data/lib/brakeman/report/report_table.rb +107 -0
- data/lib/brakeman/report/report_tabs.rb +17 -0
- data/lib/brakeman/report/templates/controller_overview.html.erb +22 -0
- data/lib/brakeman/report/templates/controller_warnings.html.erb +21 -0
- data/lib/brakeman/report/templates/error_overview.html.erb +29 -0
- data/lib/brakeman/report/templates/header.html.erb +58 -0
- data/lib/brakeman/report/templates/ignored_warnings.html.erb +25 -0
- data/lib/brakeman/report/templates/model_warnings.html.erb +21 -0
- data/lib/brakeman/report/templates/overview.html.erb +38 -0
- data/lib/brakeman/report/templates/security_warnings.html.erb +23 -0
- data/lib/brakeman/report/templates/template_overview.html.erb +21 -0
- data/lib/brakeman/report/templates/view_warnings.html.erb +34 -0
- data/lib/brakeman/report/templates/warning_overview.html.erb +17 -0
- data/lib/brakeman/rescanner.rb +483 -0
- data/lib/brakeman/scanner.rb +317 -0
- data/lib/brakeman/tracker.rb +347 -0
- data/lib/brakeman/tracker/collection.rb +93 -0
- data/lib/brakeman/tracker/config.rb +101 -0
- data/lib/brakeman/tracker/constants.rb +101 -0
- data/lib/brakeman/tracker/controller.rb +161 -0
- data/lib/brakeman/tracker/library.rb +17 -0
- data/lib/brakeman/tracker/model.rb +90 -0
- data/lib/brakeman/tracker/template.rb +33 -0
- data/lib/brakeman/util.rb +481 -0
- data/lib/brakeman/version.rb +3 -0
- data/lib/brakeman/warning.rb +255 -0
- data/lib/brakeman/warning_codes.rb +111 -0
- data/lib/ruby_parser/bm_sexp.rb +610 -0
- data/lib/ruby_parser/bm_sexp_processor.rb +116 -0
- metadata +362 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
require 'digest/sha1'
|
|
2
|
+
|
|
3
|
+
#Processes a call to render() in a controller or template
|
|
4
|
+
module Brakeman::RenderHelper
|
|
5
|
+
|
|
6
|
+
#Process s(:render, TYPE, OPTION?, OPTIONS)
|
|
7
|
+
def process_render exp
|
|
8
|
+
process_default exp
|
|
9
|
+
@rendered = true
|
|
10
|
+
case exp.render_type
|
|
11
|
+
when :action, :template
|
|
12
|
+
process_action exp[2][1], exp[3], exp.line
|
|
13
|
+
when :default
|
|
14
|
+
begin
|
|
15
|
+
process_template template_name, exp[3], nil, exp.line
|
|
16
|
+
rescue ArgumentError
|
|
17
|
+
Brakeman.debug "Problem processing render: #{exp}"
|
|
18
|
+
end
|
|
19
|
+
when :partial, :layout
|
|
20
|
+
process_partial exp[2], exp[3], exp.line
|
|
21
|
+
when :nothing
|
|
22
|
+
end
|
|
23
|
+
exp
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
#Processes layout
|
|
27
|
+
def process_layout name = nil
|
|
28
|
+
if name.nil? and defined? layout_name
|
|
29
|
+
name = layout_name
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
return unless name
|
|
33
|
+
|
|
34
|
+
process_template name, nil, nil, nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
#Determines file name for partial and then processes it
|
|
38
|
+
def process_partial name, args, line
|
|
39
|
+
if name == "" or !(string? name or symbol? name)
|
|
40
|
+
return
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
names = name.value.to_s.split("/")
|
|
44
|
+
names[-1] = "_" + names[-1]
|
|
45
|
+
process_template template_name(names.join("/")), args, nil, line
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
#Processes a given action
|
|
49
|
+
def process_action name, args, line
|
|
50
|
+
if name.is_a? String or name.is_a? Symbol
|
|
51
|
+
process_template template_name(name), args, nil, line
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
#Processes a template, adding any instance variables
|
|
56
|
+
#to its environment.
|
|
57
|
+
def process_template name, args, called_from = nil, *_
|
|
58
|
+
|
|
59
|
+
Brakeman.debug "Rendering #{name} (#{called_from})"
|
|
60
|
+
#Get scanned source for this template
|
|
61
|
+
name = name.to_s.gsub(/^\//, "")
|
|
62
|
+
template = @tracker.templates[name.to_sym]
|
|
63
|
+
unless template
|
|
64
|
+
Brakeman.debug "[Notice] No such template: #{name}"
|
|
65
|
+
return
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
template_env = only_ivars(:include_request_vars)
|
|
69
|
+
|
|
70
|
+
#Hash the environment and the source of the template to avoid
|
|
71
|
+
#pointlessly processing templates, which can become prohibitively
|
|
72
|
+
#expensive in terms of time and memory.
|
|
73
|
+
digest = Digest::SHA1.new.update(template_env.instance_variable_get(:@env).to_a.sort.to_s << name).to_s.to_sym
|
|
74
|
+
|
|
75
|
+
if @tracker.template_cache.include? digest
|
|
76
|
+
#Already processed this template with identical environment
|
|
77
|
+
return
|
|
78
|
+
else
|
|
79
|
+
@tracker.template_cache << digest
|
|
80
|
+
|
|
81
|
+
options = get_options args
|
|
82
|
+
|
|
83
|
+
#Process layout
|
|
84
|
+
if string? options[:layout]
|
|
85
|
+
process_template "layouts/#{options[:layout][1]}", nil, nil, nil
|
|
86
|
+
elsif node_type? options[:layout], :false
|
|
87
|
+
#nothing
|
|
88
|
+
elsif not template.name.to_s.match(/[^\/_][^\/]+$/)
|
|
89
|
+
#Don't do this for partials
|
|
90
|
+
|
|
91
|
+
process_layout
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
if hash? options[:locals]
|
|
95
|
+
hash_iterate options[:locals] do |key, value|
|
|
96
|
+
template_env[Sexp.new(:call, nil, key.value)] = value
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
if options[:collection]
|
|
101
|
+
|
|
102
|
+
#The collection name is the name of the partial without the leading
|
|
103
|
+
#underscore.
|
|
104
|
+
variable = template.name.to_s.match(/[^\/_][^\/]+$/)[0].to_sym
|
|
105
|
+
|
|
106
|
+
#Unless the :as => :variable_name option is used
|
|
107
|
+
if options[:as]
|
|
108
|
+
if string? options[:as] or symbol? options[:as]
|
|
109
|
+
variable = options[:as].value.to_sym
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
collection = get_class_target(options[:collection]) || Brakeman::Tracker::UNKNOWN_MODEL
|
|
114
|
+
|
|
115
|
+
template_env[Sexp.new(:call, nil, variable)] = Sexp.new(:call, Sexp.new(:const, collection), :new)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
#Set original_line for values so it is clear
|
|
119
|
+
#that values came from another file
|
|
120
|
+
template_env.all.each do |var, value|
|
|
121
|
+
unless value.original_line
|
|
122
|
+
#TODO: This has been broken for a while now and no one noticed
|
|
123
|
+
#so maybe we can skip it
|
|
124
|
+
value.original_line = value.line
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
#Run source through AliasProcessor with instance variables from the
|
|
129
|
+
#current environment.
|
|
130
|
+
#TODO: Add in :locals => { ... } to environment
|
|
131
|
+
src = Brakeman::TemplateAliasProcessor.new(@tracker, template, called_from).process_safely(template.src, template_env)
|
|
132
|
+
|
|
133
|
+
digest = Digest::SHA1.new.update(name + src.to_s).to_s.to_sym
|
|
134
|
+
|
|
135
|
+
if @tracker.template_cache.include? digest
|
|
136
|
+
return
|
|
137
|
+
else
|
|
138
|
+
@tracker.template_cache << digest
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
#Run alias-processed src through the template processor to pull out
|
|
142
|
+
#information and outputs.
|
|
143
|
+
#This information will be stored in tracker.templates, but with a name
|
|
144
|
+
#specifying this particular route. The original source should remain
|
|
145
|
+
#pristine (so it can be processed within other environments).
|
|
146
|
+
@tracker.processor.process_template name, src, template.type, called_from
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
#Override to process name, such as adding the controller name.
|
|
151
|
+
def template_name name
|
|
152
|
+
raise "RenderHelper#template_name should be overridden."
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
#Turn options Sexp into hash
|
|
156
|
+
def get_options args
|
|
157
|
+
options = {}
|
|
158
|
+
return options unless hash? args
|
|
159
|
+
|
|
160
|
+
hash_iterate args do |key, value|
|
|
161
|
+
if symbol? key
|
|
162
|
+
options[key.value] = value
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
options
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def get_class_target sexp
|
|
170
|
+
if call? sexp
|
|
171
|
+
get_class_target sexp.target
|
|
172
|
+
else
|
|
173
|
+
klass = class_name sexp
|
|
174
|
+
if klass.is_a? Symbol
|
|
175
|
+
klass
|
|
176
|
+
else
|
|
177
|
+
nil
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
module Brakeman
|
|
2
|
+
class RenderPath
|
|
3
|
+
attr_reader :path
|
|
4
|
+
|
|
5
|
+
def initialize
|
|
6
|
+
@path = []
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def add_controller_render controller_name, method_name, line, file
|
|
10
|
+
method_name ||= ""
|
|
11
|
+
|
|
12
|
+
@path << { :type => :controller,
|
|
13
|
+
:class => controller_name.to_sym,
|
|
14
|
+
:method => method_name.to_sym,
|
|
15
|
+
:line => line,
|
|
16
|
+
:file => file
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
self
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def add_template_render template_name, line, file
|
|
23
|
+
@path << { :type => :template,
|
|
24
|
+
:name => template_name.to_sym,
|
|
25
|
+
:line => line,
|
|
26
|
+
:file => file
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
self
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def include_template? name
|
|
33
|
+
name = name.to_sym
|
|
34
|
+
|
|
35
|
+
@path.any? do |loc|
|
|
36
|
+
loc[:type] == :template and loc[:name] == name
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def include_controller? klass
|
|
41
|
+
klass = klass.to_sym
|
|
42
|
+
|
|
43
|
+
@path.any? do |loc|
|
|
44
|
+
loc[:type] == :controller and loc[:class] == klass
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def include_any_method? method_names
|
|
49
|
+
names = method_names.map(&:to_sym)
|
|
50
|
+
|
|
51
|
+
@path.any? do |loc|
|
|
52
|
+
loc[:type] == :controller and names.include? loc[:method]
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def rendered_from_controller?
|
|
57
|
+
@path.any? do |loc|
|
|
58
|
+
loc[:type] == :controller
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def each &block
|
|
63
|
+
@path.each(&block)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def join *args
|
|
67
|
+
self.to_a.join(*args)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def length
|
|
71
|
+
@path.length
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def to_a
|
|
75
|
+
@path.map do |loc|
|
|
76
|
+
case loc[:type]
|
|
77
|
+
when :template
|
|
78
|
+
"Template:#{loc[:name]}"
|
|
79
|
+
when :controller
|
|
80
|
+
"#{loc[:class]}##{loc[:method]}"
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def last
|
|
86
|
+
self.to_a.last
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def to_s
|
|
90
|
+
self.to_a.to_s
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def to_sym
|
|
94
|
+
self.to_s.to_sym
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def to_json *args
|
|
98
|
+
require 'json'
|
|
99
|
+
JSON.generate(@path)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def initialize_copy original
|
|
103
|
+
@path = original.path.dup
|
|
104
|
+
self
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
module Brakeman::RouteHelper
|
|
2
|
+
#Manage Controller prefixes
|
|
3
|
+
#@prefix is an Array, but this method returns a string
|
|
4
|
+
#suitable for prefixing onto a controller name.
|
|
5
|
+
def prefix
|
|
6
|
+
if @prefix.length > 0
|
|
7
|
+
@prefix.join("::") << "::"
|
|
8
|
+
else
|
|
9
|
+
''
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
#Sets the controller name to a proper class name.
|
|
14
|
+
#For example
|
|
15
|
+
# self.current_controller = :session
|
|
16
|
+
# @controller == :SessionController #true
|
|
17
|
+
#
|
|
18
|
+
#Also prepends the prefix if there is one set.
|
|
19
|
+
def current_controller= name
|
|
20
|
+
@current_controller = (prefix + camelize(name) + "Controller").to_sym
|
|
21
|
+
@tracker.routes[@current_controller] ||= Set.new
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
#Add route to controller. If a controller is specified,
|
|
25
|
+
#the current controller will be set to that controller.
|
|
26
|
+
#If no controller is specified, uses current controller value.
|
|
27
|
+
def add_route route, controller = nil
|
|
28
|
+
if node_type? route, :str, :lit
|
|
29
|
+
route = route.value
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
return unless route.is_a? String or route.is_a? Symbol
|
|
33
|
+
|
|
34
|
+
if route.is_a? String and controller.nil? and route.include? ":controller"
|
|
35
|
+
controller = ":controller"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
route = route.to_sym
|
|
39
|
+
|
|
40
|
+
if controller
|
|
41
|
+
self.current_controller = controller
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
routes = @tracker.routes[@current_controller]
|
|
45
|
+
|
|
46
|
+
if routes and not routes.include? :allow_all_actions
|
|
47
|
+
routes << route
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
#Add default routes
|
|
52
|
+
def add_resources_routes
|
|
53
|
+
existing_routes = @tracker.routes[@current_controller]
|
|
54
|
+
|
|
55
|
+
unless existing_routes.is_a? Array and existing_routes.first == :allow_all_actions
|
|
56
|
+
existing_routes.merge [:index, :new, :create, :show, :edit, :update, :destroy]
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
#Add default routes minus :index
|
|
61
|
+
def add_resource_routes
|
|
62
|
+
existing_routes = @tracker.routes[@current_controller]
|
|
63
|
+
|
|
64
|
+
unless existing_routes.is_a? Array and existing_routes.first == :allow_all_actions
|
|
65
|
+
existing_routes.merge [:new, :create, :show, :edit, :update, :destroy]
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Brakeman
|
|
2
|
+
module SafeCallHelper
|
|
3
|
+
[[:process_safe_call, :process_call],
|
|
4
|
+
[:process_safe_attrasgn, :process_attrasgn],
|
|
5
|
+
[:process_safe_op_asgn, :process_op_asgn],
|
|
6
|
+
[:process_safe_op_asgn2, :process_op_asgn2]].each do |call, replacement|
|
|
7
|
+
define_method(call) do |exp|
|
|
8
|
+
if self.respond_to? replacement
|
|
9
|
+
self.send(replacement, exp)
|
|
10
|
+
else
|
|
11
|
+
process_default exp
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
require 'brakeman/processors/base_processor'
|
|
2
|
+
require 'brakeman/processors/alias_processor'
|
|
3
|
+
require 'brakeman/tracker/library'
|
|
4
|
+
|
|
5
|
+
#Process generic library and stores it in Tracker.libs
|
|
6
|
+
class Brakeman::LibraryProcessor < Brakeman::BaseProcessor
|
|
7
|
+
|
|
8
|
+
def initialize tracker
|
|
9
|
+
super
|
|
10
|
+
@file_name = nil
|
|
11
|
+
@alias_processor = Brakeman::AliasProcessor.new tracker
|
|
12
|
+
@current_module = nil
|
|
13
|
+
@current_class = nil
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def process_library src, file_name = nil
|
|
17
|
+
@file_name = file_name
|
|
18
|
+
process src
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def process_class exp
|
|
22
|
+
name = class_name(exp.class_name)
|
|
23
|
+
parent = class_name exp.parent_name
|
|
24
|
+
|
|
25
|
+
if @current_class
|
|
26
|
+
outer_class = @current_class
|
|
27
|
+
name = (outer_class.name.to_s + "::" + name.to_s).to_sym
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
if @current_module
|
|
31
|
+
name = (@current_module.name.to_s + "::" + name.to_s).to_sym
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
if @tracker.libs[name]
|
|
35
|
+
@current_class = @tracker.libs[name]
|
|
36
|
+
@current_class.add_file @file_name, exp
|
|
37
|
+
else
|
|
38
|
+
@current_class = Brakeman::Library.new name, parent, @file_name, exp, @tracker
|
|
39
|
+
@tracker.libs[name] = @current_class
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
exp.body = process_all! exp.body
|
|
43
|
+
|
|
44
|
+
if outer_class
|
|
45
|
+
@current_class = outer_class
|
|
46
|
+
else
|
|
47
|
+
@current_class = nil
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
exp
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def process_module exp
|
|
54
|
+
name = class_name(exp.module_name)
|
|
55
|
+
|
|
56
|
+
if @current_module
|
|
57
|
+
outer_module = @current_module
|
|
58
|
+
name = (outer_module.name.to_s + "::" + name.to_s).to_sym
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
if @current_class
|
|
62
|
+
name = (@current_class.name.to_s + "::" + name.to_s).to_sym
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
if @tracker.libs[name]
|
|
66
|
+
@current_module = @tracker.libs[name]
|
|
67
|
+
@current_module.add_file @file_name, exp
|
|
68
|
+
else
|
|
69
|
+
@current_module = Brakeman::Library.new name, nil, @file_name, exp, @tracker
|
|
70
|
+
@tracker.libs[name] = @current_module
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
exp.body = process_all! exp.body
|
|
74
|
+
|
|
75
|
+
if outer_module
|
|
76
|
+
@current_module = outer_module
|
|
77
|
+
else
|
|
78
|
+
@current_module = nil
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
exp
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def process_defn exp
|
|
85
|
+
exp = @alias_processor.process exp
|
|
86
|
+
|
|
87
|
+
if @current_class
|
|
88
|
+
exp.body = process_all! exp.body
|
|
89
|
+
@current_class.add_method :public, exp.method_name, exp, @file_name
|
|
90
|
+
elsif @current_module
|
|
91
|
+
exp.body = process_all! exp.body
|
|
92
|
+
@current_module.add_method :public, exp.method_name, exp, @file_name
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
exp
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def process_defs exp
|
|
99
|
+
exp = @alias_processor.process exp
|
|
100
|
+
|
|
101
|
+
if @current_class
|
|
102
|
+
exp.body = process_all! exp.body
|
|
103
|
+
@current_class.add_method :public, exp.method_name, exp, @file_name
|
|
104
|
+
elsif @current_module
|
|
105
|
+
exp.body = process_all! exp.body
|
|
106
|
+
@current_module.add_method :public, exp.method_name, exp, @file_name
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
exp
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def process_call exp
|
|
113
|
+
if process_call_defn? exp
|
|
114
|
+
exp
|
|
115
|
+
else
|
|
116
|
+
process_default exp
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|