arachni 1.1 → 1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (287) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +159 -0
  3. data/LICENSE.md +126 -196
  4. data/README.md +32 -24
  5. data/arachni.gemspec +7 -7
  6. data/components/checks/active/code_injection_timing.rb +3 -3
  7. data/components/checks/active/csrf.rb +2 -2
  8. data/components/checks/active/file_inclusion.rb +6 -7
  9. data/components/checks/active/os_cmd_injection.rb +3 -3
  10. data/components/checks/active/path_traversal.rb +7 -7
  11. data/components/checks/active/response_splitting.rb +9 -4
  12. data/components/checks/active/session_fixation.rb +7 -3
  13. data/components/checks/active/source_code_disclosure.rb +5 -5
  14. data/components/checks/active/unvalidated_redirect.rb +12 -3
  15. data/components/checks/active/unvalidated_redirect_dom.rb +3 -3
  16. data/components/checks/active/xss.rb +23 -10
  17. data/components/checks/active/xss_dom_inputs.rb +113 -11
  18. data/components/checks/active/xxe.rb +3 -3
  19. data/components/checks/passive/backdoors.rb +6 -5
  20. data/components/checks/passive/backup_directories.rb +6 -6
  21. data/components/checks/passive/backup_files.rb +6 -6
  22. data/components/checks/passive/common_admin_interfaces.rb +58 -0
  23. data/components/checks/passive/common_admin_interfaces/admin-panels.txt +49 -0
  24. data/components/checks/passive/common_directories/directories.txt +0 -16
  25. data/components/checks/passive/common_files.rb +6 -5
  26. data/components/checks/passive/common_files/filenames.txt +0 -2
  27. data/components/checks/passive/directory_listing.rb +6 -6
  28. data/components/checks/passive/grep/cookie_set_for_parent_domain.rb +3 -3
  29. data/components/checks/passive/grep/hsts.rb +6 -3
  30. data/components/checks/passive/grep/http_only_cookies.rb +3 -3
  31. data/components/checks/passive/grep/insecure_cookies.rb +2 -2
  32. data/components/checks/passive/grep/insecure_cors_policy.rb +6 -4
  33. data/components/checks/passive/grep/x_frame_options.rb +6 -4
  34. data/components/checks/passive/htaccess_limit.rb +6 -2
  35. data/components/checks/passive/http_put.rb +8 -4
  36. data/components/checks/passive/interesting_responses.rb +3 -2
  37. data/components/checks/passive/localstart_asp.rb +6 -2
  38. data/components/checks/passive/origin_spoof_access_restriction_bypass.rb +5 -1
  39. data/components/checks/passive/xst.rb +6 -2
  40. data/components/fingerprinters/frameworks/aspx_mvc.rb +43 -0
  41. data/components/fingerprinters/frameworks/cakephp.rb +28 -0
  42. data/components/fingerprinters/frameworks/cherrypy.rb +31 -0
  43. data/components/fingerprinters/frameworks/django.rb +33 -0
  44. data/components/fingerprinters/frameworks/jsf.rb +30 -0
  45. data/components/fingerprinters/frameworks/rack.rb +5 -7
  46. data/components/fingerprinters/frameworks/rails.rb +43 -0
  47. data/components/fingerprinters/languages/aspx.rb +11 -11
  48. data/components/fingerprinters/languages/{jsp.rb → java.rb} +11 -7
  49. data/components/fingerprinters/languages/php.rb +6 -6
  50. data/components/fingerprinters/languages/python.rb +14 -6
  51. data/components/fingerprinters/languages/ruby.rb +3 -5
  52. data/components/fingerprinters/servers/apache.rb +5 -4
  53. data/components/fingerprinters/servers/gunicorn.rb +33 -0
  54. data/components/fingerprinters/servers/jetty.rb +1 -1
  55. data/components/fingerprinters/servers/tomcat.rb +11 -4
  56. data/components/path_extractors/anchors.rb +5 -12
  57. data/components/path_extractors/areas.rb +5 -13
  58. data/components/path_extractors/comments.rb +5 -3
  59. data/components/path_extractors/data_url.rb +21 -0
  60. data/components/path_extractors/forms.rb +5 -13
  61. data/components/path_extractors/frames.rb +6 -13
  62. data/components/path_extractors/generic.rb +3 -12
  63. data/components/path_extractors/links.rb +5 -13
  64. data/components/path_extractors/meta_refresh.rb +5 -13
  65. data/components/path_extractors/scripts.rb +8 -14
  66. data/components/plugins/autologin.rb +17 -5
  67. data/components/plugins/defaults/meta/remedies/discovery.rb +11 -29
  68. data/components/plugins/login_script.rb +40 -10
  69. data/components/plugins/metrics.rb +235 -0
  70. data/components/plugins/proxy.rb +21 -4
  71. data/components/plugins/proxy/panel/page_accordion.html.erb +34 -2
  72. data/components/plugins/restrict_to_dom_state.rb +70 -0
  73. data/components/plugins/vector_feed.rb +38 -9
  74. data/components/reporters/plugin_formatters/html/metrics.rb +290 -0
  75. data/components/reporters/plugin_formatters/stdout/metrics.rb +80 -0
  76. data/components/reporters/plugin_formatters/xml/metrics.rb +29 -0
  77. data/components/reporters/stdout.rb +4 -2
  78. data/components/reporters/xml.rb +4 -4
  79. data/components/reporters/xml/schema.xsd +95 -0
  80. data/lib/arachni.rb +2 -0
  81. data/lib/arachni/browser.rb +132 -77
  82. data/lib/arachni/browser/javascript.rb +173 -45
  83. data/lib/arachni/browser/javascript/scripts/dom_monitor.js +81 -6
  84. data/lib/arachni/browser/javascript/scripts/taint_tracer.js +31 -3
  85. data/lib/arachni/browser_cluster.rb +41 -15
  86. data/lib/arachni/browser_cluster/job.rb +4 -0
  87. data/lib/arachni/browser_cluster/jobs/resource_exploration.rb +0 -9
  88. data/lib/arachni/browser_cluster/worker.rb +8 -5
  89. data/lib/arachni/check/auditor.rb +20 -8
  90. data/lib/arachni/check/base.rb +38 -6
  91. data/lib/arachni/element/base.rb +18 -1
  92. data/lib/arachni/element/capabilities/analyzable/differential.rb +0 -1
  93. data/lib/arachni/element/capabilities/analyzable/taint.rb +40 -10
  94. data/lib/arachni/element/capabilities/analyzable/timeout.rb +27 -23
  95. data/lib/arachni/element/capabilities/auditable/dom.rb +22 -0
  96. data/lib/arachni/element/capabilities/inputtable.rb +6 -2
  97. data/lib/arachni/element/capabilities/submittable.rb +1 -1
  98. data/lib/arachni/element/cookie.rb +37 -23
  99. data/lib/arachni/element/cookie/capabilities/mutable.rb +6 -6
  100. data/lib/arachni/element/cookie/dom.rb +0 -8
  101. data/lib/arachni/element/form.rb +28 -14
  102. data/lib/arachni/element/form/capabilities/auditable.rb +2 -2
  103. data/lib/arachni/element/form/capabilities/mutable.rb +5 -5
  104. data/lib/arachni/element/form/dom.rb +0 -8
  105. data/lib/arachni/element/generic_dom.rb +1 -1
  106. data/lib/arachni/element/json.rb +2 -1
  107. data/lib/arachni/element/json/capabilities/inputtable.rb +6 -6
  108. data/lib/arachni/element/json/capabilities/mutable.rb +1 -1
  109. data/lib/arachni/element/link.rb +13 -16
  110. data/lib/arachni/element/link/dom.rb +1 -14
  111. data/lib/arachni/element/link_template.rb +3 -2
  112. data/lib/arachni/element/link_template/dom.rb +0 -16
  113. data/lib/arachni/element/server.rb +51 -9
  114. data/lib/arachni/element/xml.rb +1 -0
  115. data/lib/arachni/ethon/easy.rb +4 -1
  116. data/lib/arachni/framework/parts/audit.rb +26 -77
  117. data/lib/arachni/framework/parts/browser.rb +50 -55
  118. data/lib/arachni/framework/parts/check.rb +4 -3
  119. data/lib/arachni/framework/parts/data.rb +41 -6
  120. data/lib/arachni/framework/parts/state.rb +16 -7
  121. data/lib/arachni/http/client.rb +66 -38
  122. data/lib/arachni/http/client/dynamic_404_handler.rb +46 -14
  123. data/lib/arachni/http/headers.rb +22 -10
  124. data/lib/arachni/http/proxy_server.rb +67 -22
  125. data/lib/arachni/http/proxy_server/ssl-interceptor-cacert.pem +34 -0
  126. data/lib/arachni/http/proxy_server/ssl-interceptor-cakey.pem +51 -0
  127. data/lib/arachni/http/request.rb +71 -18
  128. data/lib/arachni/issue.rb +17 -3
  129. data/lib/arachni/option_groups/browser_cluster.rb +34 -1
  130. data/lib/arachni/option_groups/http.rb +1 -1
  131. data/lib/arachni/page.rb +26 -13
  132. data/lib/arachni/page/dom/transition.rb +2 -2
  133. data/lib/arachni/parser.rb +28 -11
  134. data/lib/arachni/platform/fingerprinter.rb +5 -0
  135. data/lib/arachni/platform/manager.rb +65 -32
  136. data/lib/arachni/plugin/base.rb +8 -0
  137. data/lib/arachni/processes/instances.rb +25 -11
  138. data/lib/arachni/reporter/manager.rb +2 -2
  139. data/lib/arachni/rpc/client/instance.rb +4 -0
  140. data/lib/arachni/rpc/server/framework/master.rb +3 -3
  141. data/lib/arachni/rpc/server/framework/multi_instance.rb +0 -8
  142. data/lib/arachni/rpc/server/instance.rb +2 -1
  143. data/lib/arachni/ruby/array.rb +5 -0
  144. data/lib/arachni/ruby/hash.rb +5 -0
  145. data/lib/arachni/ruby/string.rb +2 -3
  146. data/lib/arachni/session.rb +32 -6
  147. data/lib/arachni/state/framework.rb +6 -2
  148. data/lib/arachni/support/cache.rb +1 -0
  149. data/lib/arachni/support/cache/base.rb +12 -8
  150. data/lib/arachni/support/cache/least_recently_pushed.rb +29 -0
  151. data/lib/arachni/support/cache/least_recently_used.rb +5 -8
  152. data/lib/arachni/support/cache/preference.rb +1 -1
  153. data/lib/arachni/support/cache/random_replacement.rb +1 -25
  154. data/lib/arachni/support/database/queue.rb +21 -8
  155. data/lib/arachni/support/lookup/base.rb +7 -1
  156. data/lib/arachni/support/mixins/observable.rb +3 -1
  157. data/lib/arachni/support/profiler.rb +51 -10
  158. data/lib/arachni/support/signature.rb +11 -2
  159. data/lib/arachni/trainer.rb +8 -2
  160. data/lib/arachni/uri.rb +28 -25
  161. data/lib/arachni/uri/scope.rb +1 -1
  162. data/lib/arachni/utilities.rb +8 -0
  163. data/lib/arachni/watir/element.rb +1 -1
  164. data/lib/version +1 -1
  165. data/spec/arachni/browser/javascript/dom_monitor_spec.rb +388 -53
  166. data/spec/arachni/browser/javascript/taint_tracer_spec.rb +41 -0
  167. data/spec/arachni/browser/javascript_spec.rb +235 -61
  168. data/spec/arachni/browser_cluster/jobs/resource_exploration_spec.rb +0 -9
  169. data/spec/arachni/browser_cluster_spec.rb +58 -10
  170. data/spec/arachni/browser_spec.rb +170 -26
  171. data/spec/arachni/check/auditor_spec.rb +22 -3
  172. data/spec/arachni/check/base_spec.rb +84 -0
  173. data/spec/arachni/element/body_spec.rb +1 -1
  174. data/spec/arachni/element/capabilities/analyzable/taint_spec.rb +3 -3
  175. data/spec/arachni/element/capabilities/analyzable/timeout_spec.rb +1 -1
  176. data/spec/arachni/element/cookie/dom_spec.rb +0 -9
  177. data/spec/arachni/element/cookie_spec.rb +85 -0
  178. data/spec/arachni/element/form/dom_spec.rb +0 -9
  179. data/spec/arachni/element/form_spec.rb +46 -3
  180. data/spec/arachni/element/json_spec.rb +20 -0
  181. data/spec/arachni/element/link/dom_spec.rb +0 -9
  182. data/spec/arachni/element/link_spec.rb +40 -15
  183. data/spec/arachni/element/link_template/dom_spec.rb +0 -8
  184. data/spec/arachni/element/link_template_spec.rb +2 -6
  185. data/spec/arachni/element/server_spec.rb +94 -8
  186. data/spec/arachni/element/xml_spec.rb +20 -0
  187. data/spec/arachni/framework/parts/audit_spec.rb +12 -14
  188. data/spec/arachni/framework/parts/browser_spec.rb +0 -171
  189. data/spec/arachni/framework/parts/platform_spec.rb +14 -8
  190. data/spec/arachni/framework/parts/report_spec.rb +1 -1
  191. data/spec/arachni/framework/parts/state_spec.rb +0 -9
  192. data/spec/arachni/http/client/dynamic_404_handlers_spec.rb +19 -0
  193. data/spec/arachni/http/client_spec.rb +169 -42
  194. data/spec/arachni/http/headers_spec.rb +18 -0
  195. data/spec/arachni/http/request_spec.rb +23 -0
  196. data/spec/arachni/issue_spec.rb +17 -6
  197. data/spec/arachni/page_spec.rb +22 -2
  198. data/spec/arachni/parser_spec.rb +5 -0
  199. data/spec/arachni/platform/manager_spec.rb +57 -25
  200. data/spec/arachni/reporter/manager_spec.rb +26 -0
  201. data/spec/arachni/rpc/server/active_options_spec.rb +9 -4
  202. data/spec/arachni/state/framework_spec.rb +2 -8
  203. data/spec/arachni/support/cache/least_recently_pushed_spec.rb +90 -0
  204. data/spec/arachni/support/cache/least_recently_used_spec.rb +5 -13
  205. data/spec/arachni/support/database/queue_spec.rb +7 -0
  206. data/spec/arachni/support/mixins/observable_spec.rb +15 -1
  207. data/spec/arachni/trainer_spec.rb +2 -2
  208. data/spec/components/checks/active/code_injection_timing_spec.rb +1 -1
  209. data/spec/components/checks/active/file_inclusion_spec.rb +6 -6
  210. data/spec/components/checks/active/path_traversal_spec.rb +2 -2
  211. data/spec/components/checks/active/source_code_disclosure_spec.rb +2 -2
  212. data/spec/components/checks/active/unvalidated_redirect_spec.rb +6 -6
  213. data/spec/components/checks/active/xss_dom_inputs_spec.rb +3 -5
  214. data/spec/components/checks/active/xss_dom_script_context_spec.rb +1 -1
  215. data/spec/components/checks/active/xss_spec.rb +5 -5
  216. data/spec/components/checks/passive/common_admin_interfaces_spec.rb +15 -0
  217. data/spec/components/checks/passive/interesting_responses_spec.rb +14 -1
  218. data/spec/components/fingerprinters/frameworks/aspx_mvc_spec.rb +31 -0
  219. data/spec/components/fingerprinters/frameworks/cakephp_spec.rb +22 -0
  220. data/spec/components/fingerprinters/frameworks/cherrypy_spec.rb +28 -0
  221. data/spec/components/fingerprinters/frameworks/django_spec.rb +37 -0
  222. data/spec/components/fingerprinters/frameworks/jsf_spec.rb +27 -0
  223. data/spec/components/fingerprinters/frameworks/rack_spec.rb +11 -14
  224. data/spec/components/fingerprinters/frameworks/rails_spec.rb +53 -0
  225. data/spec/components/fingerprinters/languages/asp_spec.rb +7 -9
  226. data/spec/components/fingerprinters/languages/aspx_spec.rb +10 -24
  227. data/spec/components/fingerprinters/languages/java_spec.rb +88 -0
  228. data/spec/components/fingerprinters/languages/php_spec.rb +19 -12
  229. data/spec/components/fingerprinters/languages/python_spec.rb +22 -9
  230. data/spec/components/fingerprinters/languages/ruby.rb +6 -4
  231. data/spec/components/fingerprinters/os/bsd_spec.rb +6 -4
  232. data/spec/components/fingerprinters/os/linux_spec.rb +6 -4
  233. data/spec/components/fingerprinters/os/solaris_spec.rb +6 -4
  234. data/spec/components/fingerprinters/os/unix_spec.rb +6 -4
  235. data/spec/components/fingerprinters/os/windows_spec.rb +6 -4
  236. data/spec/components/fingerprinters/servers/apache_spec.rb +15 -4
  237. data/spec/components/fingerprinters/servers/gunicorn_spec.rb +28 -0
  238. data/spec/components/fingerprinters/servers/iis_spec.rb +6 -6
  239. data/spec/components/fingerprinters/servers/jetty_spec.rb +6 -6
  240. data/spec/components/fingerprinters/servers/nginx_spec.rb +6 -4
  241. data/spec/components/fingerprinters/servers/tomcat_spec.rb +15 -6
  242. data/spec/components/path_extractors/data_url_spec.rb +19 -0
  243. data/spec/components/plugins/autologin_spec.rb +23 -0
  244. data/spec/components/plugins/login_script_spec.rb +112 -24
  245. data/spec/components/plugins/restrict_to_dom_state_spec.rb +16 -0
  246. data/spec/components/plugins/vector_feed_spec.rb +39 -1
  247. data/spec/support/factories/page/dom.rb +9 -4
  248. data/spec/support/factories/page/dom/transition.rb +31 -9
  249. data/spec/support/factories/scan_report.rb +8 -6
  250. data/spec/support/fixtures/empty/placeholder +0 -0
  251. data/spec/support/fixtures/report.afr +0 -0
  252. data/spec/support/fixtures/reporters/manager_spec/error.rb +18 -0
  253. data/spec/support/servers/arachni/browser.rb +117 -11
  254. data/spec/support/servers/arachni/browser/javascript/dom_monitor.rb +148 -4
  255. data/spec/support/servers/arachni/check/auditor.rb +4 -0
  256. data/spec/support/servers/arachni/element/cookie/cookie_dom.rb +1 -1
  257. data/spec/support/servers/arachni/http/client.rb +5 -0
  258. data/spec/support/servers/arachni/http/client/dynamic_404_handler.rb +13 -0
  259. data/spec/support/servers/checks/active/code_injection_timing.rb +1 -1
  260. data/spec/support/servers/checks/active/file_inclusion.rb +2 -2
  261. data/spec/support/servers/checks/active/path_traversal.rb +2 -2
  262. data/spec/support/servers/checks/active/source_code_disclosure.rb +40 -33
  263. data/spec/support/servers/checks/active/trainer_check.rb +9 -10
  264. data/spec/support/servers/checks/active/unvalidated_redirect_dom.rb +7 -4
  265. data/spec/support/servers/checks/active/xss.rb +35 -0
  266. data/spec/support/servers/checks/active/xss_dom.rb +1 -1
  267. data/spec/support/servers/checks/active/xss_dom_inputs.rb +24 -0
  268. data/spec/support/servers/checks/active/xss_dom_script_context.rb +1 -1
  269. data/spec/support/servers/checks/passive/common_admin_interfaces.rb +6 -0
  270. data/spec/support/servers/plugins/autologin.rb +9 -0
  271. data/spec/support/servers/plugins/restrict_to_dom_state.rb +4 -0
  272. data/spec/support/shared/element/base.rb +42 -0
  273. data/spec/support/shared/element/capabilities/auditable.rb +4 -4
  274. data/spec/support/shared/element/capabilities/auditable/dom.rb +26 -0
  275. data/spec/support/shared/element/capabilities/inputtable.rb +16 -11
  276. data/spec/support/shared/element/capabilities/submitable.rb +7 -2
  277. data/spec/support/shared/fingerprinter.rb +8 -0
  278. data/spec/support/shared/path_extractor.rb +1 -1
  279. data/ui/cli/framework.rb +3 -3
  280. data/ui/cli/framework/option_parser.rb +9 -0
  281. data/ui/cli/output.rb +9 -0
  282. data/ui/cli/reporter.rb +5 -2
  283. data/ui/cli/utilities.rb +4 -2
  284. metadata +76 -17
  285. data/lib/arachni/http/proxy_server/ssl-interceptor-cert.pem +0 -34
  286. data/lib/arachni/http/proxy_server/ssl-interceptor-pkey.pem +0 -51
  287. data/spec/components/fingerprinters/languages/jsp_spec.rb +0 -56
