arachni 1.4 → 1.6.0

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 (748) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +195 -0
  3. data/Gemfile +4 -4
  4. data/LICENSE.md +1 -1
  5. data/README.md +7 -3
  6. data/Rakefile +1 -43
  7. data/arachni.gemspec +35 -30
  8. data/bin/arachni +1 -1
  9. data/bin/arachni_console +1 -1
  10. data/bin/arachni_multi +6 -1
  11. data/bin/arachni_reporter +1 -1
  12. data/bin/arachni_reproduce +12 -0
  13. data/bin/arachni_rest_server +1 -1
  14. data/bin/arachni_restore +1 -1
  15. data/bin/arachni_rpc +6 -1
  16. data/bin/arachni_rpcd +1 -1
  17. data/bin/arachni_rpcd_monitor +6 -1
  18. data/bin/arachni_script +1 -1
  19. data/components/checks/active/code_injection.rb +1 -1
  20. data/components/checks/active/code_injection_php_input_wrapper.rb +1 -1
  21. data/components/checks/active/code_injection_timing.rb +1 -1
  22. data/components/checks/active/csrf.rb +20 -75
  23. data/components/checks/active/file_inclusion.rb +1 -1
  24. data/components/checks/active/ldap_injection.rb +1 -1
  25. data/components/checks/active/no_sql_injection.rb +1 -1
  26. data/components/checks/active/no_sql_injection_differential.rb +3 -3
  27. data/components/checks/active/os_cmd_injection.rb +1 -1
  28. data/components/checks/active/os_cmd_injection_timing.rb +1 -1
  29. data/components/checks/active/path_traversal.rb +3 -3
  30. data/components/checks/active/response_splitting.rb +1 -1
  31. data/components/checks/active/rfi.rb +1 -1
  32. data/components/checks/active/session_fixation.rb +1 -1
  33. data/components/checks/active/source_code_disclosure.rb +1 -1
  34. data/components/checks/active/sql_injection/regexps/hsqldb.yaml +1 -0
  35. data/components/checks/active/sql_injection/substrings/hsqldb +1 -0
  36. data/components/checks/active/sql_injection/substrings/java +4 -0
  37. data/components/checks/active/sql_injection/substrings/oracle +0 -1
  38. data/components/checks/active/sql_injection/substrings/sqlite +1 -0
  39. data/components/checks/active/sql_injection.rb +1 -1
  40. data/components/checks/active/sql_injection_differential.rb +3 -3
  41. data/components/checks/active/sql_injection_timing.rb +1 -1
  42. data/components/checks/active/trainer.rb +1 -1
  43. data/components/checks/active/unvalidated_redirect.rb +34 -11
  44. data/components/checks/active/unvalidated_redirect_dom.rb +4 -4
  45. data/components/checks/active/xpath_injection.rb +1 -1
  46. data/components/checks/active/xss.rb +54 -29
  47. data/components/checks/active/xss_dom.rb +15 -11
  48. data/components/checks/active/xss_dom_script_context.rb +4 -6
  49. data/components/checks/active/xss_event.rb +46 -34
  50. data/components/checks/active/xss_path.rb +9 -6
  51. data/components/checks/active/xss_script_context.rb +100 -47
  52. data/components/checks/active/xss_tag.rb +41 -15
  53. data/components/checks/active/xxe.rb +1 -1
  54. data/components/checks/passive/allowed_methods.rb +1 -1
  55. data/components/checks/passive/backdoors.rb +1 -1
  56. data/components/checks/passive/backup_directories.rb +15 -3
  57. data/components/checks/passive/backup_files.rb +39 -6
  58. data/components/checks/passive/common_admin_interfaces/admin-panels.txt +1 -0
  59. data/components/checks/passive/common_admin_interfaces.rb +1 -1
  60. data/components/checks/passive/common_directories/directories.txt +1 -0
  61. data/components/checks/passive/common_directories.rb +1 -1
  62. data/components/checks/passive/common_files.rb +1 -1
  63. data/components/checks/passive/directory_listing.rb +1 -1
  64. data/components/checks/passive/grep/captcha.rb +8 -9
  65. data/components/checks/passive/grep/cookie_set_for_parent_domain.rb +1 -1
  66. data/components/checks/passive/grep/credit_card.rb +1 -1
  67. data/components/checks/passive/grep/cvs_svn_users.rb +1 -1
  68. data/components/checks/passive/grep/emails.rb +1 -1
  69. data/components/checks/passive/grep/form_upload.rb +3 -5
  70. data/components/checks/passive/grep/hsts.rb +1 -1
  71. data/components/checks/passive/grep/html_objects.rb +1 -1
  72. data/components/checks/passive/grep/http_only_cookies.rb +1 -1
  73. data/components/checks/passive/grep/insecure_cookies.rb +5 -5
  74. data/components/checks/passive/grep/insecure_cors_policy.rb +1 -1
  75. data/components/checks/passive/grep/mixed_resource.rb +4 -4
  76. data/components/checks/passive/grep/password_autocomplete.rb +1 -1
  77. data/components/checks/passive/grep/private_ip.rb +1 -1
  78. data/components/checks/passive/grep/ssn.rb +1 -1
  79. data/components/checks/passive/grep/unencrypted_password_forms.rb +3 -3
  80. data/components/checks/passive/grep/x_frame_options.rb +4 -4
  81. data/components/checks/passive/htaccess_limit.rb +1 -1
  82. data/components/checks/passive/http_put.rb +1 -1
  83. data/components/checks/passive/insecure_client_access_policy.rb +2 -2
  84. data/components/checks/passive/insecure_cross_domain_policy_access.rb +2 -2
  85. data/components/checks/passive/insecure_cross_domain_policy_headers.rb +2 -2
  86. data/components/checks/passive/interesting_responses.rb +1 -1
  87. data/components/checks/passive/localstart_asp.rb +1 -1
  88. data/components/checks/passive/origin_spoof_access_restriction_bypass.rb +1 -1
  89. data/components/checks/passive/webdav.rb +1 -1
  90. data/components/checks/passive/xst.rb +10 -12
  91. data/components/fingerprinters/frameworks/aspx_mvc.rb +1 -1
  92. data/components/fingerprinters/frameworks/cakephp.rb +1 -1
  93. data/components/fingerprinters/frameworks/cherrypy.rb +1 -1
  94. data/components/fingerprinters/frameworks/django.rb +1 -1
  95. data/components/fingerprinters/frameworks/jsf.rb +1 -1
  96. data/components/fingerprinters/frameworks/nette.rb +1 -1
  97. data/components/fingerprinters/frameworks/rack.rb +1 -1
  98. data/components/fingerprinters/frameworks/rails.rb +1 -1
  99. data/components/fingerprinters/frameworks/symfony.rb +1 -1
  100. data/components/fingerprinters/languages/asp.rb +1 -1
  101. data/components/fingerprinters/languages/aspx.rb +1 -1
  102. data/components/fingerprinters/languages/java.rb +1 -1
  103. data/components/fingerprinters/languages/php.rb +1 -1
  104. data/components/fingerprinters/languages/python.rb +1 -1
  105. data/components/fingerprinters/languages/ruby.rb +1 -1
  106. data/components/fingerprinters/os/bsd.rb +1 -1
  107. data/components/fingerprinters/os/linux.rb +1 -1
  108. data/components/fingerprinters/os/solaris.rb +1 -1
  109. data/components/fingerprinters/os/unix.rb +1 -1
  110. data/components/fingerprinters/os/windows.rb +1 -1
  111. data/components/fingerprinters/servers/apache.rb +1 -1
  112. data/components/fingerprinters/servers/gunicorn.rb +1 -1
  113. data/components/fingerprinters/servers/iis.rb +1 -1
  114. data/components/fingerprinters/servers/jetty.rb +1 -1
  115. data/components/fingerprinters/servers/nginx.rb +1 -1
  116. data/components/fingerprinters/servers/tomcat.rb +1 -1
  117. data/components/path_extractors/anchors.rb +3 -5
  118. data/components/path_extractors/areas.rb +3 -4
  119. data/components/path_extractors/comments.rb +4 -5
  120. data/components/path_extractors/data_url.rb +4 -5
  121. data/components/path_extractors/forms.rb +3 -4
  122. data/components/path_extractors/frames.rb +3 -5
  123. data/components/path_extractors/generic.rb +3 -1
  124. data/components/path_extractors/links.rb +3 -4
  125. data/components/path_extractors/meta_refresh.rb +11 -17
  126. data/components/path_extractors/scripts.rb +18 -15
  127. data/components/plugins/autologin.rb +3 -2
  128. data/components/plugins/beep_notify.rb +1 -1
  129. data/components/plugins/content_types.rb +1 -1
  130. data/components/plugins/cookie_collector.rb +1 -1
  131. data/components/plugins/debug/browser_cluster_job_monitor.rb +60 -0
  132. data/components/plugins/defaults/autothrottle.rb +1 -1
  133. data/components/plugins/defaults/healthmap.rb +3 -1
  134. data/components/plugins/defaults/meta/remedies/discovery.rb +1 -1
  135. data/components/plugins/defaults/meta/remedies/timing_attacks.rb +1 -1
  136. data/components/plugins/defaults/meta/uniformity.rb +1 -1
  137. data/components/plugins/email_notify.rb +26 -9
  138. data/components/plugins/exec.rb +1 -1
  139. data/components/plugins/form_dicattack.rb +3 -4
  140. data/components/plugins/headers_collector.rb +1 -1
  141. data/components/plugins/http_dicattack.rb +4 -5
  142. data/components/plugins/login_script.rb +2 -2
  143. data/components/plugins/metrics.rb +44 -18
  144. data/components/plugins/page_dump.rb +60 -0
  145. data/components/plugins/proxy/panel/verify_login_sequence.html.erb +1 -1
  146. data/components/plugins/proxy/template_scope.rb +6 -1
  147. data/components/plugins/proxy.rb +44 -31
  148. data/components/plugins/rate_limiter.rb +80 -0
  149. data/components/plugins/restrict_to_dom_state.rb +1 -1
  150. data/components/plugins/script.rb +1 -1
  151. data/components/plugins/uncommon_headers.rb +1 -1
  152. data/components/plugins/vector_collector.rb +1 -1
  153. data/components/plugins/vector_feed.rb +1 -1
  154. data/components/plugins/waf_detector.rb +3 -3
  155. data/components/plugins/webhook_notify.rb +99 -0
  156. data/components/reporters/ap.rb +1 -1
  157. data/components/reporters/html/default/configuration.erb +2 -0
  158. data/components/reporters/html/default.erb +3 -2
  159. data/components/reporters/html.rb +5 -8
  160. data/components/reporters/json.rb +1 -1
  161. data/components/reporters/marshal.rb +1 -1
  162. data/components/reporters/plugin_formatters/html/autologin.rb +1 -1
  163. data/components/reporters/plugin_formatters/html/content_types.rb +1 -1
  164. data/components/reporters/plugin_formatters/html/cookie_collector.rb +1 -1
  165. data/components/reporters/plugin_formatters/html/exec.rb +1 -1
  166. data/components/reporters/plugin_formatters/html/form_dicattack.rb +1 -1
  167. data/components/reporters/plugin_formatters/html/healthmap.rb +1 -1
  168. data/components/reporters/plugin_formatters/html/http_dicattack.rb +1 -1
  169. data/components/reporters/plugin_formatters/html/login_script.rb +1 -1
  170. data/components/reporters/plugin_formatters/html/metrics.rb +46 -1
  171. data/components/reporters/plugin_formatters/html/uncommon_headers.rb +1 -1
  172. data/components/reporters/plugin_formatters/html/uniformity.rb +1 -1
  173. data/components/reporters/plugin_formatters/html/vector_collector.rb +1 -1
  174. data/components/reporters/plugin_formatters/html/waf_detector.rb +1 -1
  175. data/components/reporters/plugin_formatters/stdout/autologin.rb +1 -1
  176. data/components/reporters/plugin_formatters/stdout/content_types.rb +1 -1
  177. data/components/reporters/plugin_formatters/stdout/cookie_collector.rb +1 -1
  178. data/components/reporters/plugin_formatters/stdout/exec.rb +1 -1
  179. data/components/reporters/plugin_formatters/stdout/form_dicattack.rb +1 -1
  180. data/components/reporters/plugin_formatters/stdout/healthmap.rb +1 -1
  181. data/components/reporters/plugin_formatters/stdout/http_dicattack.rb +1 -1
  182. data/components/reporters/plugin_formatters/stdout/login_script.rb +1 -1
  183. data/components/reporters/plugin_formatters/stdout/metrics.rb +11 -1
  184. data/components/reporters/plugin_formatters/stdout/uncommon_headers.rb +1 -1
  185. data/components/reporters/plugin_formatters/stdout/uniformity.rb +1 -1
  186. data/components/reporters/plugin_formatters/stdout/vector_collector.rb +1 -1
  187. data/components/reporters/plugin_formatters/stdout/waf_detector.rb +1 -1
  188. data/components/reporters/plugin_formatters/xml/autologin.rb +1 -1
  189. data/components/reporters/plugin_formatters/xml/content_types.rb +10 -7
  190. data/components/reporters/plugin_formatters/xml/cookie_collector.rb +6 -3
  191. data/components/reporters/plugin_formatters/xml/exec.rb +1 -1
  192. data/components/reporters/plugin_formatters/xml/form_dicattack.rb +1 -1
  193. data/components/reporters/plugin_formatters/xml/healthmap.rb +1 -1
  194. data/components/reporters/plugin_formatters/xml/http_dicattack.rb +1 -1
  195. data/components/reporters/plugin_formatters/xml/login_script.rb +1 -1
  196. data/components/reporters/plugin_formatters/xml/metrics.rb +1 -1
  197. data/components/reporters/plugin_formatters/xml/uncommon_headers.rb +5 -2
  198. data/components/reporters/plugin_formatters/xml/uniformity.rb +1 -1
  199. data/components/reporters/plugin_formatters/xml/vector_collector.rb +8 -5
  200. data/components/reporters/plugin_formatters/xml/waf_detector.rb +1 -1
  201. data/components/reporters/stdout.rb +3 -2
  202. data/components/reporters/txt.rb +1 -1
  203. data/components/reporters/xml/schema.xsd +29 -13
  204. data/components/reporters/xml.rb +40 -23
  205. data/components/reporters/yaml.rb +1 -1
  206. data/config/write_paths.yml +4 -0
  207. data/lib/arachni/banner.rb +1 -1
  208. data/lib/arachni/browser/element_locator.rb +9 -5
  209. data/lib/arachni/browser/javascript/dom_monitor.rb +1 -1
  210. data/lib/arachni/browser/javascript/proxy/stub.rb +1 -1
  211. data/lib/arachni/browser/javascript/proxy.rb +1 -1
  212. data/lib/arachni/browser/javascript/scripts/dom_monitor.js +329 -72
  213. data/lib/arachni/browser/javascript/scripts/polyfills.js +0 -28
  214. data/lib/arachni/browser/javascript/scripts/taint_tracer.js +81 -25
  215. data/lib/arachni/browser/javascript/taint_tracer/frame/called_function.rb +1 -1
  216. data/lib/arachni/browser/javascript/taint_tracer/frame.rb +1 -1
  217. data/lib/arachni/browser/javascript/taint_tracer/sink/base.rb +1 -1
  218. data/lib/arachni/browser/javascript/taint_tracer/sink/data_flow.rb +1 -1
  219. data/lib/arachni/browser/javascript/taint_tracer/sink/execution_flow.rb +1 -1
  220. data/lib/arachni/browser/javascript/taint_tracer.rb +1 -1
  221. data/lib/arachni/browser/javascript.rb +111 -198
  222. data/lib/arachni/browser.rb +309 -382
  223. data/lib/arachni/browser_cluster/job/result.rb +1 -1
  224. data/lib/arachni/browser_cluster/job.rb +9 -2
  225. data/lib/arachni/browser_cluster/jobs/browser_provider.rb +8 -2
  226. data/lib/arachni/browser_cluster/jobs/dom_exploration/event_trigger/result.rb +1 -1
  227. data/lib/arachni/browser_cluster/jobs/dom_exploration/event_trigger.rb +1 -1
  228. data/lib/arachni/browser_cluster/jobs/dom_exploration/result.rb +1 -1
  229. data/lib/arachni/browser_cluster/jobs/dom_exploration.rb +13 -1
  230. data/lib/arachni/browser_cluster/jobs/taint_trace/event_trigger/result.rb +1 -1
  231. data/lib/arachni/browser_cluster/jobs/taint_trace/event_trigger.rb +1 -1
  232. data/lib/arachni/browser_cluster/jobs/taint_trace/result.rb +1 -1
  233. data/lib/arachni/browser_cluster/jobs/taint_trace.rb +1 -1
  234. data/lib/arachni/browser_cluster/worker.rb +97 -87
  235. data/lib/arachni/browser_cluster.rb +79 -62
  236. data/lib/arachni/check/auditor.rb +161 -155
  237. data/lib/arachni/check/base.rb +1 -1
  238. data/lib/arachni/check/manager.rb +1 -1
  239. data/lib/arachni/check.rb +1 -1
  240. data/lib/arachni/component/base.rb +3 -1
  241. data/lib/arachni/component/manager.rb +1 -1
  242. data/lib/arachni/component/options/address.rb +1 -1
  243. data/lib/arachni/component/options/base.rb +1 -1
  244. data/lib/arachni/component/options/bool.rb +1 -1
  245. data/lib/arachni/component/options/float.rb +1 -1
  246. data/lib/arachni/component/options/int.rb +1 -1
  247. data/lib/arachni/component/options/multiple_choice.rb +1 -1
  248. data/lib/arachni/component/options/object.rb +1 -1
  249. data/lib/arachni/component/options/path.rb +1 -1
  250. data/lib/arachni/component/options/port.rb +1 -1
  251. data/lib/arachni/component/options/string.rb +1 -1
  252. data/lib/arachni/component/options/url.rb +1 -1
  253. data/lib/arachni/component/options.rb +1 -1
  254. data/lib/arachni/component/output.rb +8 -2
  255. data/lib/arachni/component/utilities.rb +1 -1
  256. data/lib/arachni/component.rb +1 -1
  257. data/lib/arachni/data/framework/rpc.rb +2 -2
  258. data/lib/arachni/data/framework.rb +3 -2
  259. data/lib/arachni/data/issues.rb +1 -1
  260. data/lib/arachni/data/plugins.rb +1 -1
  261. data/lib/arachni/data/session.rb +1 -1
  262. data/lib/arachni/data.rb +1 -1
  263. data/lib/arachni/element/base.rb +1 -1
  264. data/lib/arachni/element/body.rb +1 -1
  265. data/lib/arachni/element/capabilities/analyzable/differential.rb +142 -175
  266. data/lib/arachni/element/capabilities/analyzable/signature.rb +40 -18
  267. data/lib/arachni/element/capabilities/analyzable/timeout.rb +1 -1
  268. data/lib/arachni/element/capabilities/analyzable.rb +1 -1
  269. data/lib/arachni/element/capabilities/auditable/buffered.rb +92 -0
  270. data/lib/arachni/element/capabilities/auditable/line_buffered.rb +103 -0
  271. data/lib/arachni/element/capabilities/auditable.rb +2 -8
  272. data/lib/arachni/element/capabilities/dom_only.rb +1 -1
  273. data/lib/arachni/element/capabilities/inputtable.rb +6 -2
  274. data/lib/arachni/element/capabilities/mutable.rb +1 -1
  275. data/lib/arachni/element/capabilities/refreshable.rb +1 -1
  276. data/lib/arachni/element/capabilities/submittable.rb +1 -1
  277. data/lib/arachni/element/capabilities/with_auditor/output.rb +4 -3
  278. data/lib/arachni/element/capabilities/with_auditor.rb +1 -1
  279. data/lib/arachni/element/capabilities/with_dom.rb +1 -1
  280. data/lib/arachni/element/capabilities/with_node.rb +3 -3
  281. data/lib/arachni/element/capabilities/with_scope/scope.rb +1 -1
  282. data/lib/arachni/element/capabilities/with_scope.rb +1 -1
  283. data/lib/arachni/element/capabilities/with_source.rb +2 -2
  284. data/lib/arachni/element/cookie/capabilities/inputtable.rb +1 -1
  285. data/lib/arachni/element/cookie/capabilities/mutable.rb +1 -1
  286. data/lib/arachni/element/cookie/capabilities/with_dom.rb +1 -1
  287. data/lib/arachni/element/cookie/dom.rb +1 -1
  288. data/lib/arachni/element/cookie.rb +49 -24
  289. data/lib/arachni/element/dom/capabilities/auditable.rb +44 -3
  290. data/lib/arachni/element/dom/capabilities/inputtable.rb +1 -1
  291. data/lib/arachni/element/dom/capabilities/locatable.rb +1 -1
  292. data/lib/arachni/element/dom/capabilities/mutable.rb +7 -3
  293. data/lib/arachni/element/dom/capabilities/submittable.rb +51 -22
  294. data/lib/arachni/element/dom.rb +1 -1
  295. data/lib/arachni/element/form/capabilities/auditable.rb +1 -1
  296. data/lib/arachni/element/form/capabilities/mutable.rb +16 -11
  297. data/lib/arachni/element/form/capabilities/submittable.rb +1 -1
  298. data/lib/arachni/element/form/capabilities/with_dom.rb +1 -1
  299. data/lib/arachni/element/form/dom.rb +1 -1
  300. data/lib/arachni/element/form.rb +21 -32
  301. data/lib/arachni/element/generic_dom.rb +1 -1
  302. data/lib/arachni/element/header/capabilities/inputtable.rb +1 -1
  303. data/lib/arachni/element/header/capabilities/mutable.rb +1 -1
  304. data/lib/arachni/element/header.rb +3 -1
  305. data/lib/arachni/element/json/capabilities/inputtable.rb +1 -1
  306. data/lib/arachni/element/json/capabilities/mutable.rb +1 -1
  307. data/lib/arachni/element/json.rb +4 -8
  308. data/lib/arachni/element/link/capabilities/auditable.rb +1 -1
  309. data/lib/arachni/element/link/capabilities/submittable.rb +1 -1
  310. data/lib/arachni/element/link/capabilities/with_dom.rb +1 -1
  311. data/lib/arachni/element/link/dom/capabilities/submittable.rb +1 -1
  312. data/lib/arachni/element/link/dom.rb +1 -1
  313. data/lib/arachni/element/link.rb +11 -30
  314. data/lib/arachni/element/link_template/capabilities/auditable.rb +1 -1
  315. data/lib/arachni/element/link_template/capabilities/inputtable.rb +1 -1
  316. data/lib/arachni/element/link_template/capabilities/with_dom.rb +1 -1
  317. data/lib/arachni/element/link_template/dom/capabilities/submittable.rb +1 -1
  318. data/lib/arachni/element/link_template/dom.rb +2 -2
  319. data/lib/arachni/element/link_template.rb +10 -19
  320. data/lib/arachni/element/nested_cookie/capabilities/submittable.rb +35 -0
  321. data/lib/arachni/element/nested_cookie.rb +370 -0
  322. data/lib/arachni/element/path.rb +1 -1
  323. data/lib/arachni/element/server.rb +11 -11
  324. data/lib/arachni/element/ui_form/dom.rb +1 -1
  325. data/lib/arachni/element/ui_form.rb +5 -6
  326. data/lib/arachni/element/ui_input/dom.rb +1 -1
  327. data/lib/arachni/element/ui_input.rb +4 -6
  328. data/lib/arachni/element/xml/capabilities/inputtable.rb +1 -1
  329. data/lib/arachni/element/xml/capabilities/mutable.rb +1 -1
  330. data/lib/arachni/element/xml.rb +3 -7
  331. data/lib/arachni/element_filter.rb +1 -1
  332. data/lib/arachni/error.rb +1 -1
  333. data/lib/arachni/ethon/easy.rb +1 -1
  334. data/lib/arachni/framework/parts/audit.rb +6 -1
  335. data/lib/arachni/framework/parts/browser.rb +14 -14
  336. data/lib/arachni/framework/parts/check.rb +1 -1
  337. data/lib/arachni/framework/parts/data.rb +1 -1
  338. data/lib/arachni/framework/parts/platform.rb +1 -1
  339. data/lib/arachni/framework/parts/plugin.rb +1 -1
  340. data/lib/arachni/framework/parts/report.rb +3 -3
  341. data/lib/arachni/framework/parts/scope.rb +1 -1
  342. data/lib/arachni/framework/parts/state.rb +1 -1
  343. data/lib/arachni/framework.rb +1 -1
  344. data/lib/arachni/http/client/dynamic_404_handler.rb +74 -16
  345. data/lib/arachni/http/client.rb +38 -11
  346. data/lib/arachni/http/cookie_jar.rb +13 -8
  347. data/lib/arachni/http/headers.rb +11 -5
  348. data/lib/arachni/http/message/scope.rb +1 -1
  349. data/lib/arachni/http/message.rb +10 -9
  350. data/lib/arachni/http/proxy_server/connection.rb +110 -82
  351. data/lib/arachni/http/proxy_server/ssl-interceptor-cacert.pem +18 -32
  352. data/lib/arachni/http/proxy_server/ssl-interceptor-cakey.pem +28 -49
  353. data/lib/arachni/http/proxy_server/ssl_interceptor.rb +8 -6
  354. data/lib/arachni/http/proxy_server/tunnel.rb +4 -4
  355. data/lib/arachni/http/proxy_server.rb +44 -11
  356. data/lib/arachni/http/request/scope.rb +1 -1
  357. data/lib/arachni/http/request.rb +239 -41
  358. data/lib/arachni/http/response/scope.rb +1 -1
  359. data/lib/arachni/http/response.rb +73 -10
  360. data/lib/arachni/http.rb +1 -1
  361. data/lib/arachni/issue/severity/base.rb +1 -1
  362. data/lib/arachni/issue/severity.rb +1 -1
  363. data/lib/arachni/issue.rb +42 -14
  364. data/lib/arachni/option_group.rb +1 -1
  365. data/lib/arachni/option_groups/audit.rb +11 -2
  366. data/lib/arachni/option_groups/browser_cluster.rb +32 -4
  367. data/lib/arachni/option_groups/datastore.rb +1 -1
  368. data/lib/arachni/option_groups/dispatcher.rb +1 -1
  369. data/lib/arachni/option_groups/http.rb +39 -10
  370. data/lib/arachni/option_groups/input.rb +1 -1
  371. data/lib/arachni/option_groups/output.rb +1 -1
  372. data/lib/arachni/option_groups/paths.rb +12 -1
  373. data/lib/arachni/option_groups/rpc.rb +1 -1
  374. data/lib/arachni/option_groups/scope.rb +58 -4
  375. data/lib/arachni/option_groups/session.rb +1 -1
  376. data/lib/arachni/option_groups/snapshot.rb +1 -1
  377. data/lib/arachni/option_groups.rb +1 -1
  378. data/lib/arachni/options.rb +23 -4
  379. data/lib/arachni/page/dom/transition.rb +5 -2
  380. data/lib/arachni/page/dom.rb +46 -54
  381. data/lib/arachni/page/scope.rb +1 -1
  382. data/lib/arachni/page.rb +10 -8
  383. data/lib/arachni/parser/document.rb +34 -0
  384. data/lib/arachni/parser/extractors/base.rb +48 -0
  385. data/lib/arachni/parser/nodes/base.rb +22 -0
  386. data/lib/arachni/parser/nodes/comment.rb +32 -0
  387. data/lib/arachni/parser/nodes/element/with_attributes/attributes.rb +31 -0
  388. data/lib/arachni/parser/nodes/element/with_attributes.rb +35 -0
  389. data/lib/arachni/parser/nodes/element.rb +48 -0
  390. data/lib/arachni/parser/nodes/text.rb +32 -0
  391. data/lib/arachni/parser/nodes/with_value.rb +29 -0
  392. data/lib/arachni/parser/sax.rb +76 -0
  393. data/lib/arachni/parser/with_children/search.rb +92 -0
  394. data/lib/arachni/parser/with_children.rb +35 -0
  395. data/lib/arachni/parser.rb +181 -78
  396. data/lib/arachni/platform/fingerprinter.rb +1 -1
  397. data/lib/arachni/platform/list.rb +1 -1
  398. data/lib/arachni/platform/manager.rb +2 -2
  399. data/lib/arachni/platform.rb +1 -1
  400. data/lib/arachni/plugin/base.rb +2 -2
  401. data/lib/arachni/plugin/formatter.rb +1 -1
  402. data/lib/arachni/plugin/manager.rb +8 -5
  403. data/lib/arachni/plugin.rb +1 -1
  404. data/lib/arachni/processes/dispatchers.rb +1 -1
  405. data/lib/arachni/processes/executables/base.rb +2 -1
  406. data/lib/arachni/processes/executables/browser.rb +0 -2
  407. data/lib/arachni/processes/helpers/dispatchers.rb +1 -1
  408. data/lib/arachni/processes/helpers/instances.rb +1 -1
  409. data/lib/arachni/processes/helpers/processes.rb +1 -1
  410. data/lib/arachni/processes/helpers.rb +1 -1
  411. data/lib/arachni/processes/instances.rb +1 -1
  412. data/lib/arachni/processes/manager.rb +18 -9
  413. data/lib/arachni/processes.rb +1 -1
  414. data/lib/arachni/report.rb +8 -1
  415. data/lib/arachni/reporter/base.rb +1 -1
  416. data/lib/arachni/reporter/formatter_manager.rb +1 -1
  417. data/lib/arachni/reporter/manager.rb +1 -1
  418. data/lib/arachni/reporter/options.rb +1 -10
  419. data/lib/arachni/reporter.rb +1 -1
  420. data/lib/arachni/rest/server/instance_helpers.rb +10 -1
  421. data/lib/arachni/rest/server.rb +13 -1
  422. data/lib/arachni/rpc/client/base.rb +1 -1
  423. data/lib/arachni/rpc/client/dispatcher.rb +1 -1
  424. data/lib/arachni/rpc/client/instance/framework.rb +1 -1
  425. data/lib/arachni/rpc/client/instance/service.rb +1 -1
  426. data/lib/arachni/rpc/client/instance.rb +1 -1
  427. data/lib/arachni/rpc/serializer.rb +1 -1
  428. data/lib/arachni/rpc/server/active_options.rb +1 -1
  429. data/lib/arachni/rpc/server/base.rb +1 -1
  430. data/lib/arachni/rpc/server/check/manager.rb +1 -1
  431. data/lib/arachni/rpc/server/dispatcher/node.rb +1 -1
  432. data/lib/arachni/rpc/server/dispatcher/service.rb +1 -1
  433. data/lib/arachni/rpc/server/dispatcher.rb +1 -1
  434. data/lib/arachni/rpc/server/framework/distributor.rb +1 -1
  435. data/lib/arachni/rpc/server/framework/master.rb +1 -1
  436. data/lib/arachni/rpc/server/framework/multi_instance.rb +1 -1
  437. data/lib/arachni/rpc/server/framework/slave.rb +1 -1
  438. data/lib/arachni/rpc/server/framework.rb +1 -1
  439. data/lib/arachni/rpc/server/instance.rb +1 -1
  440. data/lib/arachni/rpc/server/output.rb +1 -1
  441. data/lib/arachni/rpc/server/plugin/manager.rb +1 -1
  442. data/lib/arachni/ruby/array.rb +1 -1
  443. data/lib/arachni/ruby/hash.rb +1 -1
  444. data/lib/arachni/ruby/object.rb +1 -1
  445. data/lib/arachni/ruby/set.rb +1 -1
  446. data/lib/arachni/ruby/string.rb +9 -5
  447. data/lib/arachni/ruby/webrick/cookie.rb +1 -1
  448. data/lib/arachni/ruby/webrick/httprequest.rb +1 -1
  449. data/lib/arachni/ruby/webrick.rb +1 -1
  450. data/lib/arachni/ruby.rb +1 -1
  451. data/lib/arachni/scope.rb +1 -1
  452. data/lib/arachni/selenium/webdriver/element.rb +4 -4
  453. data/lib/arachni/selenium/webdriver/remote/typhoeus.rb +59 -0
  454. data/lib/arachni/session.rb +32 -13
  455. data/lib/arachni/snapshot.rb +2 -2
  456. data/lib/arachni/state/audit.rb +1 -1
  457. data/lib/arachni/state/element_filter.rb +1 -1
  458. data/lib/arachni/state/framework/rpc.rb +1 -1
  459. data/lib/arachni/state/framework.rb +1 -1
  460. data/lib/arachni/state/http.rb +2 -2
  461. data/lib/arachni/state/options.rb +1 -1
  462. data/lib/arachni/state/plugins.rb +1 -1
  463. data/lib/arachni/state.rb +1 -1
  464. data/lib/arachni/support/buffer/autoflush.rb +1 -1
  465. data/lib/arachni/support/buffer/base.rb +1 -1
  466. data/lib/arachni/support/buffer.rb +1 -1
  467. data/lib/arachni/support/cache/base.rb +1 -1
  468. data/lib/arachni/support/cache/least_cost_replacement.rb +1 -1
  469. data/lib/arachni/support/cache/least_recently_pushed.rb +1 -1
  470. data/lib/arachni/support/cache/least_recently_used.rb +1 -1
  471. data/lib/arachni/support/cache/preference.rb +1 -1
  472. data/lib/arachni/support/cache/random_replacement.rb +1 -1
  473. data/lib/arachni/support/cache.rb +1 -1
  474. data/lib/arachni/support/crypto/rsa_aes_cbc.rb +1 -1
  475. data/lib/arachni/support/crypto.rb +1 -1
  476. data/lib/arachni/support/database/base.rb +16 -10
  477. data/lib/arachni/support/database/hash.rb +1 -1
  478. data/lib/arachni/support/database/queue.rb +1 -1
  479. data/lib/arachni/support/database.rb +1 -1
  480. data/lib/arachni/support/glob.rb +1 -1
  481. data/lib/arachni/support/lookup/base.rb +1 -1
  482. data/lib/arachni/support/lookup/hash_set.rb +1 -1
  483. data/lib/arachni/support/lookup/moolb.rb +1 -1
  484. data/lib/arachni/support/lookup.rb +1 -1
  485. data/lib/arachni/support/mixins/observable.rb +1 -1
  486. data/lib/arachni/support/mixins/terminal.rb +1 -1
  487. data/lib/arachni/support/mixins.rb +1 -1
  488. data/lib/arachni/support/profiler.rb +52 -13
  489. data/lib/arachni/support/signature.rb +18 -6
  490. data/lib/arachni/support.rb +1 -1
  491. data/lib/arachni/trainer.rb +55 -39
  492. data/lib/arachni/ui/foo/output.rb +1 -1
  493. data/lib/arachni/uri/scope.rb +15 -13
  494. data/lib/arachni/uri.rb +129 -103
  495. data/lib/arachni/utilities.rb +10 -10
  496. data/lib/arachni/version.rb +1 -1
  497. data/lib/arachni.rb +1 -7
  498. data/lib/version +1 -1
  499. data/spec/arachni/browser/element_locator_spec.rb +42 -18
  500. data/spec/arachni/browser/javascript/dom_monitor_spec.rb +264 -109
  501. data/spec/arachni/browser/javascript/polyfills_spec.rb +0 -15
  502. data/spec/arachni/browser/javascript/proxy_spec.rb +0 -10
  503. data/spec/arachni/browser/javascript/taint_tracer_spec.rb +43 -118
  504. data/spec/arachni/browser/javascript_spec.rb +95 -60
  505. data/spec/arachni/browser_cluster/job_spec.rb +23 -8
  506. data/spec/arachni/browser_cluster/jobs/dom_exploration_spec.rb +6 -1
  507. data/spec/arachni/browser_cluster/worker_spec.rb +29 -87
  508. data/spec/arachni/browser_cluster_spec.rb +124 -43
  509. data/spec/arachni/browser_spec.rb +463 -421
  510. data/spec/arachni/check/auditor_spec.rb +162 -198
  511. data/spec/arachni/data/framework/rpc_spec.rb +1 -1
  512. data/spec/arachni/data/framework_spec.rb +1 -1
  513. data/spec/arachni/element/capabilities/analyzable/signature_spec.rb +46 -3
  514. data/spec/arachni/element/cookie/dom_spec.rb +1 -1
  515. data/spec/arachni/element/cookie_spec.rb +159 -64
  516. data/spec/arachni/element/form/dom_spec.rb +1 -1
  517. data/spec/arachni/element/form_spec.rb +101 -54
  518. data/spec/arachni/element/header_spec.rb +3 -1
  519. data/spec/arachni/element/json_spec.rb +2 -0
  520. data/spec/arachni/element/link/dom_spec.rb +2 -2
  521. data/spec/arachni/element/link_spec.rb +46 -15
  522. data/spec/arachni/element/link_template/dom_spec.rb +1 -1
  523. data/spec/arachni/element/link_template_spec.rb +36 -12
  524. data/spec/arachni/element/nested_cookie_spec.rb +687 -0
  525. data/spec/arachni/element/server_spec.rb +22 -5
  526. data/spec/arachni/element/ui_form/dom_spec.rb +1 -1
  527. data/spec/arachni/element/ui_form_spec.rb +2 -2
  528. data/spec/arachni/element/ui_input/dom_spec.rb +1 -1
  529. data/spec/arachni/element/ui_input_spec.rb +1 -1
  530. data/spec/arachni/element/xml_spec.rb +5 -3
  531. data/spec/arachni/framework/parts/audit_spec.rb +2 -14
  532. data/spec/arachni/framework/parts/data_spec.rb +0 -6
  533. data/spec/arachni/http/client/dynamic_404_handlers_spec.rb +126 -0
  534. data/spec/arachni/http/client_spec.rb +96 -36
  535. data/spec/arachni/http/cookie_jar_spec.rb +2 -2
  536. data/spec/arachni/http/headers_spec.rb +59 -12
  537. data/spec/arachni/http/proxy_server_spec.rb +58 -25
  538. data/spec/arachni/http/request_spec.rb +382 -35
  539. data/spec/arachni/http/response_spec.rb +135 -7
  540. data/spec/arachni/issue_spec.rb +21 -2
  541. data/spec/arachni/option_groups/browser_cluster_spec.rb +17 -0
  542. data/spec/arachni/option_groups/http_spec.rb +21 -6
  543. data/spec/arachni/option_groups/paths_spec.rb +23 -1
  544. data/spec/arachni/option_groups/scope_spec.rb +27 -7
  545. data/spec/arachni/options_spec.rb +8 -1
  546. data/spec/arachni/page/dom_spec.rb +20 -6
  547. data/spec/arachni/page_spec.rb +8 -7
  548. data/spec/arachni/parser/document_spec.rb +49 -0
  549. data/spec/arachni/parser/nodes/comment_spec.rb +24 -0
  550. data/spec/arachni/parser/nodes/element/with_attributes/attributes_spec.rb +40 -0
  551. data/spec/arachni/parser/nodes/element/with_attributes_spec.rb +50 -0
  552. data/spec/arachni/parser/nodes/element_spec.rb +18 -0
  553. data/spec/arachni/parser/nodes/text_spec.rb +24 -0
  554. data/spec/arachni/parser/sax_spec.rb +88 -0
  555. data/spec/arachni/parser/with_children/search_spec.rb +146 -0
  556. data/spec/arachni/parser/with_children_spec.rb +37 -0
  557. data/spec/arachni/parser_spec.rb +211 -27
  558. data/spec/arachni/platform/list_spec.rb +1 -2
  559. data/spec/arachni/report_spec.rb +9 -2
  560. data/spec/arachni/reporter/options_spec.rb +0 -14
  561. data/spec/arachni/rest/server_spec.rb +91 -8
  562. data/spec/arachni/rpc/server/active_options_spec.rb +1 -1
  563. data/spec/arachni/rpc/server/framework/distributor_spec.rb +6 -6
  564. data/spec/arachni/ruby/string_spec.rb +6 -0
  565. data/spec/arachni/session_spec.rb +69 -8
  566. data/spec/arachni/snapshot_spec.rb +1 -1
  567. data/spec/arachni/state/framework_spec.rb +2 -2
  568. data/spec/arachni/support/signature_spec.rb +58 -0
  569. data/spec/arachni/trainer_spec.rb +102 -21
  570. data/spec/arachni/uri_spec.rb +11 -8
  571. data/spec/arachni/utilities_spec.rb +3 -3
  572. data/spec/components/checks/active/code_injection_spec.rb +12 -7
  573. data/spec/components/checks/active/code_injection_timing_spec.rb +4 -3
  574. data/spec/components/checks/active/csrf_spec.rb +1 -21
  575. data/spec/components/checks/active/file_inclusion_spec.rb +15 -10
  576. data/spec/components/checks/active/ldap_injection_spec.rb +5 -4
  577. data/spec/components/checks/active/no_sql_injection_differential_spec.rb +1 -1
  578. data/spec/components/checks/active/no_sql_injection_spec.rb +5 -4
  579. data/spec/components/checks/active/os_cmd_injection_spec.rb +6 -4
  580. data/spec/components/checks/active/os_cmd_injection_timing_spec.rb +4 -3
  581. data/spec/components/checks/active/path_traversal_spec.rb +18 -15
  582. data/spec/components/checks/active/response_splitting_spec.rb +5 -4
  583. data/spec/components/checks/active/rfi_spec.rb +9 -8
  584. data/spec/components/checks/active/source_code_disclosure_spec.rb +33 -10
  585. data/spec/components/checks/active/sql_injection_differential_spec.rb +1 -1
  586. data/spec/components/checks/active/sql_injection_spec.rb +61 -35
  587. data/spec/components/checks/active/sql_injection_timing_spec.rb +11 -8
  588. data/spec/components/checks/active/unvalidated_redirect_spec.rb +9 -8
  589. data/spec/components/checks/active/xpath_injection_spec.rb +5 -4
  590. data/spec/components/checks/active/xss_dom_script_context_spec.rb +6 -10
  591. data/spec/components/checks/active/xss_dom_spec.rb +2 -2
  592. data/spec/components/checks/active/xss_event_spec.rb +11 -3
  593. data/spec/components/checks/active/xss_script_context_spec.rb +8 -7
  594. data/spec/components/checks/active/xss_spec.rb +7 -6
  595. data/spec/components/checks/active/xss_tag_spec.rb +11 -3
  596. data/spec/components/checks/passive/backup_directories_spec.rb +3 -1
  597. data/spec/components/checks/passive/backup_files_spec.rb +4 -1
  598. data/spec/components/checks/passive/grep/insecure_cookies_spec.rb +2 -2
  599. data/spec/components/checks/passive/grep/x_frame_options_spec.rb +6 -0
  600. data/spec/components/path_extractors/comments_spec.rb +3 -1
  601. data/spec/components/path_extractors/data_url_spec.rb +6 -2
  602. data/spec/components/path_extractors/links_spec.rb +1 -1
  603. data/spec/components/plugins/autologin_spec.rb +2 -2
  604. data/spec/components/plugins/webhook_notify_spec.rb +69 -0
  605. data/spec/spec_helper.rb +2 -1
  606. data/spec/support/factories/http/response.rb +1 -1
  607. data/spec/support/factories/issue.rb +1 -2
  608. data/spec/support/factories/page/dom.rb +6 -0
  609. data/spec/support/factories/scan_report.rb +1 -0
  610. data/spec/support/factories/vector.rb +7 -3
  611. data/spec/support/fixtures/check_with_invalid_platforms/with_invalid_platforms.rb +1 -1
  612. data/spec/support/fixtures/checks/test.rb +4 -4
  613. data/spec/support/fixtures/checks/test2.rb +1 -1
  614. data/spec/support/fixtures/checks/test3.rb +1 -1
  615. data/spec/support/fixtures/cookies.txt +2 -2
  616. data/spec/support/fixtures/executables/node.rb +2 -3
  617. data/spec/support/fixtures/fingerprinters/test.rb +1 -1
  618. data/spec/support/fixtures/nested_cookies.txt +11 -0
  619. data/spec/support/fixtures/plugins/bad.rb +1 -1
  620. data/spec/support/fixtures/plugins/defaults/default.rb +1 -1
  621. data/spec/support/fixtures/plugins/distributable.rb +1 -1
  622. data/spec/support/fixtures/plugins/loop.rb +1 -1
  623. data/spec/support/fixtures/plugins/suspendable.rb +1 -1
  624. data/spec/support/fixtures/plugins/wait.rb +1 -1
  625. data/spec/support/fixtures/plugins/with_options.rb +1 -1
  626. data/spec/support/fixtures/plugins_with_priorities/p0.rb +1 -1
  627. data/spec/support/fixtures/plugins_with_priorities/p00.rb +1 -1
  628. data/spec/support/fixtures/plugins_with_priorities/p1.rb +1 -1
  629. data/spec/support/fixtures/plugins_with_priorities/p2.rb +1 -1
  630. data/spec/support/fixtures/plugins_with_priorities/p22.rb +1 -1
  631. data/spec/support/fixtures/plugins_with_priorities/p222.rb +1 -1
  632. data/spec/support/fixtures/plugins_with_priorities/p_nil.rb +1 -1
  633. data/spec/support/fixtures/plugins_with_priorities/p_nil2.rb +1 -1
  634. data/spec/support/fixtures/report.afr +0 -0
  635. data/spec/support/fixtures/reporters/base_spec/plugin_formatters/with_formatters/foobar.rb +1 -1
  636. data/spec/support/fixtures/reporters/base_spec/with_formatters.rb +1 -1
  637. data/spec/support/fixtures/reporters/base_spec/with_outfile.rb +1 -1
  638. data/spec/support/fixtures/reporters/base_spec/without_outfile.rb +1 -1
  639. data/spec/support/fixtures/reporters/manager_spec/afr.rb +1 -1
  640. data/spec/support/fixtures/reporters/manager_spec/error.rb +1 -1
  641. data/spec/support/fixtures/reporters/manager_spec/foo.rb +1 -1
  642. data/spec/support/fixtures/run_check/body.rb +1 -1
  643. data/spec/support/fixtures/run_check/cookies.rb +1 -1
  644. data/spec/support/fixtures/run_check/empty.rb +1 -1
  645. data/spec/support/fixtures/run_check/flch.rb +1 -1
  646. data/spec/support/fixtures/run_check/forms.rb +1 -1
  647. data/spec/support/fixtures/run_check/headers.rb +1 -1
  648. data/spec/support/fixtures/run_check/links.rb +1 -1
  649. data/spec/support/fixtures/run_check/nil.rb +1 -1
  650. data/spec/support/fixtures/run_check/path.rb +1 -1
  651. data/spec/support/fixtures/run_check/server.rb +1 -1
  652. data/spec/support/fixtures/signature_check/signature.rb +1 -1
  653. data/spec/support/fixtures/wait_check/wait.rb +1 -1
  654. data/spec/support/helpers/browser_cluster/jobs/taint_tracer.rb +0 -3
  655. data/spec/support/helpers/framework.rb +1 -1
  656. data/spec/support/helpers/misc.rb +1 -1
  657. data/spec/support/helpers/paths.rb +1 -1
  658. data/spec/support/helpers/requires.rb +1 -1
  659. data/spec/support/helpers/resets.rb +1 -1
  660. data/spec/support/helpers/web_server.rb +1 -1
  661. data/spec/support/lib/factory.rb +1 -1
  662. data/spec/support/lib/web_server_client.rb +1 -1
  663. data/spec/support/lib/web_server_dispatcher.rb +1 -1
  664. data/spec/support/lib/web_server_manager.rb +4 -2
  665. data/spec/support/servers/arachni/browser/javascript/dom_monitor.rb +48 -0
  666. data/spec/support/servers/arachni/browser/javascript/taint_tracer.rb +15 -3
  667. data/spec/support/servers/arachni/browser.rb +275 -4
  668. data/spec/support/servers/arachni/check/auditor.rb +9 -0
  669. data/spec/support/servers/arachni/element/cookie.rb +34 -0
  670. data/spec/support/servers/arachni/element/form/form_dom.rb +1 -0
  671. data/spec/support/servers/arachni/element/form.rb +36 -2
  672. data/spec/support/servers/arachni/element/header.rb +36 -1
  673. data/spec/support/servers/arachni/element/json.rb +33 -0
  674. data/spec/support/servers/arachni/element/link.rb +33 -1
  675. data/spec/support/servers/arachni/element/link_template.rb +37 -5
  676. data/spec/support/servers/arachni/element/nested_cookie.rb +84 -0
  677. data/spec/support/servers/arachni/element/xml.rb +33 -0
  678. data/spec/support/servers/arachni/http/client/dynamic_404_handler.rb +36 -0
  679. data/spec/support/servers/arachni/http/client/dynamic_404_handler_redirect_1.rb +18 -0
  680. data/spec/support/servers/arachni/http/client/dynamic_404_handler_redirect_2.rb +11 -0
  681. data/spec/support/servers/arachni/http/client.rb +43 -4
  682. data/spec/support/servers/arachni/http/proxy_server.rb +12 -0
  683. data/spec/support/servers/arachni/parser.rb +6 -0
  684. data/spec/support/servers/arachni/session.rb +24 -1
  685. data/spec/support/servers/checks/active/code_injection.rb +18 -0
  686. data/spec/support/servers/checks/active/code_injection_timing.rb +18 -0
  687. data/spec/support/servers/checks/active/csrf.rb +0 -76
  688. data/spec/support/servers/checks/active/file_inclusion.rb +19 -1
  689. data/spec/support/servers/checks/active/ldap_injection.rb +18 -0
  690. data/spec/support/servers/checks/active/no_sql_injection.rb +27 -0
  691. data/spec/support/servers/checks/active/no_sql_injection_differential.rb +19 -0
  692. data/spec/support/servers/checks/active/os_cmd_injection.rb +29 -0
  693. data/spec/support/servers/checks/active/os_cmd_injection_timing.rb +18 -1
  694. data/spec/support/servers/checks/active/path_traversal.rb +30 -3
  695. data/spec/support/servers/checks/active/response_splitting.rb +30 -1
  696. data/spec/support/servers/checks/active/rfi.rb +30 -2
  697. data/spec/support/servers/checks/active/session_fixation.rb +1 -3
  698. data/spec/support/servers/checks/active/source_code_disclosure.rb +16 -0
  699. data/spec/support/servers/checks/active/sql_injection/java +2 -0
  700. data/spec/support/servers/checks/active/sql_injection.rb +27 -0
  701. data/spec/support/servers/checks/active/sql_injection_differential.rb +19 -0
  702. data/spec/support/servers/checks/active/sql_injection_timing.rb +19 -1
  703. data/spec/support/servers/checks/active/unvalidated_redirect.rb +121 -1
  704. data/spec/support/servers/checks/active/xpath_injection.rb +27 -0
  705. data/spec/support/servers/checks/active/xss.rb +40 -0
  706. data/spec/support/servers/checks/active/xss_event.rb +23 -2
  707. data/spec/support/servers/checks/active/xss_script_context.rb +18 -0
  708. data/spec/support/servers/checks/active/xss_tag.rb +40 -0
  709. data/spec/support/servers/checks/passive/backup_files.rb +20 -1
  710. data/spec/support/servers/checks/passive/grep/cookie_set_for_parent_domain.rb +3 -5
  711. data/spec/support/servers/checks/passive/grep/insecure_cookies_https.rb +9 -0
  712. data/spec/support/servers/checks/passive/grep/x_frame_options.rb +5 -0
  713. data/spec/support/servers/plugins/autologin.rb +17 -1
  714. data/spec/support/servers/plugins/webhook_notify.rb +9 -0
  715. data/spec/support/shared/check.rb +1 -0
  716. data/spec/support/shared/element/capabilities/auditable/buffered.rb +791 -0
  717. data/spec/support/shared/element/capabilities/auditable/line_buffered.rb +797 -0
  718. data/spec/support/shared/element/capabilities/auditable.rb +28 -34
  719. data/spec/support/shared/element/capabilities/inputtable.rb +26 -0
  720. data/spec/support/shared/element/capabilities/with_node.rb +2 -2
  721. data/spec/support/shared/element/dom/submittable.rb +10 -10
  722. data/spec/support/shared/path_extractor.rb +17 -5
  723. data/ui/cli/framework/option_parser.rb +78 -13
  724. data/ui/cli/framework.rb +29 -8
  725. data/ui/cli/option_parser.rb +1 -1
  726. data/ui/cli/output.rb +10 -3
  727. data/ui/cli/reporter/option_parser.rb +1 -1
  728. data/ui/cli/reporter.rb +1 -1
  729. data/ui/cli/reproduce/option_parser.rb +90 -0
  730. data/ui/cli/reproduce.rb +228 -0
  731. data/ui/cli/rest/server/option_parser.rb +1 -1
  732. data/ui/cli/rest/server.rb +1 -1
  733. data/ui/cli/restored_framework/option_parser.rb +1 -1
  734. data/ui/cli/restored_framework.rb +1 -1
  735. data/ui/cli/rpc/client/dispatcher_monitor/option_parser.rb +1 -1
  736. data/ui/cli/rpc/client/dispatcher_monitor.rb +9 -11
  737. data/ui/cli/rpc/client/instance.rb +7 -4
  738. data/ui/cli/rpc/client/local/option_parser.rb +1 -1
  739. data/ui/cli/rpc/client/local.rb +1 -1
  740. data/ui/cli/rpc/client/remote/option_parser.rb +1 -1
  741. data/ui/cli/rpc/client/remote.rb +1 -1
  742. data/ui/cli/rpc/server/dispatcher/option_parser.rb +1 -1
  743. data/ui/cli/rpc/server/dispatcher.rb +1 -1
  744. data/ui/cli/utilities.rb +1 -1
  745. metadata +178 -79
  746. data/ACKNOWLEDGMENTS.md +0 -21
  747. data/AUTHORS.md +0 -3
  748. data/CONTRIBUTORS.md +0 -22
