arachni 1.1 → 1.2

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.
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' }