@@ -174,6 +174,26 @@ EOXML
174
174
  subject.should be_nil
175
175
  end
176
176
  end
177
+
178
+ context 'when it is' do
179
+ context "equal to #{described_class::MAX_SIZE}" do
180
+ let(:size) { described_class::MAX_SIZE }
181
+
182
+ it 'returns nil'
183
+ end
184
+
185
+ context "larger than #{described_class::MAX_SIZE}" do
186
+ let(:size) { described_class::MAX_SIZE + 1 }
187
+
188
+ it 'returns nil'
189
+ end
190
+
191
+ context "smaller than #{described_class::MAX_SIZE}" do
192
+ let(:size) { described_class::MAX_SIZE - 1 }
193
+
194
+ it 'leaves parses it'
195
+ end
196
+ end
177
197
  end
178
198
 
179
199
  describe '.parse_inputs' do
@@ -190,13 +190,6 @@ describe Arachni::Framework::Parts::Audit do
190
190
  end
191
191
  end
192
192
 
193
- it 'passes the page to #apply_dom_metadata' do
194
- page = Arachni::Page.from_url( @url + '/link' )
195
-
196
- subject.should receive(:apply_dom_metadata).with(page)
197
- subject.audit_page( page )
198
- end
199
-
200
193
  context 'when checks were' do