@@ -61,70 +61,6 @@ describe Arachni::Browser do
61
61
  pages_should_have_form_with_input( pages, 'by-ajax' )
62
62
  end
63
63
 
64
- context 'when the browser dies' do
65
- it 'kills the lifeline too' do
66
- Arachni::Processes::Manager.kill subject.browser_pid
67
- expect(Arachni::Processes::Manager.alive?(subject.lifeline_pid)).to be_falsey
68
- end
69
- end
70
-
71
- context 'when the lifeline dies' do
72
- it 'kills the browser too' do
73
- Arachni::Processes::Manager.kill subject.lifeline_pid
74
- expect(Arachni::Processes::Manager.alive?(subject.browser_pid)).to be_falsey
75
- end
76
- end
77
-
78
- describe '#alive?' do
79
- context 'when the lifeline is alive' do
80
- it 'returns true' do
81
- expect(Arachni::Processes::Manager.alive?(subject.lifeline_pid)).to be_truthy
82
- expect(subject).to be_alive
83
- end
84
- end
85
-
86
- context 'when the browser is dead' do
87
- it 'returns false' do
88
- Arachni::Processes::Manager.kill subject.browser_pid
89
-
90
- expect(subject).to_not be_alive
91
- end
92
- end
93
-
94
- context 'when the lifeline is dead' do
95
- it 'returns false' do
96
- Arachni::Processes::Manager << subject.browser_pid
97
- Arachni::Processes::Manager.kill subject.lifeline_pid
98
-
99
- expect(subject).to_not be_alive
100
- end
101
- end
102
- end
103
-
104
- describe '.has_executable?' do
105
- context 'when there is no executable browser' do
106
- it 'returns false' do
107
- allow(Selenium::WebDriver::PhantomJS).to receive(:path){ false }
108
- expect(described_class.has_executable?).to be_falsey
109
- end
110
- end
111
-
112
- context 'when there is an executable browser' do
113
- it 'returns true' do
114
- allow(Selenium::WebDriver::PhantomJS).to receive(:path){ __FILE__ }
115
- expect(described_class.has_executable?).to be_truthy
116
- end
117
- end
118
- end
119
-
120
- describe '.executable' do
121
- it 'returns the path to the browser executable' do
122
- stub = __FILE__
123
- allow(Selenium::WebDriver::PhantomJS).to receive(:path){ stub }
124
- expect(described_class.executable).to eq(stub)
125
- end
126
- end
127
-
128
64
  describe '#initialize' do
