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
@@ -0,0 +1,66 @@
1
+ # extracting the diff logic to it's own class for consistency. Currently handles
2
+ # an array of Brakeman::Warnings or plain hash representations.
3
+ class Brakeman::Differ
4
+ DEFAULT_HASH = {:new => [], :fixed => []}
5
+ OLD_WARNING_KEYS = [:warning_type, :location, :code, :message, :file, :link, :confidence, :user_input]
6
+ attr_reader :old_warnings, :new_warnings
7
+
8
+ def initialize new_warnings, old_warnings
9
+ @new_warnings = new_warnings
10
+ @old_warnings = old_warnings
11
+ end
12
+
13
+ def diff
14
+ # get the type of elements
15
+ return DEFAULT_HASH if @new_warnings.empty?
16
+
17
+ warnings = {}
18
+ warnings[:new] = @new_warnings - @old_warnings
19
+ warnings[:fixed] = @old_warnings - @new_warnings
20
+
21
+ second_pass(warnings)
22
+ end
23
+
24
+ # second pass to cleanup any vulns which have changed in line number only.
25
+ # Given a list of new warnings, delete pairs of new/fixed vulns that differ
26
+ # only by line number.
27
+ # Horrible O(n^2) performance. Keep n small :-/
28
+ def second_pass(warnings)
29
+ # keep track of the number of elements deleted because the index numbers
30
+ # won't update as the list is modified
31
+ elements_deleted_offset = 0
32
+
33
+ # dup this list since we will be deleting from it and the iterator gets confused.
34
+ # use _with_index for fast deletion as opposed to .reject!{|obj| obj == *_warning}
35
+ warnings[:new].dup.each_with_index do |new_warning, new_warning_id|
36
+ warnings[:fixed].each_with_index do |fixed_warning, fixed_warning_id|
37
+ if eql_except_line_number new_warning, fixed_warning
38
+ warnings[:new].delete_at(new_warning_id - elements_deleted_offset)
39
+ elements_deleted_offset += 1
40
+ warnings[:fixed].delete_at(fixed_warning_id)
41
+ break
42
+ end
43
+ end
44
+ end
45
+
46
+ warnings
47
+ end
48
+
49
+ def eql_except_line_number new_warning, fixed_warning
50
+ # can't do this ahead of time, as callers may be expecting a Brakeman::Warning
51
+ if new_warning.is_a? Brakeman::Warning
52
+ new_warning = new_warning.to_hash
53
+ fixed_warning = fixed_warning.to_hash
54
+ end
55
+
56
+ if new_warning[:fingerprint] and fixed_warning[:fingerprint]
57
+ new_warning[:fingerprint] == fixed_warning[:fingerprint]
58
+ else
59
+ OLD_WARNING_KEYS.each do |attr|
60
+ return false if new_warning[attr] != fixed_warning[attr]
61
+ end
62
+
63
+ true
64
+ end
65
+ end
66
+ end
@@ -5,6 +5,10 @@ body {
5
5
  color: #161616;
6
6
  }
7
7
 