201
194
  context 'ran against the page' do
202
195
  it 'returns true' do
@@ -232,15 +225,14 @@ describe Arachni::Framework::Parts::Audit do
232
225
  Arachni::Framework.new do |f|
233
226
  f.options.url = @url
234
227
  f.options.audit.elements :links, :forms, :cookies
235
- f.checks.load :taint
236
228
 
237
229
  f.url_queue_total_size.should == 0
238
230
 
239
231
  f.audit_page( Arachni::Page.from_url( @url + '/with_javascript' ) )
240
232
 
241
- sleep 0.1 while f.wait_for_browser_cluster?
233
+ f.run
242
234
 
243
- f.url_queue_total_size.should == 2
235
+ f.url_queue_total_size.should == 5
244
236
  end
245
237
  end
246
238
 
@@ -254,8 +246,8 @@ describe Arachni::Framework::Parts::Audit do
254
246
  f.options.scope.dom_depth_limit = 1
255
247
  f.url_queue_total_size.should == 0
256
248
  f.audit_page( Arachni::Page.from_url( @url + '/with_javascript' ) ).should be_true
257
- sleep 0.1 while f.wait_for_browser_cluster?
258
- f.url_queue_total_size.should == 2
249
+ f.run
250
+ f.url_queue_total_size.should == 5
259
251
 