129
65
  describe ':concurrency' do
130
66
  it 'sets the HTTP request concurrency'
@@ -255,13 +191,6 @@ describe Arachni::Browser do
255
191
  end
256
192
  end
257
193
  end
258
-
259
- context 'when browser process spawn fails' do
260
- it "raises #{described_class::Error::Spawn}" do
261
- allow_any_instance_of(described_class).to receive(:spawn_phantomjs) { nil }
262
- expect { described_class.new }.to raise_error described_class::Error::Spawn
263
- end
264
- end
265
194
  end
266
195
 
267
196
  describe '#source_with_line_numbers' do
@@ -314,7 +243,7 @@ describe Arachni::Browser do
314
243
 
315
244
  time = Time.now
316
245
  subject.wait_for_timers
317
- expect(Time.now - time).to be < 0.2
246
+ expect(Time.now - time).to be < 0.3
318
247
  end
319
248
  end
320
249
  end
@@ -442,13 +371,25 @@ describe Arachni::Browser do
442
371
  end
443
372
 
444
373
  it 'pushes it to the existing transitions' do
445
- transition = { stuff: :here }
446
- captured = subject.capture_snapshot( stuff: :here )
374
+ transition = Arachni::Page::DOM::Transition.new(
375
+ :page, :load
376
+ )
377
+ captured = subject.capture_snapshot( transition )
447
378
 