8
+ a {
9
+ color: #161616;
10
+ }
11
+
8
12
  p {
9
13
  font-weight: bold;
10
14
  font-size: 11pt;
@@ -60,6 +64,11 @@ p {
60
64
  background-color: white;
61
65
  }
62
66
 
67
+ table caption {
68
+ background-color: #FFE;
69
+ padding: 2px;
70
+ }
71
+
63
72
  table.context {
64
73
  margin-top: 5px;
65
74
  margin-bottom: 5px;
@@ -103,3 +112,22 @@ p {
103
112
  pre.context {
104
113
  margin-bottom: 1px;
105
114
  }
115
+
116
+ .user_input {
117
+ background-color: #fcecab;
118
+ }
119
+
120
+ div.render_path {
121
+ display: none;
122
+ background-color: #ffe;
123
+ padding: 5px;
124
+ margin: 2px 0px 2px 0px;
125
+ }
126
+
127
+ div.template_name {
128
+ cursor: pointer;
129
+ }
130
+
131
+ div.template_name:hover {
132
+ background-color: white;
133
+ }
@@ -0,0 +1,256 @@
1
+ require 'optparse'
2
+ require 'set'
3
+
4
+ #Parses command line arguments for Brakeman
5
+ module Brakeman::Options
6
+
7
+ class << self
8
+
9
+ #Parse argument array
10
+ def parse args
11
+ get_options args
12
+ end
13
+
14
+ #Parse arguments and remove them from the array as they are matched
15
+ def parse! args
16
+ get_options args, true
17
+ end
18
+
19
+ #Return hash of options and the parser
20
+ def get_options args, destructive = false
21
+ options = {}
22
+
23
+ parser = OptionParser.new do |opts|
24
+ opts.banner = "Usage: brakeman [options] rails/root/path"
25
+
26
+ opts.on "-n", "--no-threads", "Run checks sequentially" do
27
+ options[:parallel_checks] = false
28
+ end
29
+
30
+ opts.on "--[no-]progress", "Show progress reports" do |progress|
31
+ options[:report_progress] = progress
32
+ end
33
+
34
+ opts.on "-p", "--path PATH", "Specify path to Rails application" do |path|
35
+ options[:app_path] = File.expand_path path
36
+ end
37
+
38
+ opts.on "-q", "--[no-]quiet", "Suppress informational messages" do |quiet|
39
+ options[:quiet] = quiet
40
+ end
41
+
42
+ opts.on( "-z", "--exit-on-warn", "Exit code is non-zero if warnings found") do
43
+ options[:exit_on_warn] = true
44
+ end
45
+
46
+ opts.on "-3", "--rails3", "Force Rails 3 mode" do
47
+ options[:rails3] = true
48
+ end
49
+
50
+ opts.separator ""
51
+ opts.separator "Scanning options:"
52
+
53
+ opts.on "-a", "--[no-]assume-routes", "Assume all controller methods are actions (default)" do |assume|
54
+ options[:assume_all_routes] = assume
55
+ end
56
+
57
+ opts.on "-e", "--escape-html", "Escape HTML by default" do
58
+ options[:escape_html] = true
59
+ end
60
+
61
+ opts.on "--faster", "Faster, but less accurate scan" do
62
+ options[:ignore_ifs] = true
63
+ options[:skip_libs] = true
64
+ end
65
+
66
+ opts.on "--ignore-model-output", "Consider model attributes XSS-safe" do
67
+ options[:ignore_model_output] = true
68
+ end
69
+
70
+ opts.on "--ignore-protected", "Consider models with attr_protected safe" do
71
+ options[:ignore_attr_protected] = true
72
+ end
73
+
74
+ opts.on "--interprocedural", "Process method calls to known methods" do
75
+ options[:interprocedural] = true
76
+ end
77
+
78
+ opts.on "--no-branching", "Disable flow sensitivity on conditionals" do
79
+ options[:ignore_ifs] = true
80
+ end
81
+
82
+ opts.on "--branch-limit LIMIT", Integer, "Limit depth of values in branches (-1 for no limit)" do |limit|
83
+ options[:branch_limit] = limit
84
+ end
85
+
86
+ opts.on "-r", "--report-direct", "Only report direct use of untrusted data" do |option|
87
+ options[:check_arguments] = !option
88
+ end
89
+
90
+ opts.on "-s", "--safe-methods meth1,meth2,etc", Array, "Consider the specified methods safe" do |methods|
91
+ options[:safe_methods] ||= Set.new
92
+ options[:safe_methods].merge methods.map {|e| e.to_sym }
93
+ end
94
+
95
+ opts.on "--url-safe-methods method1,method2,etc", Array, "Do not warn of XSS if the link_to href parameter is wrapped in a safe method" do |methods|
96
+ options[:url_safe_methods] ||= Set.new
97
+ options[:url_safe_methods].merge methods.map {|e| e.to_sym }
98
+ end
99
+
100
+ opts.on "--skip-files file1,file2,etc", Array, "Skip processing of these files" do |files|
101
+ options[:skip_files] ||= Set.new
102
+ options[:skip_files].merge files
103
+ end
104
+
105
+ opts.on "--only-files file1,file2,etc", Array, "Process only these files" do |files|
106
+ options[:only_files] ||= Set.new
107
+ options[:only_files].merge files
108
+ end
109
+
110
+ opts.on "--skip-libs", "Skip processing lib directory" do
111
+ options[:skip_libs] = true
112
+ end
113
+
114
+ opts.on "-t", "--test Check1,Check2,etc", Array, "Only run the specified checks" do |checks|
115
+ checks.each_with_index do |s, index|
116
+ if s[0,5] != "Check"
117
+ checks[index] = "Check" << s
118
+ end
119
+ end
120
+
121
+ options[:run_checks] ||= Set.new
122
+ options[:run_checks].merge checks
123
+ end
124
+
125
+ opts.on "-x", "--except Check1,Check2,etc", Array, "Skip the specified checks" do |skip|
126
+ skip.each do |s|
127
+ if s[0,5] != "Check"
128
+ s = "Check" << s
129
+ end
130
+
131
+ options[:skip_checks] ||= Set.new
132
+ options[:skip_checks] << s
133
+ end
134
+ end
135
+
136
+ opts.separator ""
137
+ opts.separator "Output options:"
138
+
139
+ opts.on "-d", "--debug", "Lots of output" do
140
+ options[:debug] = true
141
+ end
142
+
143
+ opts.on "-f",
144
+ "--format TYPE",
145
+ [:pdf, :text, :html, :csv, :tabs, :json],
146
+ "Specify output formats. Default is text" do |type|
147
+
148
+ type = "s" if type == :text
149
+ options[:output_format] = ("to_" << type.to_s).to_sym
150
+ end
151
+
152
+ opts.on "--css-file CSSFile", "Specify CSS to use for HTML output" do |file|
153
+ options[:html_style] = File.expand_path file
154
+ end
155
+
156
+ opts.on "-i IGNOREFILE", "--ignore-config IGNOREFILE", "Use configuration to ignore warnings" do |file|
157
+ options[:ignore_file] = file
158
+ end
159
+
160
+ opts.on "-I", "--interactive-ignore", "Interactively ignore warnings" do
161
+ options[:interactive_ignore] = true
162
+ end
163
+
164
+ opts.on "-l", "--[no-]combine-locations", "Combine warning locations (Default)" do |combine|
165
+ options[:combine_locations] = combine
166
+ end
167
+
168
+ opts.on "--[no-]highlights", "Highlight user input in report" do |highlight|
169
+ options[:highlight_user_input] = highlight
170
+ end
171
+
172
+ opts.on "-m", "--routes", "Report controller information" do
173
+ options[:report_routes] = true
174
+ end
175
+
176
+ opts.on "--message-limit LENGTH", "Limit message length in HTML report" do |limit|
177
+ options[:message_limit] = limit.to_i
178
+ end
179
+
180
+ opts.on "-o", "--output FILE", "Specify files for output. Defaults to stdout. Multiple '-o's allowed" do |file|
181
+ options[:output_files] ||= []
182
+ options[:output_files].push(file)
183
+ end
184
+
185
+ opts.on "--separate-models", "Warn on each model without attr_accessible" do
186
+ options[:collapse_mass_assignment] = false
187
+ end
188
+
189
+ opts.on "--summary", "Only output summary of warnings" do
190
+ options[:summary_only] = true
191
+ end
192
+
193
+ opts.on "--absolute-paths", "Output absolute file paths in reports" do
194
+ options[:absolute_paths] = true
195
+ end
196
+
197
+ opts.on "-w",
198
+ "--confidence-level LEVEL",
199
+ ["1", "2", "3"],
200
+ "Set minimal confidence level (1 - 3)" do |level|
201
+
202
+ options[:min_confidence] = 3 - level.to_i
203
+ end
204
+
205
+ opts.on "--compare FILE", "Compare the results of a previous brakeman scan (only JSON is supported)" do |file|
206
+ options[:previous_results_json] = File.expand_path(file)
207
+ end
208
+
209
+ opts.separator ""
210
+ opts.separator "Configuration files:"
211
+
212
+ opts.on "-c", "--config-file FILE", "Use specified configuration file" do |file|
213
+ options[:config_file] = File.expand_path(file)
214
+ end
215
+
216
+ opts.on "-C", "--create-config [FILE]", "Output configuration file based on options" do |file|
217
+ if file
218
+ options[:create_config] = file
219
+ else
220
+ options[:create_config] = true
221
+ end
222
+ end
223
+
224
+ opts.separator ""
225
+
226
+ opts.on "-k", "--checks", "List all available vulnerability checks" do
227
+ options[:list_checks] = true
228
+ end
229
+
230
+ opts.on "--rake", "Create rake task to run Brakeman" do
231
+ options[:install_rake_task] = true
232
+ end
233
+
234
+ opts.on "-v", "--version", "Show Brakeman version" do
235
+ options[:show_version] = true
236
+ end
237
+
238
+ opts.on_tail "-h", "--help", "Display this message" do
239
+ options[:show_help] = true
240
+ end
241
+ end
242
+
243
+ if destructive
244
+ parser.parse! args
245
+ else
246
+ parser.parse args
247
+ end
248
+
249
+ if options[:previous_results_json] and options[:output_files]
250
+ options[:comparison_output_file] = options[:output_files].shift
251
+ end
252
+
253
+ return options, parser
254
+ end
255
+ end
256
+ end
@@ -0,0 +1,6 @@
1
+ Brakeman.load_dependency 'erubis'
2
+
3
+ #Erubis processor which ignores any output which is plain text.
4
+ class Brakeman::ScannerErubis < Erubis::Eruby
5
+ include Erubis::NoTextEnhancer
6
+ end
@@ -0,0 +1,48 @@
1
+ Brakeman.load_dependency 'erubis'
2
+
3
+ #This is from the rails_xss plugin for Rails 2
4
+ class Brakeman::Rails2XSSPluginErubis < ::Erubis::Eruby
5
+ def add_preamble(src)
6
+ #src << "@output_buffer = ActiveSupport::SafeBuffer.new;"
7
+ end
8
+
9
+ #This is different from rails_xss - fixes some line number issues
10
+ def add_text(src, text)
11
+ if text == "\n"
12
+ src << "\n"
13
+ elsif text.include? "\n"
14
+ lines = text.split("\n")
15
+ if text.match(/\n\z/)
16
+ lines.each do |line|
17
+ src << "@output_buffer.safe_concat('" << escape_text(line) << "');\n"
18
+ end
19
+ else
20
+ lines[0..-2].each do |line|
21
+ src << "@output_buffer.safe_concat('" << escape_text(line) << "');\n"
22
+ end
23
+
24
+ src << "@output_buffer.safe_concat('" << escape_text(lines.last) << "');"
25
+ end
26
+ else
27
+ src << "@output_buffer.safe_concat('" << escape_text(text) << "');"
28
+ end
29
+ end
30
+
31
+ BLOCK_EXPR = /\s+(do|\{)(\s*\|[^|]*\|)?\s*\Z/
32
+
33
+ def add_expr_literal(src, code)
34
+ if code =~ BLOCK_EXPR
35
+ src << "@output_buffer.safe_concat((" << $1 << ").to_s);"
36
+ else
37
+ src << '@output_buffer << ((' << code << ').to_s);'
38
+ end
39
+ end
40
+
41
+ def add_expr_escaped(src, code)
42
+ src << '@output_buffer << ' << escaped_expr(code) << ';'
43
+ end
44
+
45
+ def add_postamble(src)
46
+ #src << '@output_buffer.to_s'
47
+ end
48
+ end
@@ -1,22 +1,19 @@
1
- begin
2
- require 'erubis'
3
- rescue LoadError => e
4
- $stderr.puts e.message
5
- $stderr.puts "Please install Erubis."
6
- exit!
7
- end
1
+ Brakeman.load_dependency 'erubis'
8
2
 
9
3
  #This is from Rails 3 version of the Erubis handler
10
- class RailsXSSErubis < ::Erubis::Eruby
4
+ class Brakeman::Rails3Erubis < ::Erubis::Eruby
11
5
 
12
6
  def add_preamble(src)
13
7
  # src << "_buf = ActionView::SafeBuffer.new;\n"
14
8
  end
15
9
 
10
+ #This is different from Rails 3 - fixes some line number issues
16
11
  def add_text(src, text)
17
- if text.include? "\n"
12
+ if text == "\n"
13
+ src << "\n"
14
+ elsif text.include? "\n"
18
15
  lines = text.split("\n")
19
- if text.match /\n\z/
16
+ if text.match(/\n\z/)
20
17
  lines.each do |line|
21
18
  src << "@output_buffer << ('" << escape_text(line) << "'.html_safe!);\n"
22
19
  end
@@ -24,7 +21,7 @@ class RailsXSSErubis < ::Erubis::Eruby
24
21
  lines[0..-2].each do |line|
25
22
  src << "@output_buffer << ('" << escape_text(line) << "'.html_safe!);\n"
26
23
  end
27
-
24
+
28
25
  src << "@output_buffer << ('" << escape_text(lines.last) << "'.html_safe!);"
29
26
  end
30
27
  else
@@ -63,13 +60,3 @@ class RailsXSSErubis < ::Erubis::Eruby
63
60
  # src << '_buf.to_s'
64
61
  end
65
62
  end
66
-
67
- #Erubis processor which ignores any output which is plain text.
68
- class ScannerErubis < Erubis::Eruby
69
- include Erubis::NoTextEnhancer
70
- end
71
-
72
- class ErubisEscape < ScannerErubis
73
- include Erubis::EscapeEnhancer
74
- end
75
-