260
252
  f.reset
261
253
 
@@ -268,8 +260,8 @@ describe Arachni::Framework::Parts::Audit do
268
260
  page.dom.push_transition Arachni::Page::DOM::Transition.new( :page, :load )
269
261
 
270
262
  f.audit_page( page ).should be_true
271
- sleep 0.1 while f.wait_for_browser_cluster?
272
- f.url_queue_total_size.should == 0
263
+ f.run
264
+ f.url_queue_total_size.should == 1
273
265
  end
274
266
  end
275
267
 
@@ -316,6 +308,11 @@ describe Arachni::Framework::Parts::Audit do
316
308
  end
317
309
 
318
310
  context "when #{Arachni::Options}#platforms" do
311
+ before do
312
+ Arachni::Platform::Manager.reset
313
+ subject.options.paths.fingerprinters = fixtures_path + '/empty/'
314
+ end
315
+
319
316
  context 'have been provided' do
320
317
  context 'and are supported by the check' do
321
318
  it 'audits it' do
@@ -333,6 +330,7 @@ describe Arachni::Framework::Parts::Audit do
333
330
  context 'and are not supported by the check' do
334
331
  it 'does not audit it' do
335
332
  subject.options.platforms = [:windows]
333
+
336
334
  subject.options.audit.elements :links, :forms, :cookies