448
379
  expect(captured.first.dom.transitions).to include transition
449
380
  end
450
381
  end
451
382
 
383
+ context 'when a page has the same transitions but different states' do
384
+ it 'only captures the first state' do
385
+ subject.load( "#{@url}/ever-changing-dom", take_snapshot: false )
386
+ expect(subject.capture_snapshot).to be_any
387
+
388
+ subject.load( "#{@url}/ever-changing-dom", take_snapshot: false )
389
+ expect(subject.capture_snapshot).to be_empty
390
+ end
391
+ end
392
+
452
393
  context 'when there are multiple windows open' do
453
394
 
454
395
  it 'captures snapshots from all windows' do
@@ -588,20 +529,6 @@ describe Arachni::Browser do
588
529
  end
589
530
  end
590
531
 
591
- context 'when a response is cached' do
592
- it 'is passed each response' do
593
- responses = []
594
- @browser.on_response { |response| responses << response }
595
-
596
- @browser.cache Arachni::HTTP::Client.get( @url, mode: :sync )
597
- @browser.goto @url
598
-
599
- response = responses.first
600
- expect(response).to be_kind_of Arachni::HTTP::Response
601
- expect(response.url).to eq(@url)
602
- end
603
- end
604
-
605
532
  context 'when a request is performed by the browser' do
