brakeman-min 0.5.2 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (152) hide show
  1. data/CHANGES +529 -0
  2. data/README.md +74 -28
  3. data/bin/brakeman +60 -266
  4. data/lib/brakeman.rb +422 -0
  5. data/lib/brakeman/app_tree.rb +101 -0
  6. data/lib/brakeman/brakeman.rake +10 -0
  7. data/lib/brakeman/call_index.rb +215 -0
  8. data/lib/brakeman/checks.rb +180 -0
  9. data/lib/brakeman/checks/base_check.rb +538 -0
  10. data/lib/brakeman/checks/check_basic_auth.rb +89 -0
  11. data/lib/brakeman/checks/check_content_tag.rb +162 -0
  12. data/lib/brakeman/checks/check_cross_site_scripting.rb +334 -0
  13. data/lib/{checks → brakeman/checks}/check_default_routes.rb +13 -6
  14. data/lib/brakeman/checks/check_deserialize.rb +57 -0
  15. data/lib/brakeman/checks/check_digest_dos.rb +38 -0
  16. data/lib/brakeman/checks/check_escape_function.rb +21 -0
  17. data/lib/brakeman/checks/check_evaluation.rb +33 -0
  18. data/lib/brakeman/checks/check_execute.rb +98 -0
  19. data/lib/brakeman/checks/check_file_access.rb +62 -0
  20. data/lib/brakeman/checks/check_filter_skipping.rb +31 -0
  21. data/lib/brakeman/checks/check_forgery_setting.rb +54 -0
  22. data/lib/brakeman/checks/check_jruby_xml.rb +38 -0
  23. data/lib/brakeman/checks/check_json_parsing.rb +102 -0
  24. data/lib/brakeman/checks/check_link_to.rb +132 -0
  25. data/lib/brakeman/checks/check_link_to_href.rb +92 -0
  26. data/lib/{checks → brakeman/checks}/check_mail_to.rb +14 -13
  27. data/lib/brakeman/checks/check_mass_assignment.rb +143 -0
  28. data/lib/brakeman/checks/check_model_attr_accessible.rb +48 -0
  29. data/lib/brakeman/checks/check_model_attributes.rb +118 -0
  30. data/lib/brakeman/checks/check_model_serialize.rb +66 -0
  31. data/lib/{checks → brakeman/checks}/check_nested_attributes.rb +10 -6
  32. data/lib/brakeman/checks/check_quote_table_name.rb +40 -0
  33. data/lib/brakeman/checks/check_redirect.rb +177 -0
  34. data/lib/brakeman/checks/check_render.rb +62 -0
  35. data/lib/brakeman/checks/check_response_splitting.rb +21 -0
  36. data/lib/brakeman/checks/check_safe_buffer_manipulation.rb +31 -0
  37. data/lib/brakeman/checks/check_sanitize_methods.rb +54 -0
  38. data/lib/brakeman/checks/check_select_tag.rb +60 -0
  39. data/lib/brakeman/checks/check_select_vulnerability.rb +58 -0
  40. data/lib/brakeman/checks/check_send.rb +35 -0
  41. data/lib/brakeman/checks/check_send_file.rb +19 -0
  42. data/lib/brakeman/checks/check_session_settings.rb +145 -0
  43. data/lib/brakeman/checks/check_single_quotes.rb +101 -0
  44. data/lib/brakeman/checks/check_skip_before_filter.rb +62 -0
  45. data/lib/brakeman/checks/check_sql.rb +577 -0
  46. data/lib/brakeman/checks/check_strip_tags.rb +64 -0
  47. data/lib/brakeman/checks/check_symbol_dos.rb +67 -0
  48. data/lib/brakeman/checks/check_translate_bug.rb +45 -0
  49. data/lib/brakeman/checks/check_unsafe_reflection.rb +51 -0
  50. data/lib/brakeman/checks/check_validation_regex.rb +88 -0
  51. data/lib/brakeman/checks/check_without_protection.rb +64 -0
  52. data/lib/brakeman/checks/check_yaml_parsing.rb +121 -0
  53. data/lib/brakeman/differ.rb +66 -0
  54. data/lib/{format → brakeman/format}/style.css +28 -0
  55. data/lib/brakeman/options.rb +256 -0
  56. data/lib/brakeman/parsers/rails2_erubis.rb +6 -0
  57. data/lib/brakeman/parsers/rails2_xss_plugin_erubis.rb +48 -0
  58. data/lib/{scanner_erubis.rb → brakeman/parsers/rails3_erubis.rb} +8 -21
  59. data/lib/brakeman/processor.rb +102 -0
  60. data/lib/brakeman/processors/alias_processor.rb +780 -0
  61. data/lib/{processors → brakeman/processors}/base_processor.rb +90 -74
  62. data/lib/brakeman/processors/config_processor.rb +14 -0
  63. data/lib/brakeman/processors/controller_alias_processor.rb +334 -0
  64. data/lib/brakeman/processors/controller_processor.rb +265 -0
  65. data/lib/{processors → brakeman/processors}/erb_template_processor.rb +21 -19
  66. data/lib/brakeman/processors/erubis_template_processor.rb +96 -0
  67. data/lib/brakeman/processors/gem_processor.rb +59 -0
  68. data/lib/{processors → brakeman/processors}/haml_template_processor.rb +26 -21
  69. data/lib/brakeman/processors/lib/find_all_calls.rb +185 -0
  70. data/lib/{processors → brakeman/processors}/lib/find_call.rb +23 -28
  71. data/lib/brakeman/processors/lib/find_return_value.rb +134 -0
  72. data/lib/brakeman/processors/lib/processor_helper.rb +82 -0
  73. data/lib/{processors/config_processor.rb → brakeman/processors/lib/rails2_config_processor.rb} +32 -35
  74. data/lib/{processors → brakeman/processors}/lib/rails2_route_processor.rb +60 -52
  75. data/lib/brakeman/processors/lib/rails3_config_processor.rb +129 -0
  76. data/lib/brakeman/processors/lib/rails3_route_processor.rb +282 -0
  77. data/lib/{processors → brakeman/processors}/lib/render_helper.rb +54 -20
  78. data/lib/brakeman/processors/lib/route_helper.rb +62 -0
  79. data/lib/{processors → brakeman/processors}/library_processor.rb +24 -17
  80. data/lib/{processors → brakeman/processors}/model_processor.rb +46 -22
  81. data/lib/{processors → brakeman/processors}/output_processor.rb +34 -40
  82. data/lib/brakeman/processors/route_processor.rb +17 -0
  83. data/lib/brakeman/processors/slim_template_processor.rb +113 -0
  84. data/lib/brakeman/processors/template_alias_processor.rb +120 -0
  85. data/lib/{processors → brakeman/processors}/template_processor.rb +10 -7
  86. data/lib/brakeman/report.rb +68 -0
  87. data/lib/brakeman/report/ignore/config.rb +130 -0
  88. data/lib/brakeman/report/ignore/interactive.rb +311 -0
  89. data/lib/brakeman/report/initializers/faster_csv.rb +7 -0
  90. data/lib/brakeman/report/initializers/multi_json.rb +29 -0
  91. data/lib/brakeman/report/renderer.rb +24 -0
  92. data/lib/brakeman/report/report_base.rb +279 -0
  93. data/lib/brakeman/report/report_csv.rb +56 -0
  94. data/lib/brakeman/report/report_hash.rb +22 -0
  95. data/lib/brakeman/report/report_html.rb +203 -0
  96. data/lib/brakeman/report/report_json.rb +46 -0
  97. data/lib/brakeman/report/report_table.rb +109 -0
  98. data/lib/brakeman/report/report_tabs.rb +17 -0
  99. data/lib/brakeman/report/templates/controller_overview.html.erb +18 -0
  100. data/lib/brakeman/report/templates/controller_warnings.html.erb +17 -0
  101. data/lib/brakeman/report/templates/error_overview.html.erb +25 -0
  102. data/lib/brakeman/report/templates/header.html.erb +44 -0
  103. data/lib/brakeman/report/templates/ignored_warnings.html.erb +21 -0
  104. data/lib/brakeman/report/templates/model_warnings.html.erb +17 -0
  105. data/lib/brakeman/report/templates/overview.html.erb +34 -0
  106. data/lib/brakeman/report/templates/security_warnings.html.erb +19 -0
  107. data/lib/brakeman/report/templates/template_overview.html.erb +17 -0
  108. data/lib/brakeman/report/templates/view_warnings.html.erb +30 -0
  109. data/lib/brakeman/report/templates/warning_overview.html.erb +13 -0
  110. data/lib/brakeman/rescanner.rb +446 -0
  111. data/lib/brakeman/scanner.rb +362 -0
  112. data/lib/brakeman/tracker.rb +296 -0
  113. data/lib/brakeman/util.rb +413 -0
  114. data/lib/brakeman/version.rb +3 -0
  115. data/lib/brakeman/warning.rb +217 -0
  116. data/lib/brakeman/warning_codes.rb +68 -0
  117. data/lib/ruby_parser/bm_sexp.rb +562 -0
  118. data/lib/ruby_parser/bm_sexp_processor.rb +230 -0
  119. metadata +152 -66
  120. data/lib/checks.rb +0 -71
  121. data/lib/checks/base_check.rb +0 -357
  122. data/lib/checks/check_cross_site_scripting.rb +0 -336
  123. data/lib/checks/check_evaluation.rb +0 -27
  124. data/lib/checks/check_execute.rb +0 -110
  125. data/lib/checks/check_file_access.rb +0 -46
  126. data/lib/checks/check_forgery_setting.rb +0 -42
  127. data/lib/checks/check_mass_assignment.rb +0 -74
  128. data/lib/checks/check_model_attributes.rb +0 -36
  129. data/lib/checks/check_redirect.rb +0 -98
  130. data/lib/checks/check_render.rb +0 -65
  131. data/lib/checks/check_send_file.rb +0 -15
  132. data/lib/checks/check_session_settings.rb +0 -79
  133. data/lib/checks/check_sql.rb +0 -146
  134. data/lib/checks/check_validation_regex.rb +0 -60
  135. data/lib/processor.rb +0 -86
  136. data/lib/processors/alias_processor.rb +0 -384
  137. data/lib/processors/controller_alias_processor.rb +0 -237
  138. data/lib/processors/controller_processor.rb +0 -202
  139. data/lib/processors/erubis_template_processor.rb +0 -85
  140. data/lib/processors/lib/find_model_call.rb +0 -39
  141. data/lib/processors/lib/processor_helper.rb +0 -36
  142. data/lib/processors/lib/rails3_route_processor.rb +0 -184
  143. data/lib/processors/lib/route_helper.rb +0 -34
  144. data/lib/processors/params_processor.rb +0 -77
  145. data/lib/processors/route_processor.rb +0 -11
  146. data/lib/processors/template_alias_processor.rb +0 -86
  147. data/lib/report.rb +0 -680
  148. data/lib/scanner.rb +0 -227
  149. data/lib/tracker.rb +0 -144
  150. data/lib/util.rb +0 -141
  151. data/lib/version.rb +0 -1
  152. data/lib/warning.rb +0 -99