337
335
 
338
336
  subject.checks.load :taint
@@ -118,175 +118,4 @@ describe Arachni::Framework::Parts::Browser do
118
118
  end
119
119
  end
120
120
  end
121
-
122
- describe '#apply_dom_metadata' do
123
- let(:page) { Factory[:page] }
124
- let(:browser_page) { Factory[:page] }
125
- let(:check) { subject.checks[:taint] }
126
-
127
- before do
128
- subject.checks.load :taint
129
-
130
- subject.browser.stub(:to_page) { browser_page }
131
- Arachni::Check::Auditor.stub(:check?) { true }
132
- page.stub(:has_script?) { true }
133
- page.dom.stub(:depth) { 0 }
134
- end
135
-
136
- it 'returns true' do
137
- subject.apply_dom_metadata( page ).should be_true
138
- end
139
-
140
- it 'applies DOM metadata' do
141
- page.should receive(:import_metadata).with( browser_page, :skip_dom )
142
-
143
- subject.apply_dom_metadata( page )
144
- end
145
-
146
- it 'clears the #browser buffers' do
147
- subject.browser.should receive(:clear_buffers)
148
-
149
- subject.apply_dom_metadata( page )
150
- end
151
-
152
- context "when #{Arachni::Page::DOM}#depth is" do
153
- context 0 do
154
- before do
155
- page.dom.stub(:depth) { 0 }
156
- end
157
-
158
- it 'returns true' do
159
- subject.apply_dom_metadata( page ).should be_true
160
- end
161
- end
162
-
163
- context '> 0' do
164
- before do
165
- page.dom.stub(:depth) { 1 }
166
- end
167
-
168
- it 'returns false' do
169
- subject.apply_dom_metadata( page ).should be_false
170
- end
171
- end
172
- end
173
-
174
- context "when #{Arachni::Page}#has_script? is" do
175
- context false do
176
- before do
177
- page.stub(:has_script?) { false }
178
- end
179
-
180
- it 'returns false' do
181
- subject.apply_dom_metadata( page ).should be_false
182
- end
183
- end
184
-
185
- context true do
186
- before do
187
- page.stub(:has_script?) { true }
188
- end
189
-
190
- it 'returns true' do
191
- subject.apply_dom_metadata( page ).should be_true
192
- end
193
- end
194
- end
195
-
196
- context 'when #use_browsers? is' do
197
- context false do
198
- before do
199
- subject.stub(:use_browsers?) { false }
200
- end
201
-
202
- it 'returns false' do
203
- subject.apply_dom_metadata( page ).should be_false
204
- end
205
- end
206
-
207
- context true do
208
- before do
209
- subject.stub(:use_browsers?) { true }
210
- end
211
-
212
- it 'returns true' do
213
- subject.apply_dom_metadata( page ).should be_true
214
- end
215
- end
216
- end
217
-
218
- context "when #{Arachni::Check::Auditor}.check? for [#{Arachni::Element::Form::DOM}, #{Arachni::Element::Cookie::DOM}] is" do
219
- before do
220
- check.should receive(:check?).with( page, [Arachni::Element::Form::DOM, Arachni::Element::Cookie::DOM] )
221
- end
222
-
223
- context false do
224
- before do
225
- check.stub(:check?) { false }
226
- end
227
-
228
- it 'returns false' do
229
- subject.apply_dom_metadata( page ).should be_false
230
- end
231
- end
232
-
233
- context true do
234
- before do
235
- check.stub(:check?) { true }
236
- end
237
-
238
- it 'returns true' do
239
- subject.apply_dom_metadata( page ).should be_true
240
- end
241
- end
242
- end
243
-
244
- context "when #{Arachni::Browser}#to_page returns" do
245
- context 'empty page' do
246
- before do
247
- subject.browser.stub(:to_page) { Factory[:empty_page] }
248
- end
249
-
250
- it 'returns nil' do
251
- subject.apply_dom_metadata( page ).should be_nil
252
- end
253
- end
254
-
255
- context 'valid page' do
256
- before do
257
- subject.browser.stub(:to_page) { browser_page }
258
- end
259
-
260
- it 'returns true' do
261
- subject.apply_dom_metadata( page ).should be_true
262
- end
263
- end
264
- end
265
-
266
- context "when #{Arachni::Browser}#to_page raises" do
267
- context "#{Selenium::WebDriver::Error::WebDriverError}" do
268
- before do
269
- subject.browser.stub(:to_page) do
270
- raise Selenium::WebDriver::Error::WebDriverError
271
- end
272
- end
273
-
274
- it 'returns nil' do
275
- subject.apply_dom_metadata( page ).should be_nil
276
- end
277
- end
278
-
279
- context "#{Watir::Exception::Error}" do
280
- before do
281
- subject.browser.stub(:to_page) do
282
- raise Watir::Exception::Error
283
- end
284
- end
285
-
286
- it 'returns true' do
287
- subject.apply_dom_metadata( page ).should be_nil
288
- end
289
- end
290
- end
291
- end
292
121
  end