606
533
  it 'is passed each response' do
607
534
  responses = []
@@ -655,7 +582,6 @@ describe Arachni::Browser do
655
582
  }
656
583
  } => :click
657
584
  },
658
- { "#{@url}level4" => :request },
659
585
  { "#{@url}level4" => :request }
660
586
  ],
661
587
  [
@@ -693,7 +619,6 @@ describe Arachni::Browser do
693
619
  } => :click
694
620
  },
695
621
  { "#{@url}level4" => :request },
696
- { "#{@url}level4" => :request },
697
622
  {
698
623
  {
699
624
  tag_name: 'div',
@@ -745,7 +670,6 @@ describe Arachni::Browser do
745
670
  }
746
671
  } => :click
747
672
  },
748
- { "#{@url}level4" => :request },
749
673
  { "#{@url}level4" => :request }
750
674
  ]
751
675
  ].map { |transitions| transitions_from_array( transitions ) })
@@ -781,7 +705,6 @@ describe Arachni::Browser do
781
705
 
782
706
  entry = doms[0].execution_flow_sinks[0]
783
707
  expect(entry.data).to eq([1])
784
- expect(entry.trace.size).to eq(3)
785
708
 
786
709
  expect(entry.trace[0].function.name).to eq('onClick')
787
710
  expect(entry.trace[0].function.source).to start_with 'function onClick'
@@ -805,7 +728,6 @@ describe Arachni::Browser do
805
728
 
806
729
  entry = doms[0].execution_flow_sinks[1]
807
730
  expect(entry.data).to eq([1])
808
- expect(entry.trace.size).to eq(4)
809
731
 
810
732
  expect(entry.trace[0].function.name).to eq('onClick3')
811
733
  expect(entry.trace[0].function.source).to start_with 'function onClick3'
@@ -850,7 +772,6 @@ describe Arachni::Browser do
850
772
 
851
773
  entry = doms[1].execution_flow_sinks[0]
852
774
  expect(entry.data).to eq([1])
853
- expect(entry.trace.size).to eq(2)
854
775
 
855
776
  expect(entry.trace[0].function.name).to eq('onClick')
856
777
  expect(entry.trace[0].function.source).to start_with 'function onClick'
@@ -870,7 +791,6 @@ describe Arachni::Browser do
870
791
 
871
792
  entry = doms[1].execution_flow_sinks[1]
872
793
  expect(entry.data).to eq([1])
873
- expect(entry.trace.size).to eq(3)
874
794
 
875
795
  expect(entry.trace[0].function.name).to eq('onClick3')
876
796
  expect(entry.trace[0].function.source).to start_with 'function onClick3'
@@ -908,7 +828,6 @@ describe Arachni::Browser do
908
828
 
909
829
  entry = doms[0].data_flow_sinks[0]
910
830
  expect(entry.function).to eq('blah')
911
- expect(entry.trace.size).to eq(3)
912
831
 
913
832
  expect(entry.trace[0].function.name).to eq('onClick')
914
833
  expect(entry.trace[0].function.source).to start_with 'function onClick'
@@ -932,7 +851,6 @@ describe Arachni::Browser do
932
851
 
933
852
  entry = doms[0].data_flow_sinks[1]
934
853
  expect(entry.function).to eq('blah')
935
- expect(entry.trace.size).to eq(4)
936
854
 
937
855
  expect(entry.trace[0].function.name).to eq('onClick3')
938
856
  expect(entry.trace[0].function.source).to start_with 'function onClick3'
@@ -963,7 +881,6 @@ describe Arachni::Browser do
963
881
 
964
882
  entry = doms[1].data_flow_sinks[0]
965
883
  expect(entry.function).to eq('blah')
966
- expect(entry.trace.size).to eq(2)
967
884
 
968
885
  expect(entry.trace[0].function.name).to eq('onClick')
969
886
  expect(entry.trace[0].function.source).to start_with 'function onClick'
@@ -983,7 +900,6 @@ describe Arachni::Browser do
983
900
 
984
901
  entry = doms[1].data_flow_sinks[1]
985
902
  expect(entry.function).to eq('blah')
986
- expect(entry.trace.size).to eq(3)
987
903
 
988
904
  expect(entry.trace[0].function.name).to eq('onClick3')
989
905
  expect(entry.trace[0].function.source).to start_with 'function onClick3'
@@ -1097,8 +1013,6 @@ describe Arachni::Browser do
1097
1013
 
1098
1014
  describe '#to_page' do
1099
1015
  it "converts the working window to an #{Arachni::Page}" do
1100
- ua = Arachni::Options.http.user_agent
1101
-
1102
1016
  @browser.load( @url )
1103
1017
  page = @browser.to_page
1104
1018
 
@@ -1111,14 +1025,16 @@ describe Arachni::Browser do
1111
1025
 
1112
1026
  it "assigns the proper #{Arachni::Page::DOM}#digest" do
1113
1027
  @browser.load( @url )
1114
- expect(@browser.to_page.dom.instance_variable_get(:@digest)).to eq(
1115
- '<HTML><HEAD><SCRIPT src=http://' <<
1116
- 'javascript.browser.arachni/polyfills.js><SCRIPT src=http://' <<
1117
- 'javascript.browser.arachni/' <<
1118
- 'taint_tracer.js><SCRIPT src=http://javascript.' <<
1119
- 'browser.arachni/dom_monitor.js><SCRIPT><TITLE><BODY><' <<
1120
- 'DIV><SCRIPT type=text/javascript><SCRIPT type=text/javascript>'
1121
- )
1028
+ expect(@browser.to_page.dom.digest).to eq(-2125129228)
1029
+
1030
+ # expect(@browser.to_page.dom.instance_variable_get(:@digest)).to eq(
1031
+ # '<HTML><HEAD><SCRIPT src=https://' <<
1032
+ # 'javascript.browser.arachni/polyfills.js><SCRIPT src=https://' <<
1033
+ # 'javascript.browser.arachni/' <<
1034
+ # 'taint_tracer.js><SCRIPT src=http://javascript.' <<
1035
+ # 'browser.arachni/dom_monitor.js><SCRIPT><TITLE><BODY><' <<
1036
+ # 'DIV><SCRIPT type=text/javascript><SCRIPT type=text/javascript>'
1037
+ # )
1122
1038
  end
1123
1039
 
1124
1040
  it "assigns the proper #{Arachni::Page::DOM}#transitions" do
@@ -1140,6 +1056,12 @@ describe Arachni::Browser do
1140
1056
  expect(page.dom.skip_states).to be_subset @browser.skip_states
1141
1057
  end
1142
1058
 
1059
+ it "assigns the proper #{Arachni::Page::DOM}#cookies" do
1060
+ @browser.load "#{@url}/dom-cookies-names"
1061
+
1062
+ expect(@browser.to_page.dom.cookies).to eq @browser.cookies
1063
+ end
1064
+
1143
1065
  it "assigns the proper #{Arachni::Page::DOM} sink data" do
1144
1066
  @browser.load "#{web_server_url_for( :taint_tracer )}/debug" <<
1145
1067
  "?input=#{@browser.javascript.log_execution_flow_sink_stub(1)}"
@@ -1152,7 +1074,6 @@ describe Arachni::Browser do
1152
1074
  expect(sink_data).to eq([first_entry])
1153
1075
 
1154
1076
  expect(first_entry.data).to eq([1])
1155
- expect(first_entry.trace.size).to eq(2)
1156
1077
 
1157
1078
  expect(first_entry.trace[0].function.name).to eq('onClick')
1158
1079
  expect(first_entry.trace[0].function.source).to start_with 'function onClick'