@@ -1,39 +0,0 @@
1
- require 'processors/lib/find_call'
2
-
3
- #This processor specifically looks for calls like
4
- # User.active.human.find(:all, :conditions => ...)
5
- class FindModelCall < FindCall
6
-
7
- #Passes +targets+ to FindCall
8
- def initialize targets
9
- super(targets, /^(find.*|first|last|all|count|sum|average|minumum|maximum|count_by_sql)$/, true)
10
- end
11
-
12
- #Matches entire method chain as a target. This differs from
13
- #FindCall#get_target, which only matches the first expression in the chain.
14
- def get_target exp
15
- if sexp? exp
16
- case exp.node_type
17
- when :ivar, :lvar, :const
18
- exp[1]
19
- when :true, :false
20
- exp[0]
21
- when :lit
22
- exp[1]
23
- when :colon2
24
- class_name exp
25
- when :call
26
- t = get_target(exp[1])
27
- if t and match(@find_targets, t)
28
- t
29
- else
30
- process exp
31
- end
32
- else
33
- process exp
34
- end
35
- else
36
- exp
37
- end
38
- end
39
- end
@@ -1,36 +0,0 @@
1
- #Contains a couple shared methods for Processors.
2
- module ProcessorHelper
3
-
4
- #Sets the current module.
5
- def process_module exp
6
- @current_module = class_name(exp[1]).to_s
7
- process exp[2]
8
- @current_module = nil
9
- exp
10
- end
11
-
12
- #Returns a class name as a Symbol.
13
- def class_name exp
14
- case exp
15
- when Sexp
16
- case exp.node_type
17
- when :const
18
- exp[1]
19
- when :colon2
20
- "#{class_name(exp[1])}::#{exp[2]}".to_sym
21
- when :colon3
22
- "::#{exp[1]}".to_sym
23
- when :call
24
- process exp
25
- else
26
- raise "Error: Cannot get class name from #{exp}"
27
- end
28
- when Symbol
29
- exp
30
- when nil
31
- nil
32
- else
33
- raise "Error: Cannot get class name from #{exp}"
34
- end
35
- end
36
- end
@@ -1,184 +0,0 @@
1
- #Processes the Sexp from routes.rb. Stores results in tracker.routes.
2
- #
3
- #Note that it is only interested in determining what methods on which
4
- #controllers are used as routes, not the generated URLs for routes.
5
- class RoutesProcessor < BaseProcessor
6
- include RouteHelper
7
-
8
- attr_reader :map, :nested, :current_controller
9
-
10
- def initialize tracker
11
- super
12
- @map = Sexp.new(:lvar, :map)
13
- @nested = nil #used for identifying nested targets
14
- @prefix = [] #Controller name prefix (a module name, usually)
15
- @current_controller = nil
16
- @with_options = nil #For use inside map.with_options
17
- end
18
-
19
- def process_routes exp
20
- process exp.dup
21
- end
22
-
23
- def process_call exp
24
- case exp[2]
25
- when :resources
26
- process_resources exp
27
- when :resource
28
- process_resource exp
29
- when :root
30
- process_root exp
31
- when :member
32
- process_default exp
33
- when :get, :put, :post, :delete
34
- process_verb exp
35
- when :match
36
- process_match exp
37
- else
38
- exp
39
- end
40
- end
41
-
42
- def process_iter exp
43
- case exp[1][2]
44
- when :namespace
45
- process_namespace exp
46
- when :resource
47
- process_resource_block exp
48
- when :resources
49
- process_resources_block exp
50
- when :scope
51
- process_scope_block exp
52
- else
53
- super
54
- end
55
- end
56
-
57
- def process_namespace exp
58
- name = exp[1][3][1][1]
59
- block = exp[3]
60
-
61
- @prefix << camelize(name)
62
-
63
- process block
64
-
65
- @prefix.pop
66
-
67
- exp
68
- end
69
-
70
- def process_root exp
71
- args = exp[3][1..-1]
72
-
73
- hash_iterate args[0] do |k, v|
74
- if symbol? k and k[1] == :to
75
- controller, action = extract_action v[1]
76
-
77
- self.current_controller = controller
78
- @tracker.routes[@current_controller] << action.to_sym
79
-
80
- break
81
- end
82
- end
83
-
84
- exp
85
- end
86
-
87
- def process_match exp
88
- args = exp[3][1..-1]
89
-
90
- hash_iterate args[0] do |k, v|
91
- if string? k and string? v
92
- controller, action = extract_action v[1]
93
-
94
- self.current_controller = controller
95
- @tracker.routes[@current_controller] << action.to_sym if action
96
- elsif symbol? k and k[1] == :action
97
- @tracker.routes[@current_controller] << v[1].to_sym
98
- end
99
- end
100
-
101
- exp
102
- end
103
-
104
- def process_verb exp
105
- args = exp[3][1..-1]
106
-
107
- if symbol? args[0]
108
- @tracker.routes[@current_controller] << args[0][1]
109
- elsif hash? args[1]
110
- hash_iterate args[1] do |k, v|
111
- if symbol? k and k[1] == :to and string? v
112
- controller, action = extract_action v[1]
113
-
114
- self.current_controller = controller
115
- @tracker.routes[@current_controller] << action.to_sym
116
- end
117
- end
118
- elsif string? args[0]
119
- route = args[0][1].split "/"
120
- if route.length != 2
121
- @tracker.routes[@current_controller] << route[0].to_sym
122
- else
123
- self.current_controller = route[0]
124
- @tracker.routes[@current_controller] << route[1].to_sym
125
- @current_controller = nil
126
- end
127
- else hash? args[0]
128
- hash_iterate args[0] do |k, v|
129
- if string? v
130
- controller, action = extract_action v[1]
131
-
132
- self.current_controller = controller
133
- @tracker.routes[@current_controller] << action.to_sym
134
- end
135
- end
136
- end
137
-
138
- exp
139
- end
140
-
141
- def process_resources exp
142
- if exp[3] and exp[3][2] and exp[3][2][0] == :hash
143
- #handle hash
144
- elsif exp[3][1..-1].all? { |s| symbol? s }
145
- exp[3][1..-1].each do |s|
146
- self.current_controller = s[1]
147
- add_resources_routes
148
- end
149
- end
150
-
151
- exp
152
- end
153
-
154
- def process_resource exp
155
- exp[3][1..-1].each do |s|
156
- self.current_controller = s[1]
157
- add_resource_routes
158
- end
159
-
160
- exp
161
- end
162
-
163
- def process_resources_block exp
164
- process_resources exp[1]
165
- process exp[3]
166
- exp
167
- end
168
-
169
- def process_resource_block exp
170
- process_resource exp[1]
171
- process exp[3]
172
- exp
173
- end
174
-
175
- def process_scope_block exp
176
- #How to deal with options?
177
- process exp[3]
178
- exp
179
- end
180
-
181
- def extract_action str
182
- str.split "#"
183
- end
184
- end
@@ -1,34 +0,0 @@
1
- module 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 default routes
25
- def add_resources_routes
26
- @tracker.routes[@current_controller].merge [:index, :new, :create, :show, :edit, :update, :destroy]
27
- end
28
-
29
-
30
- #Add default routes minus :index
31
- def add_resource_routes
32
- @tracker.routes[@current_controller].merge [:new, :create, :show, :edit, :update, :destroy]
33
- end
34
- end
@@ -1,77 +0,0 @@
1
- require 'rubygems'
2
- require 'sexp_processor'
3
- require 'set'
4
-
5
- #Looks for request parameters. Not used currently.
6
- class ParamsProcessor < SexpProcessor
7
- attr_reader :result
8
-
9
- def initialize
10
- super()
11
- self.strict = false
12
- self.auto_shift_type = false
13
- self.require_empty = false
14
- self.default_method = :process_default
15
- self.warn_on_default = false
16
- @result = []
17
- @matched = false
18
- @mark = false
19
- @watch_nodes = Set.new([:call, :iasgn, :lasgn, :gasgn, :cvasgn, :return, :attrasgn])
20
- @params = Sexp.new(:call, nil, :params, Sexp.new(:arglist))
21
- end
22
-
23
- def process_default exp
24
- if @watch_nodes.include?(exp.node_type) and not @mark
25
- @mark = true
26
- @matched = false
27
- process_these exp[1..-1]
28
- if @matched
29
- @result << exp
30
- @matched = false
31
- end
32
- @mark = false
33
- else
34
- process_these exp[1..-1]
35
- end
36
-
37
- exp
38
- end
39
-
40
- def process_these exp
41
- exp.each do |e|
42
- if sexp? e and not e.empty?
43
- process e
44
- end
45
- end
46
- end
47
-
48
- def process_call exp
49
- if @mark
50
- actually_process_call exp
51
- else
52
- @mark = true
53
- actually_process_call exp
54
- if @matched
55
- @result << exp
56
- end
57
- @mark = @matched = false
58
- end
59
-
60
- exp
61
- end
62
-
63
- def actually_process_call exp
64
- process exp[1]
65
- process exp[3]
66
- if exp[1] == @params or exp == @params
67
- @matched = true
68
- end
69
- end
70
-
71
- #Don't really care about condition
72
- def process_if exp
73
- process_these exp[2..-1]
74
- exp
75
- end
76
-
77
- end
@@ -1,11 +0,0 @@
1
- require 'processors/base_processor'
2
- require 'processors/alias_processor'
3
- require 'processors/lib/route_helper'
4
- require 'util'
5
- require 'set'
6
-
7
- if OPTIONS[:rails3]
8
- require 'processors/lib/rails3_route_processor'
9
- else
10
- require 'processors/lib/rails2_route_processor'
11
- end
@@ -1,86 +0,0 @@
1
- require 'set'
2
- require 'processors/alias_processor'
3
- require 'processors/lib/render_helper'
4
-
5
- #Processes aliasing in templates.
6
- #Handles calls to +render+.
7
- class TemplateAliasProcessor < AliasProcessor
8
- include RenderHelper
9
-
10
- FORM_METHODS = Set.new([:form_for, :remote_form_for, :form_remote_for])
11
-
12
- def initialize tracker, template
13
- super()
14
- @tracker = tracker
15
- @template = template
16
- end
17
-
18
- #Process template
19
- def process_template name, args
20
- super name, args, "Template:#{@template[:name]}"
21
- end
22
-
23
- #Determine template name
24
- def template_name name
25
- unless name.to_s.include? "/"
26
- name = "#{@template[:name].to_s.match(/^(.*\/).*$/)[1]}#{name}"
27
- end
28
- name
29
- end
30
-
31
- #Looks for form methods and iterating over collections of Models
32
- def process_call_with_block exp
33
- process_default exp
34
-
35
- call = exp[1]
36
- target = call[1]
37
- method = call[2]
38
- args = exp[2]
39
- block = exp[3]
40
-
41
- #Check for e.g. Model.find.each do ... end
42
- if method == :each and args and block and model = get_model_target(target)
43
- if sexp? args and args.node_type == :lasgn
44
- if model == target[1]
45
- env[Sexp.new(:lvar, args[1])] = Sexp.new(:call, model, :new, Sexp.new(:arglist))
46
- else
47
- env[Sexp.new(:lvar, args[1])] = Sexp.new(:call, Sexp.new(:const, Tracker::UNKNOWN_MODEL), :new, Sexp.new(:arglist))
48
- end
49
-
50
- process block if sexp? block
51
- end
52
- elsif FORM_METHODS.include? method
53
- if sexp? args and args.node_type == :lasgn
54
- env[Sexp.new(:lvar, args[1])] = Sexp.new(:call, Sexp.new(:const, :FormBuilder), :new, Sexp.new(:arglist))
55
-
56
- process block if sexp? block
57
- end
58
- end
59
-
60
- exp
61
- end
62
-
63
- alias process_iter process_call_with_block
64
-
65
- #Checks if +exp+ is a call to Model.all or Model.find*
66
- def get_model_target exp
67
- if call? exp
68
- target = exp[1]
69
-
70
- if exp[2] == :all or exp[2].to_s[0,4] == "find"
71
- models = Set.new @tracker.models.keys
72
-
73
- begin
74
- name = class_name target
75
- return target if models.include?(name)
76
- rescue StandardError
77
- end
78
-
79
- end
80
-
81
- return get_model_target(target)
82
- end
83
-
84
- false
85
- end
86
- end