@@ -36,26 +36,32 @@ describe Arachni::Framework::Parts::Platform do
36
36
  mongodb: 'MongoDB'
37
37
  },
38
38
  'Web servers' => {
39
- apache: 'Apache',
40
- iis: 'IIS',
41
- jetty: 'Jetty',
42
- nginx: 'Nginx',
43
- tomcat: 'TomCat'
39
+ apache: 'Apache',
40
+ iis: 'IIS',
41
+ jetty: 'Jetty',
42
+ nginx: 'Nginx',
43
+ tomcat: 'TomCat',
44
+ gunicorn: 'Gunicorn',
44
45
  },
45
46
  'Programming languages' => {
46
47
  asp: 'ASP',
47
48
  aspx: 'ASP.NET',
48
- jsp: 'JSP',
49
+ java: 'Java',
49
50
  perl: 'Perl',
50
51
  php: 'PHP',
51
52
  python: 'Python',
52
53
  ruby: 'Ruby'
53
54
  },
54
55
  'Frameworks' => {
55
- rack: 'Rack'
56
+ rack: 'Rack',
57
+ django: 'Django',
58
+ rails: 'Ruby on Rails',
59
+ aspx_mvc: 'ASP.NET MVC',
60
+ jsf: 'JavaServer Faces',
61
+ cherrypy: 'CherryPy',
62
+ cakephp: 'CakePHP'
56
63
  }
57
64
  }
58
-
59
65
  end
60
66
  end
61
67
 
@@ -6,7 +6,7 @@ describe Arachni::Framework::Parts::Report do
6
6
  describe '#reporters' do
7
7
  it 'provides access to the reporter manager' do
8
8
  subject.reporters.is_a?( Arachni::Reporter::Manager ).should be_true
9
- subject.reporters.available.sort.should == %w(afr foo).sort
9
+ subject.reporters.available.sort.should == %w(afr foo error).sort
10
10
  end
11
11
  end
12
12
 
@@ -483,15 +483,6 @@ describe Arachni::Framework::Parts::State do
483
483
  end
484
484
  end
485
485
 