@@ -1188,7 +1109,7 @@ describe Arachni::Browser do
1188
1109
  input = @browser.to_page.ui_forms.first
1189
1110
 
1190
1111
  expect(input.action).to eq @browser.url
1191
- expect(input.source).to eq '<input type="button" id="insert">'
1112
+ expect(input.source).to eq '<input id="insert" type="button">'
1192
1113
  expect(input.method).to eq :click
1193
1114
  end
1194
1115
  end
@@ -1251,8 +1172,8 @@ describe Arachni::Browser do
1251
1172
  input = @browser.to_page.ui_inputs.first
1252
1173
 
1253
1174
  expect(input.action).to eq @browser.url
1254
- expect(input.source).to eq '<input oninput="handleOnInput();" id="my-input" name="my-input" value="1">'
1255
- expect(input.method).to eq :oninput
1175
+ expect(input.source).to eq '<input id="my-input" name="my-input" oninput="handleOnInput();" value="1">'
1176
+ expect(input.method).to eq :input
1256
1177
  end
1257
1178
  end
1258
1179
 
@@ -1272,8 +1193,8 @@ describe Arachni::Browser do
1272
1193
  input = @browser.to_page.ui_inputs.first
1273
1194
 
1274
1195
  expect(input.action).to eq @browser.url
1275
- expect(input.source).to eq '<textarea oninput="handleOnInput();" id="my-input" name="my-input">'
1276
- expect(input.method).to eq :oninput
1196
+ expect(input.source).to eq '<textarea id="my-input" name="my-input" oninput="handleOnInput();">'
1197
+ expect(input.method).to eq :input
1277
1198
  end
1278
1199
  end
1279
1200
 
@@ -1406,6 +1327,24 @@ describe Arachni::Browser do
1406
1327
  end
1407
1328
  end
1408
1329
  end
1330
+
1331
+ context 'when taints are not exact matches' do
1332
+ context 'names' do
1333
+ let(:page) { 'dom-cookies-names-substring' }
1334
+
1335
+ it 'does not set #skip_dom' do
1336
+ expect(cookies.find { |c| c.name == 'js_cookie3' }.skip_dom).to be_truthy
1337
+ end
1338
+ end
1339
+
1340
+ context 'values' do
1341
+ let(:page) { 'dom-cookies-values-substring' }
1342
+
1343
+ it 'does not set #skip_dom' do
1344
+ expect(cookies.find { |c| c.name == 'js_cookie3' }.skip_dom).to be_truthy
1345
+ end
1346
+ end
1347
+ end
1409
1348
  end
1410
1349
 
1411
1350
  context 'false' do
@@ -1434,15 +1373,15 @@ describe Arachni::Browser do
1434
1373
  Arachni::Options.url = @url
1435
1374
  subject.load @url
1436
1375
 
1437
- subject.javascript.run( 'window.location = "http://google.com/";' )
1376
+ subject.javascript.run( 'window.location = "http://www.google.com/";' )
1438
1377
  sleep 1
1439
1378
 
1440
1379
  page = subject.to_page
1441
1380
 
1442
1381
  expect(page.code).to eq(0)
1443
- expect(page.url).to eq('http://google.com/')
1382
+ expect(page.url).to eq('http://www.google.com/')
1444
1383
  expect(page.body).to be_empty
1445
- expect(page.dom.url).to eq('http://google.com/')
1384
+ expect(page.dom.url).to eq('http://www.google.com/')
1446
1385
  end
1447
1386
  end
1448
1387
  end
@@ -1461,7 +1400,7 @@ describe Arachni::Browser do
1461
1400
  it 'accepts events without the "on" prefix' do
1462
1401
  pages_should_not_have_form_with_input [@browser.to_page], 'by-ajax'
1463
1402
 
1464
- @browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :onclick
1403
+ @browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :click
1465
1404
  pages_should_have_form_with_input [@browser.to_page], 'by-ajax'
1466
1405
 
1467
1406
  @browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :click
@@ -1479,24 +1418,55 @@ describe Arachni::Browser do
1479
1418
  pages_should_have_form_with_input [@browser.to_page], 'by-ajax'
1480
1419
  end
1481
1420
 
1482
- context 'when new timers are introduced' do
1483
- let(:url) { "#{@url}/trigger_events/with_new_timers/3000" }
1421
+ context 'when new elements are introduced' do
1422
+ let(:url) { "#{@url}/trigger_events/with_new_elements" }
1423
+
1424
+ it 'sets element IDs' do
1425
+ expect(@browser.selenium.find_elements( :css, 'a' )).to be_empty
1484
1426
 
1485
- it 'waits for them' do
1486
1427
  @browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :click
1487
- pages_should_have_form_with_input [@browser.to_page], 'by-ajax'
1428
+
1429
+ expect(@browser.selenium.find_elements( :css, 'a' ).first.opening_tag).to eq '<a href="#blah" data-arachni-id="2073105">'
1488
1430
  end
1431
+ end
1489
1432
 
1490
- context 'when a new timer exceeds Options.http.request_timeout' do
1491
- let(:url) { "#{@url}/trigger_events/with_new_timers/#{Arachni::Options.http.request_timeout + 5000}" }
1433
+ context 'when new timers are introduced' do
1434
+ let(:url) { "#{@url}/trigger_events/with_new_timers/3000" }
1492
1435
 
1493
- it 'waits for Options.http.request_timeout' do
1494
- t = Time.now
1436
+ context "when #{Arachni::OptionGroups::BrowserCluster}#wait_for_timers is" do
1437
+ context 'true' do
1438
+ before do
1439
+ Arachni::Options.browser_cluster.wait_for_timers = true
1440
+ end
1441
+
1442
+ it 'waits for them' do
1443
+ @browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :click
1444
+ pages_should_have_form_with_input [@browser.to_page], 'by-ajax'
1445
+ end
1446
+
1447
+ context 'when a new timer exceeds Options.http.request_timeout' do
1448
+ let(:url) { "#{@url}/trigger_events/with_new_timers/#{Arachni::Options.http.request_timeout + 5000}" }
1495
1449
 
1496
- @browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :click
1497
- pages_should_not_have_form_with_input [@browser.to_page], 'by-ajax'
1450
+ it 'waits for Options.http.request_timeout' do
1451
+ t = Time.now
1498
1452
 
1499
- expect(Time.now - t).to be <= Arachni::Options.http.request_timeout
1453
+ @browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :click
1454
+ pages_should_not_have_form_with_input [@browser.to_page], 'by-ajax'
1455
+
1456
+ expect(Time.now - t).to be <= Arachni::Options.http.request_timeout
1457
+ end
1458
+ end
1459
+ end
1460
+
1461
+ context 'false' do
1462
+ before do
1463
+ Arachni::Options.browser_cluster.wait_for_timers = false
1464
+ end
1465
+
1466
+ it 'waits for them' do
1467
+ @browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :click
1468
+ pages_should_not_have_form_with_input [@browser.to_page], 'by-ajax'
1469
+ end
1500
1470
  end
1501
1471
  end
1502
1472
  end
@@ -1560,13 +1530,75 @@ describe Arachni::Browser do
1560
1530
  context ':submit' do
1561
1531
  let(:url) { "#{@url}/fire_event/form/onsubmit" }
1562
1532
 
1563
- context 'when option' do
1564
- describe ':inputs' do
1533
+ def element
1534
+ @browser.selenium.find_element(:tag_name, :form)
1535
+ end
1565
1536
 
1566
- def element
1567
- @browser.selenium.find_element(:tag_name, :form)
1568
- end
1537
+ context 'when there is a submit button' do
1538
+ let(:url) { "#{@url}/fire_event/form/submit_button" }
1539
+ let(:inputs) do
1540
+ {
1541
+ name: 'The Dude',
1542
+ email: 'the.dude@abides.com'
1543
+ }
1544
+ end
1545
+
1546
+ it 'clicks it' do
1547
+ @browser.fire_event element, :submit, inputs: inputs
1548
+
1549
+ expect(@browser.watir.div( id: 'container-name' ).text).to eq(
1550
+ inputs[:name]
1551
+ )
1552
+ expect(@browser.watir.div( id: 'container-email' ).text).to eq(
1553
+ inputs[:email]
1554
+ )
1555
+ end
1556
+ end
1557
+
1558
+ context 'when there is a submit input' do
1559
+ let(:url) { "#{@url}/fire_event/form/submit_input" }
1560
+ let(:inputs) do
1561
+ {
1562
+ name: 'The Dude',
1563
+ email: 'the.dude@abides.com'
1564
+ }
1565
+ end
1566
+
1567
+ it 'clicks it' do
1568
+ @browser.fire_event element, :submit, inputs: inputs
1569
+
1570
+ expect(@browser.watir.div( id: 'container-name' ).text).to eq(
1571
+ inputs[:name]
1572
+ )
1573
+ expect(@browser.watir.div( id: 'container-email' ).text).to eq(
1574
+ inputs[:email]
1575
+ )
1576
+ end
1577
+ end
1569
1578
 
1579
+ context 'when there is no submit button or input' do
1580
+ let(:url) { "#{@url}/fire_event/form/onsubmit" }
1581
+ let(:inputs) do
1582
+ {
1583
+ name: 'The Dude',
1584
+ email: 'the.dude@abides.com'
1585
+ }
1586
+ end
1587
+
1588
+ it 'triggers the submit event' do
1589
+ @browser.fire_event element, :submit, inputs: inputs
1590
+
1591
+ expect(@browser.watir.div( id: 'container-name' ).text).to eq(
1592
+ inputs[:name]
1593
+ )
1594
+ expect(@browser.watir.div( id: 'container-email' ).text).to eq(
1595
+ inputs[:email]
1596
+ )
1597
+ end
1598
+ end
1599
+
1600
+ context 'when option' do
1601
+ describe ':inputs' do
1570
1602
  context 'is given' do
1571
1603
  let(:inputs) do
1572
1604
  {
@@ -1760,6 +1792,59 @@ describe Arachni::Browser do
1760
1792
  end
1761
1793
  end
1762
1794
 
1795
+ context ':fill' do
1796
+ before(:each) do
1797
+ @browser.load url
1798
+ end
1799
+
1800
+ let(:url) { "#{@url}/fire_event/form/onsubmit" }
1801
+ let(:inputs) do
1802
+ {
1803
+ name: "The Dude",
1804
+ email: "the.dude@abides.com"
1805
+ }
1806
+ end
1807
+
1808
+ def element
1809
+ @browser.selenium.find_element(:tag_name, :form)
1810
+ end
1811
+
1812
+ it 'fills in the form inputs' do
1813
+ @browser.fire_event element, :fill, inputs: inputs
1814
+
1815
+ expect(@browser.watir.textarea( name: 'name' ).value).to eq(
1816
+ inputs[:name]
1817
+ )
1818
+
1819
+ expect(@browser.watir.input( id: 'email' ).value).to eq(
1820
+ inputs[:email]
1821
+ )
1822
+
1823
+ expect(@browser.watir.div( id: 'container-name' ).text).to be_empty
1824
+ expect(@browser.watir.div( id: 'container-email' ).text).to be_empty
1825
+ end
1826
+
1827
+ it 'returns a playable transition' do
1828
+ @browser.load url
1829
+ transition = @browser.fire_event element, :fill, inputs: inputs
1830
+
1831
+ @browser.load url
1832
+
1833
+ expect(@browser.watir.textarea( name: 'name' ).value).to be_empty
1834
+ expect(@browser.watir.input( id: 'email' ).value).to be_empty
1835
+
1836
+ transition.play @browser
1837
+
1838
+ expect(@browser.watir.textarea( name: 'name' ).value).to eq(
1839
+ inputs[:name]
1840
+ )
1841
+
1842
+ expect(@browser.watir.input( id: 'email' ).value).to eq(
1843
+ inputs[:email]
1844
+ )
1845
+ end
1846
+ end
1847
+
1763
1848
  context 'image button' do
1764
1849
  context ':click' do
1765
1850
  before( :each ) { @browser.start_capture }
@@ -1800,7 +1885,16 @@ describe Arachni::Browser do
1800
1885
  end
1801
1886
 
1802
1887
  context 'input' do
1803
- described_class::Javascript::EVENTS_PER_ELEMENT[:input].each do |event|
1888
+ [
1889
+ :onselect,
1890
+ :onchange,
1891
+ :onfocus,
1892
+ :onblur,
1893
+ :onkeydown,
1894
+ :onkeypress,
1895
+ :onkeyup,
1896
+ :oninput
1897
+ ].each do |event|
1804
1898
  calculate_expectation = proc do |string|
1805
1899
  [:onkeypress, :onkeydown].include?( event ) ?
1806
1900
  string[0...-1] : string
@@ -1894,44 +1988,6 @@ describe Arachni::Browser do
1894
1988
  end
1895
1989
  end
1896
1990
 
1897
- describe '#elements_with_events' do
1898
- before :each do
1899
- @browser.load url
1900
- end
1901
-
1902
- let(:elements_with_events) do
1903
- elements_with_events = {}
1904
- @browser.each_element_with_events do |locator, events|
1905
- elements_with_events[locator] = events
1906
- end
1907
- elements_with_events
1908
- end
1909
-
1910
- let(:url) { @url + '/trigger_events' }
1911
-
1912
- it 'returns all elements with associated events' do
1913
- expect(subject.elements_with_events.to_s).to eq elements_with_events.to_s
1914
- end
1915
-
1916
- it 'caches results' do
1917
- expect(subject).to receive(:each_element_with_events)
1918
- subject.elements_with_events
1919
-
1920
- expect(subject).to_not receive(:each_element_with_events)
1921
- subject.elements_with_events
1922
- end
1923
-
1924
- context 'when passed true' do
1925
- it 'clears the cache' do
1926
- expect(subject).to receive(:each_element_with_events)
1927
- subject.elements_with_events
1928
-
1929
- expect(subject).to receive(:each_element_with_events)
1930
- subject.elements_with_events( true )
1931
- end
1932
- end
1933
- end
1934
-
1935
1991
  describe '#each_element_with_events' do
1936
1992
  before :each do
1937
1993
  @browser.load url
@@ -1952,14 +2008,14 @@ describe Arachni::Browser do
1952
2008
  tag_name: 'body',
1953
2009
  attributes: { 'onmouseover' => 'makePOST();' }
1954
2010
  ),
1955
- { onmouseover: ['makePOST();'] }
2011
+ { mouseover: ['makePOST();'] }
1956
2012
  ],
1957
2013
  [
1958
2014
  described_class::ElementLocator.new(
1959
2015
  tag_name: 'div',
1960
2016
  attributes: { 'id' => 'my-div', 'onclick' => 'addForm();' }
1961
2017
  ),
1962
- { onclick: ['addForm();']}
2018
+ { click: ['addForm();']}
1963
2019
  ]
1964
2020
  ])
1965
2021
  end
@@ -2074,7 +2130,7 @@ describe Arachni::Browser do
2074
2130
  end
2075
2131
 
2076
2132
  locators.each do |element|
2077
- @browser.javascript.class.events.each do |e|
2133
+ described_class::Javascript::EVENTS.each do |e|
2078
2134
  begin
2079
2135
  @browser.trigger_event @browser.to_page, element, e
2080
2136
  rescue
@@ -2089,6 +2145,7 @@ describe Arachni::Browser do
2089
2145
  end
2090
2146
 
2091
2147
  describe '#trigger_events' do
2148
+
2092
2149
  it 'returns self' do
2093
2150
  expect(@browser.load( @url + '/explore' ).trigger_events).to eq(@browser)
2094
2151
  end
@@ -2128,6 +2185,7 @@ describe Arachni::Browser do
2128
2185
  }
2129
2186
  } => :click
2130
2187
  },
2188
+ { "#{@url}post-ajax" => :request },
2131
2189
  { "#{@url}get-ajax?ajax-token=my-token" => :request },
2132
2190
  { "#{@url}post-ajax" => :request }
2133
2191
  ],
@@ -2142,7 +2200,6 @@ describe Arachni::Browser do
2142
2200
  }
2143
2201
  } => :click
2144
2202
  },
2145
- { "#{@url}href-ajax" => :request },
2146
2203
  { "#{@url}post-ajax" => :request },
2147
2204
  { "#{@url}href-ajax" => :request }
2148
2205
  ]
@@ -2173,15 +2230,33 @@ describe Arachni::Browser do
2173
2230
  pages_should_have_form_with_input @browser.captured_pages, 'myImageButton.y'
2174
2231
  end
2175
2232
  end
2233
+
2234
+ context 'when OptionGroups::Scope#dom_event_limit' do
2235
+ context 'has been set' do
2236
+ it 'only triggers that amount of events' do
2237
+ Arachni::Options.scope.dom_event_limit = 1
2238
+
2239
+ @browser.load( "#{@url}form-with-image-button" ).start_capture.trigger_events
2240
+
2241
+ expect(@browser.flush_pages.size).to eq 1
2242
+ end
2243
+ end
2244
+
2245
+ context 'has not been set' do
2246
+ it 'triggers all events' do
2247
+ Arachni::Options.scope.dom_event_limit = nil
2248
+
2249
+ @browser.load( "#{@url}form-with-image-button" ).start_capture.trigger_events
2250
+
2251
+ expect(@browser.flush_pages.size).to eq 2
2252
+ end
2253
+ end
2254
+ end
2176
2255
  end
2177
2256
 
2178
2257
  describe '#source' do
2179
2258
  it 'returns the evaluated HTML source' do
2180
2259
  @browser.load @url
2181
-
2182
- ua = Arachni::Options.http.user_agent
2183
- expect(ua).not_to be_empty
2184
-
2185
2260
  expect(@browser.source).to include( ua )
2186
2261
  end
2187
2262
  end
@@ -2201,10 +2276,6 @@ describe Arachni::Browser do
2201
2276
  describe '#goto' do
2202
2277
  it 'loads the given URL' do
2203
2278
  @browser.goto @url
2204
-
2205
- ua = Arachni::Options.http.user_agent
2206
- expect(ua).not_to be_empty
2207
-
2208
2279
  expect(@browser.source).to include( ua )
2209
2280
  end
2210
2281
 
@@ -2215,8 +2286,6 @@ describe Arachni::Browser do
2215
2286
  @browser = described_class.new
2216
2287
 
2217
2288
  transition.play( @browser )
2218
- ua = Arachni::Options.http.user_agent
2219
- expect(ua).not_to be_empty
2220
2289
 
2221
2290
  expect(@browser.source).to include( ua )
2222
2291
  end
@@ -2226,7 +2295,83 @@ describe Arachni::Browser do
2226
2295
  expect(described_class.asset_domains).to include Arachni::URI( @url ).domain
2227
2296
  end
2228
2297
 
2298
+ it 'does not receive a Content-Security-Policy header' do
2299
+ subject.goto "#{@url}/Content-Security-Policy"
2300
+ expect(subject.response.code).to eq(200)
2301
+ expect(subject.response.headers).not_to include 'Content-Security-Policy'
2302
+ end
2303
+
2304
+ context 'when there is no page URL' do
2305
+ it 'does not receive a Date header' do
2306
+ subject.watir.goto "#{@url}/Date"
2307
+ expect(subject.response.code).to eq(200)
2308
+ expect(subject.response.headers).not_to include 'Date'
2309
+ end
2310
+
2311
+ it 'does not receive an Etag header' do
2312
+ subject.watir.goto "#{@url}/Etag"
2313
+ expect(subject.response.code).to eq(200)
2314
+ expect(subject.response.headers).not_to include 'Etag'
2315
+ end
2316
+
2317
+ it 'does not receive a Cache-Control header' do
2318
+ subject.watir.goto "#{@url}/Cache-Control"
2319
+ expect(subject.response.code).to eq(200)
2320
+ expect(subject.response.headers).not_to include 'Cache-Control'
2321
+ end
2322
+
2323
+ it 'does not receive a Last-Modified header' do
2324
+ subject.watir.goto "#{@url}/Last-Modified"
2325
+ expect(subject.response.code).to eq(200)
2326
+ expect(subject.response.headers).not_to include 'Last-Modified'
2327
+ end
2328
+
2329
+ it 'does not send If-None-Match request headers' do
2330
+ subject.watir.goto "#{@url}/If-None-Match"
2331
+ expect(subject.response.code).to eq(200)
2332
+ expect(subject.response.request.headers).not_to include 'If-None-Match'
2333
+
2334
+ subject.watir.goto "#{@url}/If-None-Match"
2335
+ expect(subject.response.code).to eq(200)
2336
+ expect(subject.response.request.headers).not_to include 'If-None-Match'
2337
+ end
2338
+
2339
+ it 'does not send If-Modified-Since request headers' do
2340
+ subject.watir.goto "#{@url}/If-Modified-Since"
2341
+ expect(subject.response.code).to eq(200)
2342
+ expect(subject.response.request.headers).not_to include 'If-Modified-Since'
2343
+
2344
+ subject.watir.goto "#{@url}/If-Modified-Since"
2345
+ expect(subject.response.code).to eq(200)
2346
+ expect(subject.response.request.headers).not_to include 'If-Modified-Since'
2347
+ end
2348
+ end
2349
+
2229
2350
  context 'when requesting the page URL' do
2351
+ it 'does not receive a Date header' do
2352
+ subject.goto "#{@url}/Date"
2353
+ expect(subject.response.code).to eq(200)
2354
+ expect(subject.response.headers).not_to include 'Date'
2355
+ end
2356
+
2357
+ it 'does not receive an Etag header' do
2358
+ subject.goto "#{@url}/Etag"
2359
+ expect(subject.response.code).to eq(200)
2360
+ expect(subject.response.headers).not_to include 'Etag'
2361
+ end
2362
+
2363
+ it 'does not receive a Cache-Control header' do
2364
+ subject.goto "#{@url}/Cache-Control"
2365
+ expect(subject.response.code).to eq(200)
2366
+ expect(subject.response.headers).not_to include 'Cache-Control'
2367
+ end
2368
+
2369
+ it 'does not receive a Last-Modified header' do
2370
+ subject.goto "#{@url}/Last-Modified"
2371
+ expect(subject.response.code).to eq(200)
2372
+ expect(subject.response.headers).not_to include 'Last-Modified'
2373
+ end
2374
+
2230
2375
  it 'does not send If-None-Match request headers' do
2231
2376
  subject.goto "#{@url}/If-None-Match"
2232
2377
  expect(subject.response.code).to eq(200)
@@ -2249,6 +2394,66 @@ describe Arachni::Browser do
2249
2394
  end
2250
2395
 
2251
2396
  context 'when requesting something other than the page URL' do
2397
+ it 'receives a Date header' do
2398
+ url = "#{@url}Date"
2399
+
2400
+ response = nil
2401
+ subject.on_response do |r|
2402
+ next if r.url == url
2403
+ response = r
2404
+ end
2405
+
2406
+ subject.goto url
2407
+
2408
+ expect(response.code).to eq(200)
2409
+ expect(response.headers).to include 'Date'
2410
+ end
2411
+
2412
+ it 'receives an Etag header' do
2413
+ url = "#{@url}Etag"
2414
+
2415
+ response = nil
2416
+ subject.on_response do |r|
2417
+ next if r.url == url
2418
+ response = r
2419
+ end
2420
+
2421
+ subject.goto url
2422
+
2423
+ expect(response.code).to eq(200)
2424
+ expect(response.headers).to include 'Etag'
2425
+ end
2426
+
2427
+ it 'receives a Cache-Control header' do
2428
+ url = "#{@url}Cache-Control"
2429
+
2430
+ response = nil
2431
+ subject.on_response do |r|
2432
+ next if r.url == url
2433
+ response = r
2434
+ end
2435
+
2436
+ subject.goto url
2437
+
2438
+ expect(response.code).to eq(200)
2439
+ expect(response.headers).to include 'Cache-Control'
2440
+ end
2441
+
2442
+ it 'receives a Last-Modified header' do
2443
+ url = "#{@url}Last-Modified"
2444
+
2445
+ response = nil
2446
+ subject.on_response do |r|
2447
+ next if r.url == url
2448
+ response = r
2449
+ end
2450
+
2451
+ subject.goto url
2452
+
2453
+ expect(response.code).to eq(200)
2454
+ expect(response.headers).to include 'Last-Modified'
2455
+ end
2456
+
2252
2457
  it 'sends If-None-Match request headers' do
2253
2458
  url = "#{@url}If-None-Match"
2254
2459
 
@@ -2320,12 +2525,34 @@ describe Arachni::Browser do
2320
2525
  end
2321
2526
 
2322
2527
  context 'when the page has JS timeouts' do
2323
- it 'waits for them to complete' do
2324
- time = Time.now
2325
- subject.goto "#{@url}load_delay"
2326
- waited = Time.now - time
2528
+ context "when #{Arachni::OptionGroups::BrowserCluster}#wait_for_timers is" do
2529
+ context 'true' do
2530
+ before do
2531
+ Arachni::Options.browser_cluster.wait_for_timers = true
2532
+ end
2533
+
2534
+ it 'waits for them to complete' do
2535
+ time = Time.now
2536
+ subject.goto "#{@url}load_delay"
2537
+ waited = Time.now - time
2538
+
2539
+ expect(waited).to be >= subject.load_delay / 1000.0
2540
+ end
2541
+ end
2542
+
2543
+ context 'false' do
2544
+ before do
2545
+ Arachni::Options.browser_cluster.wait_for_timers = false
2546
+ end
2327
2547
 
2328
- expect(waited).to be >= subject.load_delay / 1000.0
2548
+ it 'does not waits for them to complete' do
2549
+ time = Time.now
2550
+ subject.goto "#{@url}load_delay"
2551
+ waited = Time.now - time
2552
+
2553
+ expect(waited).to be < subject.load_delay / 1000.0
2554
+ end
2555
+ end
2329
2556
  end
2330
2557
  end
2331
2558
 
@@ -2367,6 +2594,19 @@ describe Arachni::Browser do
2367
2594
  end
2368
2595
  end
2369
2596
 
2597
+ context "with #{Arachni::OptionGroups::BrowserCluster}#session_storage" do
2598
+ before do
2599
+ Arachni::Options.browser_cluster.session_storage = {
2600
+ 'name' => 'value'
2601
+ }
2602
+ end
2603
+
2604
+ it 'sets the data as session storage' do
2605
+ subject.load @url
2606
+ expect( subject.javascript.run( 'return sessionStorage.getItem( "name" )' ) ).to eq 'value'
2607
+ end
2608
+ end
2609
+
2370
2610
  context "with #{Arachni::OptionGroups::BrowserCluster}#wait_for_elements" do
2371
2611
  before do