486
- it 'shuts down the #browser' do
487
- Arachni::Framework.new do |f|
488
- f.options.url = @url + '/elem_combo'
489
-
490
- f.browser.should receive(:shutdown)
491
- f.clean_up
492
- end
493
- end
494
-
495
486
  it 'stops the #plugins' do
496
487
  Arachni::Framework.new do |f|
497
488
  f.options.url = @url + '/elem_combo'
@@ -31,6 +31,7 @@ describe Arachni::HTTP::Client::Dynamic404Handler do
31
31
  res = nil
32
32
  client.get( url + 'static/crap' ) { |c_res| res = c_res }
33
33
  client.run
34
+
34
35
  bool = false
35
36
  subject._404?( res ) { |c_bool| bool = c_bool }
36
37
  client.run
@@ -39,6 +40,18 @@ describe Arachni::HTTP::Client::Dynamic404Handler do
39
40
  end
40
41
 
41
42
  context 'when dealing with a dynamic handler' do
43
+ context 'which at any point returns non-200' do
44
+ it 'aborts the check' do
45
+ response = client.get( url + 'dynamic/erratic', mode: :sync )
46
+
47
+ check = nil
48
+ subject._404?( response ) { |bool| check = bool }
49
+ client.run
50
+
51
+ check.should be_nil
52
+ end
53
+ end
54
+
42
55
  context 'which includes the requested resource in the response' do
43
56
  it 'returns true' do
44
57
  res = nil
@@ -88,6 +101,12 @@ describe Arachni::HTTP::Client::Dynamic404Handler do
88
101
  end
89
102
  end
90
103
  end
104
+
105
+ context 'when checking for a resource with a name that includes ~' do
106
+ context 'and the handler ignores it' do
107
+ it 'returns true'
108
+ end
109
+ end
91
110
  end
92
111
 
93
112
  context 'when checking for an already checked URL' do
@@ -345,13 +345,20 @@ describe Arachni::HTTP::Client do
345
345
 
346
346
  context 'when the cookies option is set' do
347
347
  it 'adds those cookies to the CookieJar' do
348
- cookie_jar_file = fixtures_path + 'cookies.txt'
349
- @opts.http.cookies = Arachni::Utilities.cookies_from_file( '', cookie_jar_file )
348
+ @opts.http.cookies = {
349
+ 'cookie1' => 'val1',
350
+ 'cookie2' => 'val2',
351
+ }
352
+
350
353
  subject.cookie_jar.cookies.should be_empty
354
+
351
355
  subject.reset
356
+
352
357
  cookies = subject.cookie_jar.cookies
353
- cookies.size.should == 4
354
- cookies.should == @opts.http.cookies
358
+ cookies.size.should == 2
359
+
360
+ cookies[0].inputs.should == { 'cookie1' => 'val1' }
361
+ cookies[1].inputs.should == { 'cookie2' => 'val2' }
355
362
  end
356
363
  end
357
364
 
@@ -576,52 +583,136 @@ describe Arachni::HTTP::Client do
576
583
  ).request.effective_body.should == "1=%202&%203=4"
577
584
  end
578
585
 
579
- describe :response_max_size do
580
- context "when #{Arachni::OptionGroups::HTTP}#response_max_size is specified" do
581
- it 'ignores bodies of responses which are larger than specified' do
582
- @opts.http.response_max_size = 0
583
- subject.request( @url + '/http_response_max_size',
584
- mode: :sync
585
- ).body.should be_empty
586
+ describe :fingerprint do
587
+ before do
588
+ Arachni::Platform::Manager.clear
589
+ end
586
590
 
587
- @opts.http.response_max_size = 1
588
- subject.request( @url + '/http_response_max_size',
589
- mode: :sync
590
- ).body.should be_empty
591
+ context 'nil' do
592
+ it 'performs platform fingerprinting on the response' do
593
+ res = nil
594
+ subject.request( @url + '/fingerprint.php' ) { |c_res| res = c_res }
595
+ subject.run
591
596
 
592
- @opts.http.response_max_size = 999999
593
- subject.request( @url + '/http_response_max_size',
594
- mode: :sync
595
- ).body.should be_empty
597
+ res.platforms.to_a.should == [:php]
598
+ end
599
+ end
596
600
 
597
- @opts.http.response_max_size = 1000000
598
- subject.request( @url + '/http_response_max_size',
599
- mode: :sync
600
- ).body.should_not be_empty
601
+ context true do
602
+ it 'performs platform fingerprinting on the response' do
603
+ res = nil
604
+ subject.request( @url + '/fingerprint.php', fingerprint: true ) { |c_res| res = c_res }
605
+ subject.run
606
+
607
+ res.platforms.to_a.should == [:php]
601
608
  end
602
609
  end
603
610
 
604
- context 'when specified' do
605
- it 'ignores bodies of responses which are larger than specified' do
606
- subject.request( @url + '/http_response_max_size',
607
- mode: :sync,
608
- response_max_size: 0
609
- ).body.should be_empty
611
+ context false do
612
+ it 'does not fingerprint the response' do
613
+ res = nil
614
+ subject.request( @url + '/fingerprint.php', fingerprint: false ) { |c_res| res = c_res }
615
+ subject.run
610
616
 
611
- subject.request( @url + '/http_response_max_size',
612
- mode: :sync,
613
- response_max_size: 1
614
- ).body.should be_empty
617
+ res.platforms.should be_empty
618
+ end
619
+ end
620
+ end
615
621
 
616
- subject.request( @url + '/http_response_max_size',
617
- mode: :sync,
618
- response_max_size: 999999
619
- ).body.should be_empty
622
+ describe :response_max_size do
623
+ context 'when not specified' do
624
+ context "and #{Arachni::OptionGroups::HTTP}#response_max_size is specified" do
625
+ context 'when response bodies are larger that its value' do
626
+ it 'ignores them' do
627
+ @opts.http.response_max_size = 0
628
+ subject.request( @url + '/http_response_max_size',
629
+ mode: :sync
630
+ ).body.should be_empty
631
+
632
+ @opts.http.response_max_size = 1
633
+ subject.request( @url + '/http_response_max_size',
634
+ mode: :sync
635
+ ).body.should be_empty
636
+
637
+ @opts.http.response_max_size = 999999
638
+ subject.request( @url + '/http_response_max_size',
639
+ mode: :sync
640
+ ).body.should be_empty
641
+ end
642
+ end
620
643
 
621
- subject.request( @url + '/http_response_max_size',
622
- mode: :sync,
623
- response_max_size: 1000000
624
- ).body.should_not be_empty
644
+ context 'when response bodies are not larger that its value' do
645
+ it 'reads them' do
646
+ @opts.http.response_max_size = 1000000
647
+ subject.request( @url + '/http_response_max_size',
648
+ mode: :sync
649
+ ).body.should_not be_empty
650
+ end
651
+ end
652
+ end
653
+ end
654
+
655
+ context 'when specified' do
656
+ context 'when response bodies are larger that its value' do
657
+ it 'ignores them' do
658
+ subject.request( @url + '/http_response_max_size',
659
+ mode: :sync,
660
+ response_max_size: 0
661
+ ).body.should be_empty
662
+
663
+ subject.request( @url + '/http_response_max_size',
664
+ mode: :sync,
665
+ response_max_size: 1
666
+ ).body.should be_empty
667
+
668
+ subject.request( @url + '/http_response_max_size',
669
+ mode: :sync,
670
+ response_max_size: 999999
671
+ ).body.should be_empty
672
+ end
673
+ end
674
+
675
+ context 'when response bodies are not larger that its value' do
676
+ it 'reads them' do
677
+ subject.request( @url + '/http_response_max_size',
678
+ mode: :sync,
679
+ response_max_size: 1000000
680
+ ).body.should_not be_empty
681
+ end
682
+ end
683
+
684
+ context 'when the server returns no Content-Length' do
685
+ it 'still works' do
686
+ r = subject.request( @url + '/http_response_max_size/without_content_length',
687
+ mode: :sync,
688
+ response_max_size: 0
689
+ )
690
+
691
+ r.headers.should_not include 'Content-Type'
692
+ r.body.should be_empty
693
+
694
+ r = subject.request( @url + '/http_response_max_size/without_content_length',
695
+ mode: :sync,
696
+ response_max_size: 1
697
+ )
698
+ r.headers.should_not include 'Content-Type'
699
+ r.body.should be_empty
700
+
701
+ r = subject.request( @url + '/http_response_max_size/without_content_length',
702
+ mode: :sync,
703
+ response_max_size: 999999
704
+ )
705
+ r.headers.should_not include 'Content-Type'
706
+ r.body.should be_empty
707
+
708
+ r = subject.request( @url + '/http_response_max_size/without_content_length',
709
+ mode: :sync,
710
+ response_max_size: 1000000
711
+ )
712
+
713
+ r.headers.should_not include 'Content-Type'
714
+ r.body.should_not be_empty
715
+ end
625
716
  end
626
717
  end
627
718
 
@@ -634,6 +725,42 @@ describe Arachni::HTTP::Client do
634
725
  ).body.should_not be_empty
635
726
  end
636
727
  end
728
+
729
+ it 'works for asynchronous requests' do
730
+ subject.request( @url + '/http_response_max_size/without_content_length',
731
+ mode: :sync,
732
+ response_max_size: 0
733
+ ) do |r|
734
+ r.headers.should_not include 'Content-Type'
735
+ r.body.should be_empty
736
+ end
737
+
738
+ subject.request( @url + '/http_response_max_size/without_content_length',
739
+ mode: :sync,
740
+ response_max_size: 1
741
+ ) do |r|
742
+ r.headers.should_not include 'Content-Type'
743
+ r.body.should be_empty
744
+ end
745
+
746
+ subject.request( @url + '/http_response_max_size/without_content_length',
747
+ mode: :sync,
748
+ response_max_size: 999999
749
+ ) do |r|
750
+ r.headers.should_not include 'Content-Type'
751
+ r.body.should be_empty
752
+ end
753
+
754
+ subject.request( @url + '/http_response_max_size/without_content_length',
755
+ mode: :sync,
756
+ response_max_size: 1000000
757
+ ) do |r|
758
+ r.headers.should_not include 'Content-Type'
759
+ r.body.should_not be_empty
760
+ end
761
+
762
+ subject.run
763
+ end
637
764
  end
638
765
 
639
766
  describe :no_cookie_jar do
@@ -1151,7 +1278,7 @@ describe Arachni::HTTP::Client do
1151
1278
  end
1152
1279
  end
1153
1280
 
1154
- describe '#headers' do
1281
+ describe '#header' do
1155
1282
  it 'queues a GET request' do
1156
1283
  body = nil
1157
1284
  headers = { 'name' => 'val' }