2372
2612
  Arachni::Options.browser_cluster.wait_for_elements = {
@@ -2389,10 +2629,6 @@ describe Arachni::Browser do
2389
2629
  t = Time.now
2390
2630
  @browser.goto( @url + '/wait_for_elements#stuff/here' )
2391
2631
  expect(Time.now - t).to be < 5
2392
-
2393
- expect do
2394
- @browser.watir.element( css: '#matchThis' ).tag_name
2395
- end.to raise_error Watir::Exception::UnknownObjectException
2396
2632
  end
2397
2633
  end
2398
2634
 
@@ -2401,36 +2637,6 @@ describe Arachni::Browser do
2401
2637
  t = Time.now
2402
2638
  @browser.goto( @url + '/wait_for_elements' )
2403
2639
  expect(Time.now - t).to be < 5
2404
-
2405
- expect do
2406
- @browser.watir.element( css: '#matchThis' ).tag_name
2407
- end.to raise_error Watir::Exception::UnknownObjectException
2408
- end
2409
- end
2410
- end
2411
-
2412
- context "#{Arachni::OptionGroups::BrowserCluster}#ignore_images" do
2413
- context 'true' do
2414
- it 'does not load images' do
2415
- Arachni::Options.browser_cluster.ignore_images = true
2416
- @browser.shutdown
2417
- @browser = described_class.new( disk_cache: false )
2418
-
2419
- @browser.load( "#{@url}form-with-image-button" )
2420
-
2421
- expect(image_hit_count).to eq(0)
2422
- end
2423
- end
2424
-
2425
- context 'false' do
2426
- it 'loads images' do
2427
- Arachni::Options.browser_cluster.ignore_images = false
2428
- @browser.shutdown
2429
- @browser = described_class.new( disk_cache: false )
2430
-
2431
- @browser.load( "#{@url}form-with-image-button" )
2432
-
2433
- expect(image_hit_count).to eq(1)
2434
2640
  end
2435
2641
  end
2436
2642
  end
@@ -2459,8 +2665,10 @@ describe Arachni::Browser do
2459
2665
 
2460
2666
  context "with #{Arachni::OptionGroups::Scope}#auto_redundant_paths has bee configured" do
2461
2667
  it 'respects scope restrictions' do
2462
- Arachni::Options.scope.auto_redundant_paths = 0
2463
- expect(@browser.load( @url + '/explore?test=1&test2=2' ).response).to be_nil
2668
+ Arachni::Options.scope.auto_redundant_paths = 1
2669
+ Arachni::URI( @url + '/explore?test=2&test2=3' ).scope.auto_redundant?( true )
2670
+
2671
+ expect(@browser.load( @url + '/explore?test=4&test2=5' ).response.body).to be_empty
2464
2672
  end
2465
2673
  end
2466
2674
 
@@ -2819,78 +3027,6 @@ describe Arachni::Browser do
2819
3027
  end
2820
3028
  end
2821
3029
 
2822
- describe '#cache' do
2823
- it 'keeps entries after they are used' do
2824
- @browser.cache Arachni::HTTP::Client.get( @url, mode: :sync )
2825
- clear_hit_count
2826
-
2827
- expect(hit_count).to eq(0)
2828
-
2829
- @browser.load @url
2830
- expect(@browser.source).to include( ua )
2831
- expect(@browser.cache).to include( @url )
2832
-
2833
- expect(hit_count).to eq(0)
2834
-
2835
- 2.times do
2836
- @browser.load @url
2837
- expect(@browser.source).to include( ua )
2838
- end
2839
-
2840
- expect(@browser.cache).to include( @url )
2841
-
2842
- expect(hit_count).to eq(0)
2843
- end
2844
-
2845
- it 'returns the URL of the resource' do
2846
- response = Arachni::HTTP::Client.get( @url, mode: :sync )
2847
- expect(@browser.cache( response )).to eq(response.url)
2848
-
2849
- @browser.load response.url
2850
- expect(@browser.source).to include( ua )
2851
- expect(@browser.cache).to include( response.url )
2852
- end
2853
-
2854
- context 'when given a' do
2855
- describe 'Arachni::HTTP::Response' do
2856
- it 'caches it' do
2857
- @browser.cache Arachni::HTTP::Client.get( @url, mode: :sync )
2858
- clear_hit_count
2859
-
2860
- expect(hit_count).to eq(0)
2861
-
2862
- @browser.load @url
2863
- expect(@browser.source).to include( ua )
2864
- expect(@browser.cache).to include( @url )
2865
-
2866
- expect(hit_count).to eq(0)
2867
- end
2868
- end
2869
-
2870
- describe 'Arachni::Page' do
2871
- it 'caches it' do
2872
- @browser.cache Arachni::Page.from_url( @url )
2873
- clear_hit_count
2874
-
2875
- expect(hit_count).to eq(0)
2876
-
2877
- @browser.load @url
2878
- expect(@browser.source).to include( ua )
2879
- expect(@browser.cache).to include( @url )
2880
-
2881
- expect(hit_count).to eq(0)
2882
- end
2883
- end
2884
-
2885
- describe 'other' do
2886
- it 'raises Arachni::Browser::Error::Load' do
2887
- expect { @browser.cache [] }.to raise_error Arachni::Browser::Error::Load
2888
- end
2889
- end
2890
-
2891
- end
2892
- end
2893
-
2894
3030
  describe '#start_capture' do
2895
3031
  before(:each) { @browser.start_capture }
2896
3032
 
@@ -2948,6 +3084,23 @@ describe Arachni::Browser do
2948
3084
  end
2949
3085
 
2950
3086
  context 'when a POST request is performed' do
3087
+ context 'with query parameters' do
3088
+ it "is added as an #{Arachni::Element::Form} to the page" do
3089
+ @browser.load @url + '/with-ajax'
3090
+
3091
+ pages = @browser.captured_pages
3092
+ expect(pages.size).to eq(2)
3093
+
3094
+ form = find_page_with_form_with_input( pages, 'post-name' ).
3095
+ forms.find { |form| form.inputs.include? 'post-query' }
3096
+
3097
+ expect(form.url).to eq(@url + 'with-ajax')
3098
+ expect(form.action).to eq(@url + 'post-ajax')
3099
+ expect(form.inputs).to eq({ 'post-query' => 'blah' })
3100
+ expect(form.method).to eq(:get)
3101
+ end
3102
+ end
3103
+
2951
3104
  context 'with form data' do
2952
3105
  it "is added as an #{Arachni::Element::Form} to the page" do
2953
3106
  @browser.load @url + '/with-ajax'
@@ -2959,7 +3112,7 @@ describe Arachni::Browser do
2959
3112
  forms.find { |form| form.inputs.include? 'post-name' }
2960
3113
 
2961
3114
  expect(form.url).to eq(@url + 'with-ajax')
2962
- expect(form.action).to eq(@url + 'post-ajax')
3115
+ expect(form.action).to eq(@url + 'post-ajax?post-query=blah')
2963
3116
  expect(form.inputs).to eq({ 'post-name' => 'post-value' })
2964
3117
  expect(form.method).to eq(:post)
2965
3118
  end
@@ -3066,15 +3219,19 @@ describe Arachni::Browser do
3066
3219
  expect(cookie.expires.to_s).to eq Time.parse( '2047-08-01 09:30:11 +0000' ).to_s
3067
3220
  end
3068
3221
 
3222
+ # Need a better test, Chrome returns no cookies for '.localhost'
3223
+ # (or is it a bug and it's all subdomains?) and Firefox just converts
3224
+ # '.localhost' to 'localhost', is this only for localhost or general bug?
3069
3225
  it 'preserves the domain' do
3226
+ skip
3070
3227
  @browser.load "#{@url}/cookies/domains"
3071
3228
 
3072
- cookies = @browser.cookies
3229
+ ap cookies = @browser.cookies
3073
3230
 
3074
3231
  cookie = cookies.find { |c| c.name == 'include_subdomains' }
3075
3232
  expect(cookie.name).to eq 'include_subdomains'
3076
3233
  expect(cookie.value).to eq 'bar1'
3077
- expect(cookie.domain).to eq '.127.0.0.2'
3234
+ expect(cookie.domain).to eq ".#{Arachni::URI( @url ).host}"
3078
3235
  end
3079
3236
 
3080
3237
  it 'ignores cookies for other domains' do
@@ -3090,7 +3247,7 @@ describe Arachni::Browser do
3090
3247
  cookie = @browser.cookies.first
3091
3248
  expect(cookie.name).to eq 'cookie_under_path'
3092
3249
  expect(cookie.value).to eq 'value'
3093
- expect(cookie.path).to eq '/cookies/under/'
3250
+ expect(cookie.path).to eq '/cookies/under'
3094
3251
  end
3095
3252
 
3096
3253
  it 'preserves httpOnly' do
@@ -3099,7 +3256,7 @@ describe Arachni::Browser do
3099
3256
  cookie = @browser.cookies.first
3100
3257
  expect(cookie.name).to eq 'cookie_under_path'
3101
3258
  expect(cookie.value).to eq 'value'
3102
- expect(cookie.path).to eq '/cookies/under/'
3259
+ expect(cookie.path).to eq '/cookies/under'
3103
3260
  expect(cookie).to_not be_http_only
3104
3261
 
3105
3262
  @browser.load "#{@url}/cookies/httpOnly"
@@ -3130,119 +3287,4 @@ describe Arachni::Browser do
3130
3287
  end
3131
3288
  end
3132
3289
 
3133
- describe '#snapshot_id' do
3134
- before(:each) do
3135
- Arachni::Options.url = @url
3136
-
3137
- @empty_snapshot_id ||= @browser.load( empty_snapshot_id_url ).snapshot_id
3138
-
3139
- @snapshot_id = @browser.load( url ).snapshot_id
3140
- end
3141
-
3142
- let(:empty_snapshot_id_url) { @url + '/snapshot_id/default' }
3143
- let(:empty_snapshot_id) do
3144
- @empty_snapshot_id
3145
- end
3146
- let(:snapshot_id) do
3147
- @snapshot_id
3148
- end
3149
-
3150
- let(:url) { @url + '/trigger_events' }
3151
-
3152
- it 'returns a DOM digest' do
3153
- expect(snapshot_id).to eq(@browser.load( url ).snapshot_id)
3154
- end
3155
-
3156
- context 'when there are new cookies' do
3157
- let(:url) { @url + '/each_element_with_events/set-cookie' }
3158
-
3159
- it 'takes them into account' do
3160
- @browser.fire_event described_class::ElementLocator.new(
3161
- tag_name: :button,
3162
- attributes: {
3163
- onclick: 'setCookie()'
3164
- }
3165
- ), :click
3166
-
3167
- expect(@browser.snapshot_id).not_to eq(snapshot_id)
3168
- end
3169
- end
3170
-
3171
- context ':a' do
3172
- context 'and the href is not empty' do
3173
- context 'and it starts with javascript:' do
3174
- let(:url) { @url + '/each_element_with_events/a/href/javascript' }
3175
-
3176
- it 'takes it into account' do
3177
- expect(snapshot_id).not_to eq(empty_snapshot_id)
3178
- end
3179
- end
3180
-
3181
- context 'and it does not start with javascript:' do
3182
- let(:url) { @url + '/each_element_with_events/a/href/regular' }
3183
-
3184
- it 'takes it into account' do
3185
- expect(snapshot_id).not_to eq(empty_snapshot_id)
3186
- end
3187
- end
3188
-
3189
- context 'and is out of scope' do
3190
- let(:url) { @url + '/each_element_with_events/a/href/out-of-scope' }
3191
-
3192
- it 'is ignored' do
3193
- expect(snapshot_id).to eq(empty_snapshot_id)
3194
- end
3195
- end
3196
- end
3197
-
3198
- context 'and the href is empty' do
3199
- let(:url) { @url + '/each_element_with_events/a/href/empty' }
3200
-
3201
- it 'takes it into account' do
3202
- expect(snapshot_id).not_to eq(empty_snapshot_id)
3203
- end
3204
- end
3205
- end
3206
-
3207
- context ':form' do
3208
- let(:empty_snapshot_id_url) { @url + '/snapshot_id/form/default' }
3209
-
3210
- context ':input' do
3211
- context 'of type "image"' do
3212
- let(:url) { @url + '/each_element_with_events/form/input/image' }
3213
-
3214
- it 'takes it into account' do
3215
- expect(snapshot_id).not_to eq(empty_snapshot_id)
3216
- end
3217
- end
3218
- end
3219
-
3220
- context 'and the action is not empty' do
3221
- context 'and it starts with javascript:' do
3222
- let(:url) { @url + '/each_element_with_events/form/action/javascript' }
3223
-
3224
- it 'takes it into account' do
3225
- expect(snapshot_id).not_to eq(empty_snapshot_id)
3226
- end
3227
- end
3228
-
3229
- context 'and it does not start with javascript:' do
3230
- let(:url) { @url + '/each_element_with_events/form/action/regular' }
3231
-
3232
- it 'takes it into account' do
3233
- expect(snapshot_id).not_to eq(empty_snapshot_id)
3234
- end
3235
- end
3236
-
3237
- context 'and is out of scope' do
3238
- let(:url) { @url + '/each_element_with_events/form/action/out-of-scope' }
3239
-
3240
- it 'is ignored' do
3241
- expect(snapshot_id).to eq(empty_snapshot_id)
3242
- end
3243
- end
3244
- end
3245
- end
3246
- end
3247
-
3248
3290
  end