arachni 1.2.1 → 1.3

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 (373) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -0
  3. data/Gemfile +1 -1
  4. data/README.md +16 -5
  5. data/components/checks/active/ldap_injection/errors.txt +1 -0
  6. data/components/checks/active/source_code_disclosure.rb +1 -1
  7. data/components/checks/active/unvalidated_redirect.rb +6 -6
  8. data/components/checks/active/unvalidated_redirect_dom.rb +10 -7
  9. data/components/checks/passive/grep/captcha.rb +14 -5
  10. data/components/checks/passive/grep/form_upload.rb +7 -3
  11. data/components/checks/passive/grep/hsts.rb +3 -3
  12. data/components/checks/passive/grep/html_objects.rb +2 -3
  13. data/components/checks/passive/grep/http_only_cookies.rb +2 -3
  14. data/components/checks/passive/grep/insecure_cookies.rb +1 -1
  15. data/components/checks/passive/grep/password_autocomplete.rb +2 -2
  16. data/components/checks/passive/grep/unencrypted_password_forms.rb +7 -7
  17. data/components/checks/passive/grep/x_frame_options.rb +2 -2
  18. data/components/checks/passive/http_put.rb +2 -3
  19. data/components/path_extractors/comments.rb +3 -3
  20. data/components/path_extractors/scripts.rb +10 -1
  21. data/components/plugins/defaults/autothrottle.rb +27 -18
  22. data/components/plugins/defaults/meta/remedies/discovery.rb +30 -33
  23. data/components/plugins/defaults/meta/remedies/timing_attacks.rb +7 -11
  24. data/components/plugins/login_script.rb +9 -3
  25. data/components/plugins/proxy.rb +4 -3
  26. data/components/reporters/html.rb +11 -14
  27. data/components/reporters/html/default/issue.erb +13 -38
  28. data/components/reporters/html/default/issue/info.erb +1 -1
  29. data/components/reporters/html/default/summary/issues/by_name.erb +3 -3
  30. data/components/reporters/stdout.rb +62 -71
  31. data/components/reporters/xml.rb +26 -40
  32. data/components/reporters/xml/schema.xsd +43 -89
  33. data/lib/arachni/browser.rb +52 -3
  34. data/lib/arachni/browser/javascript.rb +3 -3
  35. data/lib/arachni/browser/javascript/scripts/taint_tracer.js +46 -25
  36. data/lib/arachni/browser_cluster.rb +61 -0
  37. data/lib/arachni/browser_cluster/job.rb +21 -1
  38. data/lib/arachni/browser_cluster/jobs/browser_provider.rb +3 -1
  39. data/lib/arachni/browser_cluster/jobs/resource_exploration.rb +2 -1
  40. data/lib/arachni/browser_cluster/jobs/resource_exploration/event_trigger.rb +2 -1
  41. data/lib/arachni/browser_cluster/jobs/taint_trace.rb +3 -2
  42. data/lib/arachni/browser_cluster/jobs/taint_trace/event_trigger.rb +1 -1
  43. data/lib/arachni/browser_cluster/worker.rb +5 -0
  44. data/lib/arachni/check/auditor.rb +22 -12
  45. data/lib/arachni/data/framework.rb +13 -1
  46. data/lib/arachni/data/issues.rb +9 -25
  47. data/lib/arachni/element/base.rb +9 -3
  48. data/lib/arachni/element/capabilities/analyzable.rb +2 -6
  49. data/lib/arachni/element/capabilities/analyzable/differential.rb +24 -7
  50. data/lib/arachni/element/capabilities/analyzable/{taint.rb → signature.rb} +23 -23
  51. data/lib/arachni/element/capabilities/auditable.rb +0 -6
  52. data/lib/arachni/element/capabilities/dom_only.rb +61 -0
  53. data/lib/arachni/element/capabilities/with_dom.rb +3 -1
  54. data/lib/arachni/element/cookie.rb +35 -5
  55. data/lib/arachni/element/cookie/dom.rb +13 -4
  56. data/lib/arachni/element/{capabilities/auditable/dom.rb → dom.rb} +20 -68
  57. data/lib/arachni/element/dom/capabilities/auditable.rb +29 -0
  58. data/lib/arachni/element/dom/capabilities/inputtable.rb +27 -0
  59. data/lib/arachni/element/dom/capabilities/mutable.rb +21 -0
  60. data/lib/arachni/element/dom/capabilities/submittable.rb +52 -0
  61. data/lib/arachni/element/form.rb +12 -1
  62. data/lib/arachni/element/form/capabilities/mutable.rb +2 -1
  63. data/lib/arachni/element/form/capabilities/with_dom.rb +0 -1
  64. data/lib/arachni/element/form/dom.rb +9 -3
  65. data/lib/arachni/element/header.rb +14 -33
  66. data/lib/arachni/element/header/capabilities/inputtable.rb +29 -0
  67. data/lib/arachni/element/header/capabilities/mutable.rb +51 -0
  68. data/lib/arachni/element/input/dom.rb +71 -0
  69. data/lib/arachni/element/json.rb +2 -0
  70. data/lib/arachni/element/link.rb +3 -0
  71. data/lib/arachni/element/link/capabilities/with_dom.rb +0 -1
  72. data/lib/arachni/element/link/dom.rb +16 -3
  73. data/lib/arachni/element/link/dom/capabilities/submittable.rb +29 -0
  74. data/lib/arachni/element/link_template.rb +3 -5
  75. data/lib/arachni/element/link_template/capabilities/inputtable.rb +5 -0
  76. data/lib/arachni/element/link_template/capabilities/with_dom.rb +0 -1
  77. data/lib/arachni/element/link_template/dom.rb +16 -3
  78. data/lib/arachni/element/link_template/dom/capabilities/submittable.rb +29 -0
  79. data/lib/arachni/element/server.rb +3 -5
  80. data/lib/arachni/element/ui_form.rb +106 -0
  81. data/lib/arachni/element/ui_form/dom.rb +107 -0
  82. data/lib/arachni/element/ui_input.rb +62 -0
  83. data/lib/arachni/element/xml.rb +2 -1
  84. data/lib/arachni/framework.rb +7 -5
  85. data/lib/arachni/framework/parts/audit.rb +0 -1
  86. data/lib/arachni/framework/parts/check.rb +1 -0
  87. data/lib/arachni/framework/parts/data.rb +4 -0
  88. data/lib/arachni/framework/parts/state.rb +0 -2
  89. data/lib/arachni/http/client.rb +17 -6
  90. data/lib/arachni/http/proxy_server.rb +52 -5
  91. data/lib/arachni/http/request.rb +1 -1
  92. data/lib/arachni/issue.rb +34 -179
  93. data/lib/arachni/issue/severity.rb +2 -0
  94. data/lib/arachni/option_groups/audit.rb +22 -2
  95. data/lib/arachni/option_groups/browser_cluster.rb +15 -0
  96. data/lib/arachni/page.rb +3 -2
  97. data/lib/arachni/parser.rb +24 -5
  98. data/lib/arachni/platform/manager.rb +1 -2
  99. data/lib/arachni/rpc/server/framework.rb +3 -4
  100. data/lib/arachni/rpc/server/framework/multi_instance.rb +2 -1
  101. data/lib/arachni/session.rb +1 -1
  102. data/lib/arachni/trainer.rb +4 -7
  103. data/lib/arachni/watir/element.rb +12 -1
  104. data/lib/version +1 -1
  105. data/spec/arachni/browser/element_locator_spec.rb +43 -43
  106. data/spec/arachni/browser/javascript/dom_monitor_spec.rb +44 -44
  107. data/spec/arachni/browser/javascript/proxy/stub_spec.rb +17 -14
  108. data/spec/arachni/browser/javascript/proxy_spec.rb +24 -24
  109. data/spec/arachni/browser/javascript/taint_tracer/frame/called_function_spec.rb +11 -11
  110. data/spec/arachni/browser/javascript/taint_tracer/frame_spec.rb +7 -7
  111. data/spec/arachni/browser/javascript/taint_tracer/sink/data_flow_spec.rb +13 -13
  112. data/spec/arachni/browser/javascript/taint_tracer/sink/execution_flow_spec.rb +7 -7
  113. data/spec/arachni/browser/javascript/taint_tracer_spec.rb +568 -558
  114. data/spec/arachni/browser/javascript_spec.rb +73 -63
  115. data/spec/arachni/browser_cluster/job/result_spec.rb +3 -3
  116. data/spec/arachni/browser_cluster/job_spec.rb +68 -48
  117. data/spec/arachni/browser_cluster/jobs/resource_exploration/event_trigger/result_spec.rb +2 -2
  118. data/spec/arachni/browser_cluster/jobs/resource_exploration/event_trigger_spec.rb +5 -4
  119. data/spec/arachni/browser_cluster/jobs/resource_exploration/result_spec.rb +2 -2
  120. data/spec/arachni/browser_cluster/jobs/resource_exploration_spec.rb +5 -5
  121. data/spec/arachni/browser_cluster/worker_spec.rb +87 -70
  122. data/spec/arachni/browser_cluster_spec.rb +64 -39
  123. data/spec/arachni/browser_spec.rb +692 -527
  124. data/spec/arachni/check/auditor_spec.rb +177 -147
  125. data/spec/arachni/check/base_spec.rb +33 -33
  126. data/spec/arachni/check/manager_spec.rb +15 -15
  127. data/spec/arachni/component/base_spec.rb +8 -8
  128. data/spec/arachni/component/manager_spec.rb +100 -99
  129. data/spec/arachni/component/options/address_spec.rb +3 -3
  130. data/spec/arachni/component/options/base_spec.rb +7 -7
  131. data/spec/arachni/component/options/bool_spec.rb +9 -9
  132. data/spec/arachni/component/options/float_spec.rb +6 -6
  133. data/spec/arachni/component/options/int_spec.rb +5 -5
  134. data/spec/arachni/component/options/multiple_choice_spec.rb +12 -12
  135. data/spec/arachni/component/options/object_spec.rb +2 -2
  136. data/spec/arachni/component/options/path_spec.rb +3 -3
  137. data/spec/arachni/component/options/port_spec.rb +5 -5
  138. data/spec/arachni/component/options/string_spec.rb +3 -3
  139. data/spec/arachni/component/options/url_spec.rb +4 -4
  140. data/spec/arachni/component/utilities_spec.rb +2 -2
  141. data/spec/arachni/data/framework/rpc_spec.rb +10 -9
  142. data/spec/arachni/data/framework_spec.rb +65 -46
  143. data/spec/arachni/data/issues_spec.rb +39 -77
  144. data/spec/arachni/data/plugins_spec.rb +11 -11
  145. data/spec/arachni/data/session_spec.rb +6 -6
  146. data/spec/arachni/data_spec.rb +8 -8
  147. data/spec/arachni/element/body_spec.rb +10 -10
  148. data/spec/arachni/element/capabilities/analyzable/differential_spec.rb +39 -21
  149. data/spec/arachni/element/capabilities/analyzable/{taint_spec.rb → signature_spec.rb} +63 -63
  150. data/spec/arachni/element/capabilities/analyzable/timeout_spec.rb +51 -51
  151. data/spec/arachni/element/capabilities/with_scope/scope_spec.rb +5 -5
  152. data/spec/arachni/element/cookie/dom_spec.rb +37 -18
  153. data/spec/arachni/element/cookie_spec.rb +206 -139
  154. data/spec/arachni/element/form/dom_spec.rb +36 -19
  155. data/spec/arachni/element/form_spec.rb +210 -187
  156. data/spec/arachni/element/generic_dom_spec.rb +14 -14
  157. data/spec/arachni/element/header_spec.rb +35 -17
  158. data/spec/arachni/element/json_spec.rb +53 -31
  159. data/spec/arachni/element/link/dom_spec.rb +46 -28
  160. data/spec/arachni/element/link_spec.rb +58 -40
  161. data/spec/arachni/element/link_template/dom_spec.rb +47 -29
  162. data/spec/arachni/element/link_template_spec.rb +79 -61
  163. data/spec/arachni/element/path_spec.rb +1 -1
  164. data/spec/arachni/element/server_spec.rb +33 -32
  165. data/spec/arachni/element/ui_form/ui_form_dom_spec.rb +164 -0
  166. data/spec/arachni/element/ui_form_spec.rb +242 -0
  167. data/spec/arachni/element/ui_input/dom_spec.rb +157 -0
  168. data/spec/arachni/element/ui_input_spec.rb +136 -0
  169. data/spec/arachni/element/xml_spec.rb +42 -24
  170. data/spec/arachni/element_filter_spec.rb +49 -48
  171. data/spec/arachni/error_spec.rb +3 -3
  172. data/spec/arachni/framework/parts/audit_spec.rb +64 -63
  173. data/spec/arachni/framework/parts/browser_spec.rb +16 -16
  174. data/spec/arachni/framework/parts/check_spec.rb +3 -3
  175. data/spec/arachni/framework/parts/data_spec.rb +48 -48
  176. data/spec/arachni/framework/parts/platform_spec.rb +3 -3
  177. data/spec/arachni/framework/parts/plugin_spec.rb +7 -6
  178. data/spec/arachni/framework/parts/report_spec.rb +7 -7
  179. data/spec/arachni/framework/parts/scope_spec.rb +16 -16
  180. data/spec/arachni/framework/parts/state_spec.rb +68 -69
  181. data/spec/arachni/framework_spec.rb +39 -31
  182. data/spec/arachni/http/client/dynamic_404_handlers_spec.rb +32 -32
  183. data/spec/arachni/http/client_spec.rb +219 -208
  184. data/spec/arachni/http/cookie_jar_spec.rb +72 -72
  185. data/spec/arachni/http/headers_spec.rb +14 -14
  186. data/spec/arachni/http/proxy_server_spec.rb +43 -42
  187. data/spec/arachni/http/request_spec.rb +105 -103
  188. data/spec/arachni/http/response/scope_spec.rb +24 -24
  189. data/spec/arachni/http/response_spec.rb +50 -49
  190. data/spec/arachni/issue/severity_spec.rb +10 -9
  191. data/spec/arachni/issue_spec.rb +71 -369
  192. data/spec/arachni/option_groups/audit_spec.rb +114 -114
  193. data/spec/arachni/option_groups/browser_cluster_spec.rb +20 -3
  194. data/spec/arachni/option_groups/datastore_spec.rb +6 -6
  195. data/spec/arachni/option_groups/dispatcher_spec.rb +19 -19
  196. data/spec/arachni/option_groups/http_spec.rb +11 -11
  197. data/spec/arachni/option_groups/input_spec.rb +31 -27
  198. data/spec/arachni/option_groups/output_spec.rb +2 -2
  199. data/spec/arachni/option_groups/paths_spec.rb +17 -17
  200. data/spec/arachni/option_groups/rpc_spec.rb +2 -2
  201. data/spec/arachni/option_groups/scope_spec.rb +40 -40
  202. data/spec/arachni/option_groups/session_spec.rb +6 -5
  203. data/spec/arachni/option_groups/snapshot_spec.rb +4 -4
  204. data/spec/arachni/options_spec.rb +46 -45
  205. data/spec/arachni/page/dom/transition_spec.rb +74 -72
  206. data/spec/arachni/page/dom_spec.rb +35 -35
  207. data/spec/arachni/page/scope_spec.rb +15 -15
  208. data/spec/arachni/page_spec.rb +217 -217
  209. data/spec/arachni/parser_spec.rb +106 -104
  210. data/spec/arachni/platform/fingerprinter_spec.rb +17 -14
  211. data/spec/arachni/platform/list_spec.rb +33 -33
  212. data/spec/arachni/platform/manager_spec.rb +67 -64
  213. data/spec/arachni/plugin/base_spec.rb +10 -10
  214. data/spec/arachni/plugin/manager_spec.rb +38 -37
  215. data/spec/arachni/report_spec.rb +43 -40
  216. data/spec/arachni/reporter/base_spec.rb +15 -15
  217. data/spec/arachni/reporter/manager_spec.rb +4 -4
  218. data/spec/arachni/reporter/options_spec.rb +6 -6
  219. data/spec/arachni/rpc/client/base_spec.rb +6 -6
  220. data/spec/arachni/rpc/client/dispatcher_spec.rb +2 -2
  221. data/spec/arachni/rpc/client/instance_spec.rb +6 -6
  222. data/spec/arachni/rpc/server/active_options_spec.rb +11 -8
  223. data/spec/arachni/rpc/server/base_spec.rb +5 -5
  224. data/spec/arachni/rpc/server/checks/manager_spec.rb +8 -8
  225. data/spec/arachni/rpc/server/dispatcher/node_spec.rb +37 -37
  226. data/spec/arachni/rpc/server/dispatcher/service_spec.rb +15 -14
  227. data/spec/arachni/rpc/server/dispatcher_spec.rb +36 -35
  228. data/spec/arachni/rpc/server/framework/distributor_spec.rb +36 -36
  229. data/spec/arachni/rpc/server/framework_multi_spec.rb +340 -336
  230. data/spec/arachni/rpc/server/framework_spec.rb +90 -85
  231. data/spec/arachni/rpc/server/instance_spec.rb +126 -107
  232. data/spec/arachni/rpc/server/output_spec.rb +1 -1
  233. data/spec/arachni/rpc/server/plugin/manager_spec.rb +6 -6
  234. data/spec/arachni/ruby/array_spec.rb +42 -42
  235. data/spec/arachni/ruby/hash_spec.rb +20 -18
  236. data/spec/arachni/ruby/io_spec.rb +2 -2
  237. data/spec/arachni/ruby/object_spec.rb +1 -1
  238. data/spec/arachni/ruby/set_spec.rb +3 -3
  239. data/spec/arachni/ruby/string_spec.rb +30 -30
  240. data/spec/arachni/ruby/webrick_spec.rb +2 -2
  241. data/spec/arachni/scope_spec.rb +1 -1
  242. data/spec/arachni/session_spec.rb +67 -64
  243. data/spec/arachni/snapshot_spec.rb +15 -15
  244. data/spec/arachni/state/audit_spec.rb +11 -11
  245. data/spec/arachni/state/element_filter_spec.rb +6 -6
  246. data/spec/arachni/state/framework/rpc_spec.rb +12 -12
  247. data/spec/arachni/state/framework_spec.rb +125 -121
  248. data/spec/arachni/state/http_spec.rb +7 -7
  249. data/spec/arachni/state/options_spec.rb +7 -7
  250. data/spec/arachni/state/plugins_spec.rb +8 -8
  251. data/spec/arachni/state_spec.rb +10 -10
  252. data/spec/arachni/support/buffer/autoflush_spec.rb +16 -16
  253. data/spec/arachni/support/buffer/base_spec.rb +39 -39
  254. data/spec/arachni/support/cache/least_cost_replacement_spec.rb +18 -18
  255. data/spec/arachni/support/cache/least_recently_pushed_spec.rb +24 -24
  256. data/spec/arachni/support/cache/least_recently_used_spec.rb +20 -20
  257. data/spec/arachni/support/cache/preference_spec.rb +4 -4
  258. data/spec/arachni/support/cache/random_replacement_spec.rb +8 -8
  259. data/spec/arachni/support/crypto/rsa_aes_cbc_spec.rb +1 -1
  260. data/spec/arachni/support/database/hash_spec.rb +44 -43
  261. data/spec/arachni/support/database/queue_spec.rb +27 -27
  262. data/spec/arachni/support/lookup/hash_set_spec.rb +8 -8
  263. data/spec/arachni/support/lookup/moolb_spec.rb +3 -3
  264. data/spec/arachni/support/mixins/observable_spec.rb +6 -6
  265. data/spec/arachni/support/signature_spec.rb +19 -19
  266. data/spec/arachni/trainer_spec.rb +39 -39
  267. data/spec/arachni/typhoeus/hydra_spec.rb +2 -2
  268. data/spec/arachni/uri/scope_spec.rb +66 -66
  269. data/spec/arachni/uri_spec.rb +107 -105
  270. data/spec/arachni/utilities_spec.rb +40 -40
  271. data/spec/components/checks/active/csrf_spec.rb +8 -8
  272. data/spec/components/checks/active/no_sql_injection_spec.rb +1 -1
  273. data/spec/components/checks/active/sql_injection_spec.rb +16 -16
  274. data/spec/components/checks/active/trainer_spec.rb +4 -4
  275. data/spec/components/checks/active/unvalidated_redirect_dom_spec.rb +4 -2
  276. data/spec/components/checks/active/xpath_injection_spec.rb +1 -1
  277. data/spec/components/checks/active/xss_dom_script_context_spec.rb +51 -21
  278. data/spec/components/checks/active/xss_dom_spec.rb +46 -24
  279. data/spec/components/checks/passive/allowed_methods_spec.rb +1 -1
  280. data/spec/components/checks/passive/grep/cookie_set_for_parent_domain_spec.rb +1 -1
  281. data/spec/components/checks/passive/grep/hsts_spec.rb +2 -2
  282. data/spec/components/checks/passive/grep/http_only_cookies_spec.rb +1 -1
  283. data/spec/components/checks/passive/grep/insecure_cookies_spec.rb +1 -1
  284. data/spec/components/checks/passive/grep/insecure_cors_policy_spec.rb +2 -2
  285. data/spec/components/checks/passive/grep/password_autocomplete_spec.rb +1 -1
  286. data/spec/components/checks/passive/grep/private_ip_spec.rb +3 -3
  287. data/spec/components/checks/passive/grep/unencrypted_password_forms_spec.rb +1 -1
  288. data/spec/components/checks/passive/grep/x_frame_options_spec.rb +2 -2
  289. data/spec/components/checks/passive/interesting_responses_spec.rb +2 -2
  290. data/spec/components/checks/passive/webdav_spec.rb +1 -1
  291. data/spec/components/checks/passive/xst_spec.rb +1 -1
  292. data/spec/components/fingerprinters/servers/apache_spec.rb +2 -2
  293. data/spec/components/path_extractors/comments_spec.rb +5 -1
  294. data/spec/components/path_extractors/scripts_spec.rb +5 -2
  295. data/spec/components/plugins/autologin_spec.rb +22 -22
  296. data/spec/components/plugins/autothrottle_spec.rb +6 -5
  297. data/spec/components/plugins/content_types_spec.rb +4 -4
  298. data/spec/components/plugins/cookie_collector_spec.rb +5 -5
  299. data/spec/components/plugins/exec_spec.rb +12 -12
  300. data/spec/components/plugins/form_dicattack_spec.rb +3 -3
  301. data/spec/components/plugins/headers_collector_spec.rb +8 -8
  302. data/spec/components/plugins/healthmap_spec.rb +3 -3
  303. data/spec/components/plugins/http_dicattack_spec.rb +3 -3
  304. data/spec/components/plugins/login_script_spec.rb +79 -22
  305. data/spec/components/plugins/meta/remedies/discovery_spec.rb +3 -2
  306. data/spec/components/plugins/meta/remedies/timing_attacks_spec.rb +3 -3
  307. data/spec/components/plugins/meta/uniformity_spec.rb +2 -2
  308. data/spec/components/plugins/restrict_to_dom_state_spec.rb +1 -1
  309. data/spec/components/plugins/script_spec.rb +1 -1
  310. data/spec/components/plugins/uncommon_headers_spec.rb +2 -2
  311. data/spec/components/plugins/vector_collector_spec.rb +2 -2
  312. data/spec/components/plugins/vector_feed_spec.rb +40 -40
  313. data/spec/components/plugins/waf_detector_spec.rb +6 -6
  314. data/spec/components/reporters/json_spec.rb +4 -4
  315. data/spec/components/reporters/marshal_spec.rb +2 -2
  316. data/spec/components/reporters/yaml_spec.rb +3 -2
  317. data/spec/external/wavsep/active/sqli_spec.rb +1 -3
  318. data/spec/spec_helper.rb +4 -0
  319. data/spec/support/factories/element/ui_form.rb +14 -0
  320. data/spec/support/factories/element/ui_input.rb +13 -0
  321. data/spec/support/factories/issue.rb +0 -13
  322. data/spec/support/fixtures/report.afr +0 -0
  323. data/spec/support/fixtures/{taint_check/taint.rb → signature_check/signature.rb} +2 -2
  324. data/spec/support/helpers/browser_cluster/jobs/taint_tracer.rb +11 -11
  325. data/spec/support/helpers/framework.rb +1 -1
  326. data/spec/support/helpers/pages.rb +2 -2
  327. data/spec/support/servers/arachni/browser.rb +139 -0
  328. data/spec/support/servers/arachni/browser/javascript/taint_tracer.rb +40 -0
  329. data/spec/support/servers/arachni/element/capabilities/analyzable/{taint.rb → signature.rb} +0 -0
  330. data/spec/support/servers/arachni/element/input/input_dom.rb +102 -0
  331. data/spec/support/servers/arachni/element/ui_form/ui_form_dom.rb +238 -0
  332. data/spec/support/servers/checks/active/trainer_check.rb +7 -7
  333. data/spec/support/servers/checks/active/unvalidated_redirect_dom.rb +22 -6
  334. data/spec/support/servers/checks/active/xss_dom.rb +50 -0
  335. data/spec/support/servers/checks/active/xss_dom_script_context.rb +53 -0
  336. data/spec/support/shared/browser/javascript/taint_tracer/sink/base.rb +6 -6
  337. data/spec/support/shared/check.rb +10 -12
  338. data/spec/support/shared/component/options/base.rb +24 -24
  339. data/spec/support/shared/element/base.rb +25 -25
  340. data/spec/support/shared/element/capabilities/auditable.rb +116 -140
  341. data/spec/support/shared/element/capabilities/dom_only.rb +65 -0
  342. data/spec/support/shared/element/capabilities/inputtable.rb +71 -86
  343. data/spec/support/shared/element/capabilities/mutable.rb +122 -111
  344. data/spec/support/shared/element/capabilities/refreshable.rb +10 -10
  345. data/spec/support/shared/element/capabilities/{submitable.rb → submittable.rb} +26 -26
  346. data/spec/support/shared/element/capabilities/with_auditor.rb +10 -10
  347. data/spec/support/shared/element/capabilities/with_dom.rb +8 -8
  348. data/spec/support/shared/element/capabilities/with_node.rb +4 -6
  349. data/spec/support/shared/element/capabilities/with_scope.rb +2 -2
  350. data/spec/support/shared/element/capabilities/with_source.rb +6 -8
  351. data/spec/support/shared/element/dom.rb +144 -0
  352. data/spec/support/shared/element/dom/auditable.rb +42 -0
  353. data/spec/support/shared/element/dom/inputtable.rb +5 -0
  354. data/spec/support/shared/element/dom/mutable.rb +3 -0
  355. data/spec/support/shared/element/dom/submittable.rb +119 -0
  356. data/spec/support/shared/external/wavsep.rb +3 -3
  357. data/spec/support/shared/fingerprinter.rb +2 -2
  358. data/spec/support/shared/framework.rb +1 -1
  359. data/spec/support/shared/http/message.rb +9 -9
  360. data/spec/support/shared/option_group.rb +17 -17
  361. data/spec/support/shared/path_extractor.rb +1 -1
  362. data/spec/support/shared/plugin.rb +2 -2
  363. data/spec/support/shared/support/cache.rb +57 -57
  364. data/spec/support/shared/support/lookup.rb +25 -25
  365. data/ui/cli/framework.rb +22 -11
  366. data/ui/cli/framework/option_parser.rb +15 -0
  367. data/ui/cli/option_parser.rb +8 -1
  368. data/ui/cli/output.rb +2 -1
  369. metadata +54 -20
  370. data/components/checks/active/xss_dom_inputs.rb +0 -236
  371. data/spec/components/checks/active/xss_dom_inputs_spec.rb +0 -30
  372. data/spec/support/servers/checks/active/xss_dom_inputs.rb +0 -59
  373. data/spec/support/shared/element/capabilities/auditable/dom.rb +0 -322
@@ -1,12 +1,26 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Arachni::Element::Form::DOM do
4
- it_should_behave_like 'element_dom', inputs: { 'param' => '1' }
4
+ inputs = { 'param' => '1' }
5
+
6
+ it_should_behave_like 'element_dom'
7
+
8
+ it_should_behave_like 'with_node'
9
+ it_should_behave_like 'with_auditor'
10
+
11
+ it_should_behave_like 'submittable_dom'
12
+ it_should_behave_like 'inputtable_dom', inputs: inputs
13
+ it_should_behave_like 'mutable_dom', inputs: inputs
14
+ it_should_behave_like 'auditable_dom'
5
15
 
6
16
  def auditable_extract_parameters( page )
7
17
  YAML.load( page.document.css( 'body' ).text )
8
18
  end
9
19
 
20
+ def run
21
+ auditor.browser_cluster.wait
22
+ end
23
+
10
24
  before :each do
11
25
  @framework = Arachni::Framework.new
12
26
  @page = Arachni::Page.from_url( "#{url}/form" )
@@ -33,25 +47,25 @@ describe Arachni::Element::Form::DOM do
33
47
 
34
48
  describe '#type' do
35
49
  it 'returns :form_dom' do
36
- subject.type.should == :form_dom
50
+ expect(subject.type).to eq(:form_dom)
37
51
  end
38
52
  end
39
53
 
40
54
  describe '.type' do
41
55
  it 'returns :form_dom' do
42
- described_class.type.should == :form_dom
56
+ expect(described_class.type).to eq(:form_dom)
43
57
  end
44
58
  end
45
59
 
46
60
  describe '#parent' do
47
61
  it 'returns the parent element' do
48
- subject.parent.should be_kind_of Arachni::Element::Form
62
+ expect(subject.parent).to be_kind_of Arachni::Element::Form
49
63
  end
50
64
  end
51
65
 
52
66
  describe '#inputs' do
53
67
  it 'uses the parent\'s inputs' do
54
- subject.inputs.should == parent.inputs
68
+ expect(subject.inputs).to eq(parent.inputs)
55
69
  end
56
70
  end
57
71
 
@@ -63,17 +77,17 @@ describe Arachni::Element::Form::DOM do
63
77
  browser.load subject.page
64
78
 
65
79
  element = subject.locate
66
- element.should be_kind_of Watir::HTMLElement
80
+ expect(element).to be_kind_of Watir::HTMLElement
67
81
 
68
- parent.class.from_document(
82
+ expect(parent.class.from_document(
69
83
  parent.url, Nokogiri::HTML(element.html)
70
- ).first.should == parent
84
+ ).first).to eq(parent)
71
85
 
72
86
  called = true
73
87
  end
74
88
 
75
89
  subject.auditor.browser_cluster.wait
76
- called.should be_true
90
+ expect(called).to be_truthy
77
91
  end
78
92
  end
79
93
 
@@ -91,46 +105,49 @@ describe Arachni::Element::Form::DOM do
91
105
 
92
106
  page = browser.to_page
93
107
 
94
- subject.inputs.should == auditable_extract_parameters( page )
108
+ expect(subject.inputs).to eq(auditable_extract_parameters( page ))
95
109
  called = true
96
110
  end
97
111
 
98
112
  subject.auditor.browser_cluster.wait
99
- called.should be_true
113
+ expect(called).to be_truthy
100
114
  end
101
115
 
102
116
  it 'returns a playable transition' do
103
117
  inputs = { 'param' => 'The.Dude' }
104
118
  subject.update inputs
105
119
 
106
- transition = nil
120
+ transitions = []
107
121
  called = false
108
122
  subject.with_browser do |browser|
109
123
  subject.browser = browser
110
124
  browser.load subject.page
111
125
 
112
- transition = subject.trigger
126
+ transitions = subject.trigger
113
127
 
114
128
  page = browser.to_page
115
129
 
116
- subject.inputs.should == auditable_extract_parameters( page )
130
+ expect(subject.inputs).to eq(auditable_extract_parameters( page ))
117
131
  called = true
118
132
  end
119
133
 
120
134
  subject.auditor.browser_cluster.wait
121
- called.should be_true
135
+ expect(called).to be_truthy
122
136
 
123
137
  called = false
124
138
  auditor.with_browser do |browser|
125
139
  browser.load subject.page
126
- auditable_extract_parameters( browser.to_page ).should be_false
140
+ expect(auditable_extract_parameters( browser.to_page )).to be_falsey
141
+
142
+ transitions.each do |transition|
143
+ transition.play browser
144
+ end
127
145
 
128
- transition.play browser
129
- auditable_extract_parameters( browser.to_page ).should == inputs
146
+ expect(auditable_extract_parameters( browser.to_page )).to eq(inputs)
130
147
  called = true
131
148
  end
132
149
  auditor.browser_cluster.wait
133
- called.should be_true
150
+ expect(called).to be_truthy
134
151
  end
135
152
  end
136
153
 
@@ -7,11 +7,29 @@ describe Arachni::Element::Form do
7
7
  </form>'
8
8
 
9
9
  it_should_behave_like 'element'
10
- it_should_behave_like 'with_node', html
10
+ it_should_behave_like 'with_node'
11
11
  it_should_behave_like 'with_dom', html
12
12
  it_should_behave_like 'refreshable'
13
+ it_should_behave_like 'with_source'
14
+ it_should_behave_like 'with_auditor'
15
+
16
+ it_should_behave_like 'submittable'
17
+ it_should_behave_like 'inputtable'
18
+ it_should_behave_like 'mutable'
13
19
  it_should_behave_like 'auditable'
14
20
 
21
+ before :each do
22
+ @framework ||= Arachni::Framework.new
23
+ @auditor = Auditor.new( Arachni::Page.from_url( url ), @framework )
24
+ end
25
+
26
+ after :each do
27
+ @framework.reset
28
+ reset_options
29
+ end
30
+
31
+ let(:auditor) { @auditor }
32
+
15
33
  def auditable_extract_parameters( resource )
16
34
  YAML.load( resource.body )
17
35
  end
@@ -39,29 +57,29 @@ describe Arachni::Element::Form do
39
57
  end
40
58
 
41
59
  it 'assigned to Arachni::Form for easy access' do
42
- Arachni::Form.should == described_class
60
+ expect(Arachni::Form).to eq(described_class)
43
61
  end
44
62
 
45
63
  describe '#initialize' do
46
64
  describe :method do
47
65
  it 'defaults to :get' do
48
- described_class.new( url: url ).method.should == :get
66
+ expect(described_class.new( url: url ).method).to eq(:get)
49
67
  end
50
68
  end
51
69
  describe :name do
52
70
  it 'sets #name' do
53
- described_class.new( url: url, name: 'john' ).name.should == 'john'
71
+ expect(described_class.new( url: url, name: 'john' ).name).to eq('john')
54
72
  end
55
73
  end
56
74
  describe :action do
57
75
  it 'sets #action' do
58
76
  action = "#{url}stuff"
59
- described_class.new( url: url, action: action ).action.should == action
77
+ expect(described_class.new( url: url, action: action ).action).to eq(action)
60
78
  end
61
79
 
62
80
  context 'when nil' do
63
81
  it 'defaults to :url' do
64
- described_class.new( url: url ).action.should == url
82
+ expect(described_class.new( url: url ).action).to eq(url)
65
83
  end
66
84
  end
67
85
  end
@@ -69,26 +87,26 @@ describe Arachni::Element::Form do
69
87
 
70
88
  describe '#mutation_with_original_values?' do
71
89
  it 'returns false' do
72
- subject.mutation_with_original_values?.should be_false
90
+ expect(subject.mutation_with_original_values?).to be_falsey
73
91
  end
74
92
 
75
93
  context 'when #mutation_with_original_values' do
76
94
  it 'returns true' do
77
95
  subject.mutation_with_original_values
78
- subject.mutation_with_original_values?.should be_true
96
+ expect(subject.mutation_with_original_values?).to be_truthy
79
97
  end
80
98
  end
81
99
  end
82
100
 
83
101
  describe '#mutation_with_sample_values?' do
84
102
  it 'returns false' do
85
- subject.mutation_with_sample_values?.should be_false
103
+ expect(subject.mutation_with_sample_values?).to be_falsey
86
104
  end
87
105
 
88
106
  context 'when #mutation_with_sample_values' do
89
107
  it 'returns true' do
90
108
  subject.mutation_with_sample_values
91
- subject.mutation_with_sample_values?.should be_true
109
+ expect(subject.mutation_with_sample_values?).to be_truthy
92
110
  end
93
111
  end
94
112
  end
@@ -97,7 +115,7 @@ describe Arachni::Element::Form do
97
115
  context 'when #force_train?' do
98
116
  it 'returns #mutation_id' do
99
117
  subject.mutation_with_original_values
100
- subject.audit_id( 'stuff' ).should == subject.id
118
+ expect(subject.audit_id( 'stuff' )).to eq(subject.id)
101
119
  end
102
120
  end
103
121
  end
@@ -114,7 +132,7 @@ describe Arachni::Element::Form do
114
132
  subject.audit( 'stuff', each_mutation: each_mutation ) {}
115
133
  subject.http.run
116
134
 
117
- had_mutation_with_original_values.should be_false
135
+ expect(had_mutation_with_original_values).to be_falsey
118
136
  end
119
137
 
120
138
  it 'ignores mutation_with_sample_values' do
@@ -127,7 +145,7 @@ describe Arachni::Element::Form do
127
145
  subject.audit( 'stuff', each_mutation: each_mutation ) {}
128
146
  subject.http.run
129
147
 
130
- had_mutation_with_sample_values.should be_false
148
+ expect(had_mutation_with_sample_values).to be_falsey
131
149
  end
132
150
  end
133
151
  end
@@ -135,8 +153,8 @@ describe Arachni::Element::Form do
135
153
  describe '#name_or_id' do
136
154
  context 'when a #name is available' do
137
155
  it 'returns it' do
138
- described_class.new( url: url, name: 'john' ).
139
- name_or_id.should == 'john'
156
+ expect(described_class.new( url: url, name: 'john' ).
157
+ name_or_id).to eq('john')
140
158
  end
141
159
  end
142
160
 
@@ -144,8 +162,8 @@ describe Arachni::Element::Form do
144
162
  subject { described_class.new( url: url, id: 'john' ) }
145
163
 
146
164
  it 'returns the configured :id' do
147
- subject.name.should be_nil
148
- subject.name_or_id.should == 'john'
165
+ expect(subject.name).to be_nil
166
+ expect(subject.name_or_id).to eq('john')
149
167
  end
150
168
  end
151
169
 
@@ -153,7 +171,7 @@ describe Arachni::Element::Form do
153
171
  subject { described_class.new( url: url ) }
154
172
 
155
173
  it 'returns nil' do
156
- subject.name_or_id.should be_nil
174
+ expect(subject.name_or_id).to be_nil
157
175
  end
158
176
  end
159
177
  end
@@ -162,33 +180,33 @@ describe Arachni::Element::Form do
162
180
  context 'when there are no #inputs' do
163
181
  it 'returns nil' do
164
182
  subject.inputs = {}
165
- subject.dom.should be_nil
183
+ expect(subject.dom).to be_nil
166
184
  end
167
185
  end
168
186
 
169
187
  context 'when there is no #node' do
170
188
  it 'returns nil' do
171
189
  subject.source = nil
172
- subject.dom.should be_nil
190
+ expect(subject.dom).to be_nil
173
191
  end
174
192
  end
175
193
  end
176
194
 
177
195
  describe '#force_train?' do
178
196
  it 'returns false' do
179
- subject.force_train?.should be_false
197
+ expect(subject.force_train?).to be_falsey
180
198
  end
181
199
 
182
200
  context 'when #mutation_with_original_values?' do
183
201
  it 'returns true' do
184
202
  subject.mutation_with_original_values
185
- subject.force_train?.should be_true
203
+ expect(subject.force_train?).to be_truthy
186
204
  end
187
205
  end
188
206
  context 'when #mutation_with_sample_values?' do
189
207
  it 'returns true' do
190
208
  subject.mutation_with_sample_values
191
- subject.force_train?.should be_true
209
+ expect(subject.force_train?).to be_truthy
192
210
  end
193
211
  end
194
212
  end
@@ -221,11 +239,11 @@ describe Arachni::Element::Form do
221
239
  let(:method) { :get }
222
240
 
223
241
  it 'removes the URL query' do
224
- subject.action.should == url
242
+ expect(subject.action).to eq(url)
225
243
  end
226
244
 
227
245
  it 'merges the URL query parameters with the given :inputs' do
228
- subject.inputs.should == query_inputs.merge( option_inputs )
246
+ expect(subject.inputs).to eq(query_inputs.merge( option_inputs ))
229
247
  end
230
248
 
231
249
  context 'when URL query parameters and :inputs have the same name' do
@@ -237,7 +255,7 @@ describe Arachni::Element::Form do
237
255
  end
238
256
 
239
257
  it 'it gives precedence to the :inputs' do
240
- subject.inputs.should == query_inputs.merge( option_inputs )
258
+ expect(subject.inputs).to eq(query_inputs.merge( option_inputs ))
241
259
  end
242
260
  end
243
261
  end
@@ -246,11 +264,11 @@ describe Arachni::Element::Form do
246
264
  let(:method) { :post }
247
265
 
248
266
  it 'preserves the URL query' do
249
- subject.action.should == action
267
+ expect(subject.action).to eq(action)
250
268
  end
251
269
 
252
270
  it 'ignores the URL query parameters' do
253
- subject.inputs.should == option_inputs
271
+ expect(subject.inputs).to eq(option_inputs)
254
272
  end
255
273
  end
256
274
  end
@@ -270,13 +288,14 @@ describe Arachni::Element::Form do
270
288
  }
271
289
  }
272
290
 
273
- described_class.new( options ).details_for( :password ).should ==
291
+ expect(described_class.new( options ).details_for( :password )).to eq(
274
292
  options[:inputs]['password']
293
+ )
275
294
  end
276
295
  end
277
296
  describe 'when no data is available' do
278
297
  it 'return nil' do
279
- described_class.new( options ).details_for( :username ).should == {}
298
+ expect(described_class.new( options ).details_for( :username )).to eq({})
280
299
  end
281
300
  end
282
301
  end
@@ -284,12 +303,12 @@ describe Arachni::Element::Form do
284
303
  describe '#name' do
285
304
  context 'when there is a form name' do
286
305
  it 'returns it' do
287
- described_class.new( options ).name.should == options[:name]
306
+ expect(described_class.new( options ).name).to eq(options[:name])
288
307
  end
289
308
  end
290
309
  describe 'when no data is available' do
291
310
  it 'return nil' do
292
- described_class.new( url: options[:url] ).name.should be_nil
311
+ expect(described_class.new( url: options[:url] ).name).to be_nil
293
312
  end
294
313
  end
295
314
  end
@@ -314,8 +333,8 @@ describe Arachni::Element::Form do
314
333
  }
315
334
 
316
335
  e = described_class.new( options )
317
- e.field_type_for( 'password' ).should == :password
318
- e.field_type_for( 'hidden_field' ).should == :hidden
336
+ expect(e.field_type_for( 'password' )).to eq(:password)
337
+ expect(e.field_type_for( 'hidden_field' )).to eq(:hidden)
319
338
  end
320
339
  end
321
340
 
@@ -333,8 +352,8 @@ describe Arachni::Element::Form do
333
352
  </body>
334
353
  </html>'
335
354
 
336
- described_class.from_document( url, html ).
337
- first.requires_password?.should be_true
355
+ expect(described_class.from_document( url, html ).
356
+ first.requires_password?).to be_truthy
338
357
  end
339
358
  end
340
359
  context 'when the form does not have a password field' do
@@ -349,8 +368,8 @@ describe Arachni::Element::Form do
349
368
  </body>
350
369
  </html>'
351
370
 
352
- described_class.from_document( url, html ).
353
- first.requires_password?.should be_false
371
+ expect(described_class.from_document( url, html ).
372
+ first.requires_password?).to be_falsey
354
373
  end
355
374
  end
356
375
  end
@@ -370,16 +389,16 @@ describe Arachni::Element::Form do
370
389
  has_sample ||= false
371
390
 
372
391
  e.mutations( 'seed' ).each do |m|
373
- m.url.should == e.url
374
- m.action.should == e.action
392
+ expect(m.url).to eq(e.url)
393
+ expect(m.action).to eq(e.action)
375
394
 
376
395
  if m.mutation_with_original_values?
377
- m.inputs.should == e.inputs
396
+ expect(m.inputs).to eq(e.inputs)
378
397
  has_original ||= true
379
398
  end
380
399
  end
381
400
 
382
- has_original.should be_true
401
+ expect(has_original).to be_truthy
383
402
  end
384
403
  end
385
404
  end
@@ -399,17 +418,17 @@ describe Arachni::Element::Form do
399
418
  has_sample ||= false
400
419
 
401
420
  e.mutations( 'seed' ).each do |m|
402
- m.url.should == e.url
403
- m.action.should == e.action
421
+ expect(m.url).to eq(e.url)
422
+ expect(m.action).to eq(e.action)
404
423
 
405
424
  if m.mutation_with_sample_values?
406
- m.affected_input_name.should == described_class::SAMPLE_VALUES
407
- m.inputs.should == Arachni::Options.input.fill( e.inputs )
425
+ expect(m.affected_input_name).to eq(described_class::SAMPLE_VALUES)
426
+ expect(m.inputs).to eq(Arachni::Options.input.fill( e.inputs ))
408
427
  has_sample ||= true
409
428
  end
410
429
  end
411
430
 
412
- has_sample.should be_true
431
+ expect(has_sample).to be_truthy
413
432
  end
414
433
  end
415
434
  end
@@ -427,14 +446,14 @@ describe Arachni::Element::Form do
427
446
  e.mutations( 'seed' ).each do |m|
428
447
  next if m.mutation_with_original_values? || m.mutation_with_sample_values?
429
448
 
430
- m.url.should == e.url
431
- m.action.should == e.action
449
+ expect(m.url).to eq(e.url)
450
+ expect(m.action).to eq(e.action)
432
451
 
433
- m.inputs.should_not == e.inputs
452
+ expect(m.inputs).not_to eq(e.inputs)
434
453
  checked = true
435
454
  end
436
455
 
437
- checked.should be_true
456
+ expect(checked).to be_truthy
438
457
  end
439
458
 
440
459
  it 'sets #affected_input_name to the name of the fuzzed input' do
@@ -448,16 +467,16 @@ describe Arachni::Element::Form do
448
467
  e.mutations( 'seed' ).each do |m|
449
468
  next if m.mutation_with_original_values? || m.mutation_with_sample_values?
450
469
 
451
- m.url.should == e.url
452
- m.action.should == e.action
470
+ expect(m.url).to eq(e.url)
471
+ expect(m.action).to eq(e.action)
453
472
 
454
- m.affected_input_name.should_not == e.affected_input_name
455
- m.inputs[m.affected_input_name].should include 'seed'
473
+ expect(m.affected_input_name).not_to eq(e.affected_input_name)
474
+ expect(m.inputs[m.affected_input_name]).to include 'seed'
456
475
 
457
476
  checked = true
458
477
  end
459
478
 
460
- checked.should be_true
479
+ expect(checked).to be_truthy
461
480
  end
462
481
 
463
482
  context 'when it contains more than 1 password field' do
@@ -471,9 +490,9 @@ describe Arachni::Element::Form do
471
490
 
472
491
  e = described_class.from_document( 'http://test.com', form ).first
473
492
 
474
- e.mutations( 'seed' ).select do |m|
493
+ expect(e.mutations( 'seed' ).select do |m|
475
494
  m.inputs['my_pass'] == m.inputs['my_pass_validation']
476
- end.should be_any
495
+ end).to be_any
477
496
  end
478
497
  end
479
498
 
@@ -506,10 +525,10 @@ describe Arachni::Element::Form do
506
525
  numbers = mutations.map { |f| f['numbers'] }
507
526
 
508
527
  include = %w(volvo Saab mercedes audi)
509
- (manufacturers & include).should == include
528
+ expect(manufacturers & include).to eq(include)
510
529
 
511
530
  include = %w(33 22)
512
- (numbers & include).should == include
531
+ expect(numbers & include).to eq(include)
513
532
  end
514
533
  end
515
534
 
@@ -517,7 +536,7 @@ describe Arachni::Element::Form do
517
536
  it 'does not add mutations with original nor default values' do
518
537
  e = described_class.new( options )
519
538
  mutations = e.mutations( @seed, skip_original: true )
520
- mutations.select { |m| m.mutation? }.size.should == 10
539
+ expect(mutations.select { |m| m.mutation? }.size).to eq(10)
521
540
  end
522
541
  end
523
542
  end
@@ -526,7 +545,7 @@ describe Arachni::Element::Form do
526
545
  it 'sets the name of the input holding the nonce' do
527
546
  f = described_class.new( url: url, inputs: { nonce: 'value' } )
528
547
  f.nonce_name = 'nonce'
529
- f.nonce_name.should == 'nonce'
548
+ expect(f.nonce_name).to eq('nonce')
530
549
  end
531
550
 
532
551
  context 'when there is no input called nonce_name' do
@@ -548,13 +567,13 @@ describe Arachni::Element::Form do
548
567
  it 'returns true' do
549
568
  f = described_class.new( url: url, inputs: { nonce: 'value' } )
550
569
  f.nonce_name = 'nonce'
551
- f.has_nonce?.should be_true
570
+ expect(f.has_nonce?).to be_truthy
552
571
  end
553
572
  end
554
573
  context 'when the form does not have a nonce' do
555
574
  it 'returns false' do
556
575
  f = described_class.new( url: url, inputs: { nonce: 'value' } )
557
- f.has_nonce?.should be_false
576
+ expect(f.has_nonce?).to be_falsey
558
577
  end
559
578
  end
560
579
  end
@@ -573,7 +592,7 @@ describe Arachni::Element::Form do
573
592
 
574
593
  f.submit { |res| body = res.body }
575
594
  http.run
576
- body_should.should == body
595
+ expect(body_should).to eq(body)
577
596
  end
578
597
  end
579
598
  context 'when method is get' do
@@ -589,7 +608,7 @@ describe Arachni::Element::Form do
589
608
 
590
609
  f.submit.on_complete { |res| body = res.body }
591
610
  http.run
592
- body_should.should == body
611
+ expect(body_should).to eq(body)
593
612
  end
594
613
  end
595
614
  context 'when the form has a nonce' do
@@ -612,20 +631,20 @@ describe Arachni::Element::Form do
612
631
 
613
632
  subject.submit { |res| body = res.body }
614
633
  http.run
615
- body.should_not == subject.default_inputs['nonce']
616
- body.to_i.should > 0
634
+ expect(body).not_to eq(subject.default_inputs['nonce'])
635
+ expect(body.to_i).to be > 0
617
636
  end
618
637
 
619
638
  context 'and it could not refresh it' do
620
639
  it 'submits it anyway' do
621
640
  body = nil
622
641
 
623
- subject.stub(:refresh) { nil }
642
+ allow(subject).to receive(:refresh) { nil }
624
643
  subject.submit { |res| body = res.body }
625
644
  http.run
626
645
 
627
- body.should_not == subject.default_inputs['nonce']
628
- body.to_i.should > 0
646
+ expect(body).not_to eq(subject.default_inputs['nonce'])
647
+ expect(body.to_i).to be > 0
629
648
  end
630
649
  end
631
650
  end
@@ -635,7 +654,7 @@ describe Arachni::Element::Form do
635
654
  it 'returns a simplified version of the form attributes and inputs as a Hash' do
636
655
  f = described_class.new( options )
637
656
  f.update 'user' => 'blah'
638
- f.simple.should == {
657
+ expect(f.simple).to eq({
639
658
  url: options[:url],
640
659
  action: options[:url],
641
660
  name: 'login-form',
@@ -645,20 +664,20 @@ describe Arachni::Element::Form do
645
664
  'password' => 's3cr3t'
646
665
  },
647
666
  source: html
648
- }
667
+ })
649
668
  end
650
669
  end
651
670
 
652
671
  describe '#type' do
653
672
  it 'is "form"' do
654
- described_class.new( options ).type.should == :form
673
+ expect(described_class.new( options ).type).to eq(:form)
655
674
  end
656
675
  end
657
676
 
658
677
  describe '.from_document' do
659
678
  context 'when the response does not contain any forms' do
660
679
  it 'returns an empty array' do
661
- described_class.from_document( '', '' ).should be_empty
680
+ expect(described_class.from_document( '', '' )).to be_empty
662
681
  end
663
682
  end
664
683
 
@@ -682,8 +701,8 @@ EOHTML
682
701
  Arachni::Options.scope.exclude_path_patterns = [/exclude/]
683
702
 
684
703
  forms = described_class.from_document( url, form_html )
685
- forms.size.should == 1
686
- forms.first.action.should == utilities.normalize_url( url + '/form_action' )
704
+ expect(forms.size).to eq(1)
705
+ expect(forms.first.action).to eq(utilities.normalize_url( url + '/form_action' ))
687
706
  end
688
707
 
689
708
  context 'when ignore_scope is set' do
@@ -691,7 +710,7 @@ EOHTML
691
710
  Arachni::Options.scope.exclude_path_patterns = [/exclude/]
692
711
 
693
712
  forms = described_class.from_document( url, form_html, true )
694
- forms.size.should == 2
713
+ expect(forms.size).to eq(2)
695
714
  end
696
715
  end
697
716
  end
@@ -711,16 +730,16 @@ EOHTML
711
730
  </html>'
712
731
 
713
732
  form = described_class.from_document( url, html ).first
714
- form.action.should == utilities.normalize_url( url + '/form_action' )
715
- form.name.should == 'my_form'
716
- form.url.should == url
717
- form.method.should == :get
718
- form.inputs.should == {
733
+ expect(form.action).to eq(utilities.normalize_url( url + '/form_action' ))
734
+ expect(form.name).to eq('my_form')
735
+ expect(form.url).to eq(url)
736
+ expect(form.method).to eq(:get)
737
+ expect(form.inputs).to eq({
719
738
  'my_first_input' => 'my_first_value',
720
739
  'my_second_input' => 'my_second_value'
721
- }
740
+ })
722
741
  form.inputs.keys.each do |input|
723
- form.field_type_for( input ).should == :text
742
+ expect(form.field_type_for( input )).to eq(:text)
724
743
  end
725
744
  end
726
745
  end
@@ -739,16 +758,16 @@ EOHTML
739
758
  </html>'
740
759
 
741
760
  form = described_class.from_document( url, html ).first
742
- form.action.should == utilities.normalize_url( url + '/form_action' )
743
- form.name.should == 'my_form'
744
- form.url.should == url
745
- form.method.should == :get
746
- form.inputs.should == {
761
+ expect(form.action).to eq(utilities.normalize_url( url + '/form_action' ))
762
+ expect(form.name).to eq('my_form')
763
+ expect(form.url).to eq(url)
764
+ expect(form.method).to eq(:get)
765
+ expect(form.inputs).to eq({
747
766
  'vehicle' => 'Bike',
748
767
  'stuff' => 'Car'
749
- }
768
+ })
750
769
  form.inputs.keys.each do |input|
751
- form.field_type_for( input ).should == :checkbox
770
+ expect(form.field_type_for( input )).to eq(:checkbox)
752
771
  end
753
772
  end
754
773
  end
@@ -767,16 +786,16 @@ EOHTML
767
786
  </html>'
768
787
 
769
788
  form = described_class.from_document( url, html ).first
770
- form.action.should == utilities.normalize_url( url + '/form_action' )
771
- form.name.should == 'my_form'
772
- form.url.should == url
773
- form.method.should == :get
774
- form.inputs.should == {
789
+ expect(form.action).to eq(utilities.normalize_url( url + '/form_action' ))
790
+ expect(form.name).to eq('my_form')
791
+ expect(form.url).to eq(url)
792
+ expect(form.method).to eq(:get)
793
+ expect(form.inputs).to eq({
775
794
  'my_first_input' => 'my_first_value',
776
795
  'my_second_input' => 'my_second_value'
777
- }
796
+ })
778
797
  form.inputs.keys.each do |input|
779
- form.field_type_for( input ).should == :radio
798
+ expect(form.field_type_for( input )).to eq(:radio)
780
799
  end
781
800
  end
782
801
  end
@@ -794,12 +813,12 @@ EOHTML
794
813
  </html>'
795
814
 
796
815
  form = described_class.from_document( url, html ).first
797
- form.action.should == utilities.normalize_url( url + '/form_action' )
798
- form.name.should == 'my_form'
799
- form.url.should == url
800
- form.method.should == :get
801
- form.field_type_for( 'my_button' ).should == :submit
802
- form.inputs.should == { 'my_button' => 'my_button_value' }
816
+ expect(form.action).to eq(utilities.normalize_url( url + '/form_action' ))
817
+ expect(form.name).to eq('my_form')
818
+ expect(form.url).to eq(url)
819
+ expect(form.method).to eq(:get)
820
+ expect(form.field_type_for( 'my_button' )).to eq(:submit)
821
+ expect(form.inputs).to eq({ 'my_button' => 'my_button_value' })
803
822
  end
804
823
  end
805
824
 
@@ -816,23 +835,23 @@ EOHTML
816
835
  </html>'
817
836
 
818
837
  forms = described_class.from_document( url, html )
819
- forms.size.should == 2
838
+ expect(forms.size).to eq(2)
820
839
 
821
840
  form = forms.first
822
- form.action.should == utilities.normalize_url( url + '/form_action' )
823
- form.name.should == 'my_form'
824
- form.url.should == url
825
- form.method.should == :get
826
- form.field_type_for( 'choice' ).should == :submit
827
- form.inputs['choice'].should == 'value 1'
841
+ expect(form.action).to eq(utilities.normalize_url( url + '/form_action' ))
842
+ expect(form.name).to eq('my_form')
843
+ expect(form.url).to eq(url)
844
+ expect(form.method).to eq(:get)
845
+ expect(form.field_type_for( 'choice' )).to eq(:submit)
846
+ expect(form.inputs['choice']).to eq('value 1')
828
847
 
829
848
  form = forms[1]
830
- form.action.should == utilities.normalize_url( url + '/form_action' )
831
- form.name.should == 'my_form'
832
- form.url.should == url
833
- form.method.should == :get
834
- form.field_type_for( 'choice' ).should == :submit
835
- form.inputs['choice'].should == 'value 2'
849
+ expect(form.action).to eq(utilities.normalize_url( url + '/form_action' ))
850
+ expect(form.name).to eq('my_form')
851
+ expect(form.url).to eq(url)
852
+ expect(form.method).to eq(:get)
853
+ expect(form.field_type_for( 'choice' )).to eq(:submit)
854
+ expect(form.inputs['choice']).to eq('value 2')
836
855
  end
837
856
  end
838
857
 
@@ -859,16 +878,16 @@ EOHTML
859
878
  </html>'
860
879
 
861
880
  form = described_class.from_document( url, html ).first
862
- form.action.should == utilities.normalize_url( url + '/form_action' )
863
- form.name.should == 'my_form'
864
- form.url.should == url
865
- form.method.should == :get
866
- form.inputs.should == {
881
+ expect(form.action).to eq(utilities.normalize_url( url + '/form_action' ))
882
+ expect(form.name).to eq('my_form')
883
+ expect(form.url).to eq(url)
884
+ expect(form.method).to eq(:get)
885
+ expect(form.inputs).to eq({
867
886
  'manufacturer' => 'volvo',
868
887
  'numbers' => '1'
869
- }
888
+ })
870
889
  form.inputs.keys.each do |input|
871
- form.field_type_for( input ).should == :select
890
+ expect(form.field_type_for( input )).to eq(:select)
872
891
  end
873
892
  end
874
893
  end
@@ -893,16 +912,16 @@ EOHTML
893
912
  </html>'
894
913
 
895
914
  form = described_class.from_document( url, html ).first
896
- form.action.should == utilities.normalize_url( url + '/form_action' )
897
- form.name.should == 'my_form'
898
- form.url.should == url
899
- form.method.should == :get
900
- form.inputs.should == {
915
+ expect(form.action).to eq(utilities.normalize_url( url + '/form_action' ))
916
+ expect(form.name).to eq('my_form')
917
+ expect(form.url).to eq(url)
918
+ expect(form.method).to eq(:get)
919
+ expect(form.inputs).to eq({
901
920
  'manufacturer' => 'Volvo',
902
921
  'numbers' => 'One'
903
- }
922
+ })
904
923
  form.inputs.keys.each do |input|
905
- form.field_type_for( input ).should == :select
924
+ expect(form.field_type_for( input )).to eq(:select)
906
925
  end
907
926
  end
908
927
  end
@@ -929,16 +948,16 @@ EOHTML
929
948
  </html>'
930
949
 
931
950
  form = described_class.from_document( url, html ).first
932
- form.action.should == utilities.normalize_url( url + '/form_action' )
933
- form.name.should == 'my_form'
934
- form.url.should == url
935
- form.method.should == :get
936
- form.inputs.should == {
951
+ expect(form.action).to eq(utilities.normalize_url( url + '/form_action' ))
952
+ expect(form.name).to eq('my_form')
953
+ expect(form.url).to eq(url)
954
+ expect(form.method).to eq(:get)
955
+ expect(form.inputs).to eq({
937
956
  'manufacturer' => 'Saab',
938
957
  'numbers' => 'Two'
939
- }
958
+ })
940
959
  form.inputs.keys.each do |input|
941
- form.field_type_for( input ).should == :select
960
+ expect(form.field_type_for( input )).to eq(:select)
942
961
  end
943
962
  end
944
963
  end
@@ -956,13 +975,13 @@ EOHTML
956
975
  </html>'
957
976
 
958
977
  form = described_class.from_document( url, html ).first
959
- form.action.should == utilities.normalize_url( url + '/form_action' )
960
- form.name.should == 'my_form'
961
- form.url.should == url
962
- form.method.should == :get
963
- form.inputs.should == { 'manufacturer' => '' }
978
+ expect(form.action).to eq(utilities.normalize_url( url + '/form_action' ))
979
+ expect(form.name).to eq('my_form')
980
+ expect(form.url).to eq(url)
981
+ expect(form.method).to eq(:get)
982
+ expect(form.inputs).to eq({ 'manufacturer' => '' })
964
983
  form.inputs.keys.each do |input|
965
- form.field_type_for( input ).should == :select
984
+ expect(form.field_type_for( input )).to eq(:select)
966
985
  end
967
986
  end
968
987
  end
@@ -988,29 +1007,29 @@ EOHTML
988
1007
  </html>'
989
1008
 
990
1009
  forms = described_class.from_document( url, html )
991
- forms.size.should == 2
1010
+ expect(forms.size).to eq(2)
992
1011
 
993
1012
  form = forms.shift
994
- form.action.should == utilities.normalize_url( url + base_url + 'form_action/is/here')
995
- form.name.should == 'my_form!'
996
- form.url.should == url
997
- form.method.should == :get
998
- form.inputs.should == {
1013
+ expect(form.action).to eq(utilities.normalize_url( url + base_url + 'form_action/is/here'))
1014
+ expect(form.name).to eq('my_form!')
1015
+ expect(form.url).to eq(url)
1016
+ expect(form.method).to eq(:get)
1017
+ expect(form.inputs).to eq({
999
1018
  'text_here' => '',
1000
1019
  'ha' => 'hoo'
1001
- }
1020
+ })
1002
1021
  form.inputs.keys.each do |input|
1003
- form.field_type_for( input ).should == :text
1022
+ expect(form.field_type_for( input )).to eq(:text)
1004
1023
  end
1005
1024
 
1006
1025
  form = forms.shift
1007
- form.action.should == utilities.normalize_url( url + '/form_action' )
1008
- form.name.should == 'my_second_form!'
1009
- form.url.should == url
1010
- form.method.should == :post
1011
- form.inputs.should == { 'text_here' => "my value" }
1026
+ expect(form.action).to eq(utilities.normalize_url( url + '/form_action' ))
1027
+ expect(form.name).to eq('my_second_form!')
1028
+ expect(form.url).to eq(url)
1029
+ expect(form.method).to eq(:post)
1030
+ expect(form.inputs).to eq({ 'text_here' => "my value" })
1012
1031
  form.inputs.keys.each do |input|
1013
- form.field_type_for( input ).should == :text
1032
+ expect(form.field_type_for( input )).to eq(:text)
1014
1033
  end
1015
1034
  end
1016
1035
  end
@@ -1046,34 +1065,34 @@ EOHTML
1046
1065
  </html>'
1047
1066
 
1048
1067
  forms = described_class.from_document( url, html )
1049
- forms.size.should == 3
1068
+ expect(forms.size).to eq(3)
1050
1069
 
1051
1070
  form = forms.shift
1052
- form.action.should == utilities.normalize_url( base_url + 'form_2' )
1053
- form.name.should == 'my_form_2'
1054
- form.url.should == url
1055
- form.method.should == :get
1056
- form.inputs.should == { 'text_here' => '' }
1071
+ expect(form.action).to eq(utilities.normalize_url( base_url + 'form_2' ))
1072
+ expect(form.name).to eq('my_form_2')
1073
+ expect(form.url).to eq(url)
1074
+ expect(form.method).to eq(:get)
1075
+ expect(form.inputs).to eq({ 'text_here' => '' })
1057
1076
 
1058
1077
  form = forms.shift
1059
- form.action.should == utilities.normalize_url( url + '/form' )
1060
- form.name.should == 'my_form'
1061
- form.url.should == url
1062
- form.method.should == :post
1063
- form.inputs.should == {
1078
+ expect(form.action).to eq(utilities.normalize_url( url + '/form' ))
1079
+ expect(form.name).to eq('my_form')
1080
+ expect(form.url).to eq(url)
1081
+ expect(form.method).to eq(:post)
1082
+ expect(form.inputs).to eq({
1064
1083
  'form_input_1' => 'form_val_1',
1065
1084
  'form_input_2' => 'form_val_2'
1066
- }
1085
+ })
1067
1086
 
1068
1087
  form = forms.shift
1069
- form.action.should == utilities.normalize_url( url + '/form_3' )
1070
- form.name.should == 'my_form_3'
1071
- form.url.should == url
1072
- form.method.should == :get
1073
- form.inputs.should == {
1088
+ expect(form.action).to eq(utilities.normalize_url( url + '/form_3' ))
1089
+ expect(form.name).to eq('my_form_3')
1090
+ expect(form.url).to eq(url)
1091
+ expect(form.method).to eq(:get)
1092
+ expect(form.inputs).to eq({
1074
1093
  'form_3_input_1' => 'form_3_val_1',
1075
1094
  'manufacturer' => 'volvo'
1076
- }
1095
+ })
1077
1096
  end
1078
1097
  end
1079
1098
 
@@ -1096,8 +1115,8 @@ EOHTML
1096
1115
  let(:size) { described_class::MAX_SIZE }
1097
1116
 
1098
1117
  it 'returns empty array' do
1099
- form.inputs['input_1'].should be_empty
1100
- form.inputs['input_2'].should == 'val_2'
1118
+ expect(form.inputs['input_1']).to be_empty
1119
+ expect(form.inputs['input_2']).to eq('val_2')
1101
1120
  end
1102
1121
  end
1103
1122
 
@@ -1105,8 +1124,8 @@ EOHTML
1105
1124
  let(:size) { described_class::MAX_SIZE + 1 }
1106
1125
 
1107
1126
  it 'sets empty value' do
1108
- form.inputs['input_1'].should be_empty
1109
- form.inputs['input_2'].should == 'val_2'
1127
+ expect(form.inputs['input_1']).to be_empty
1128
+ expect(form.inputs['input_2']).to eq('val_2')
1110
1129
  end
1111
1130
  end
1112
1131
 
@@ -1114,8 +1133,8 @@ EOHTML
1114
1133
  let(:size) { described_class::MAX_SIZE - 1 }
1115
1134
 
1116
1135
  it 'leaves the values alone' do
1117
- form.inputs['input_1'].should == value
1118
- form.inputs['input_2'].should == 'val_2'
1136
+ expect(form.inputs['input_1']).to eq(value)
1137
+ expect(form.inputs['input_2']).to eq('val_2')
1119
1138
  end
1120
1139
  end
1121
1140
  end
@@ -1124,25 +1143,29 @@ EOHTML
1124
1143
 
1125
1144
  describe '.encode' do
1126
1145
  it 'form-encodes the passed string' do
1127
- described_class.encode( '% value\ +=&;' ).should == '%25%20value%5C%20%2B%3D%26%3B'
1146
+ expect(described_class.encode( '% value\ +=&;' )).to eq('%25%20value%5C%20%2B%3D%26%3B')
1128
1147
  end
1129
1148
  end
1130
1149
  describe '#encode' do
1131
1150
  it 'form-encodes the passed string' do
1132
1151
  v = '% value\ +=&;'
1133
- subject.encode( v ).should == described_class.encode( v )
1152
+ expect(subject.encode( v )).to eq(described_class.encode( v ))
1134
1153
  end
1135
1154
  end
1136
1155
 
1137
1156
  describe '.decode' do
1138
1157
  it 'form-decodes the passed string' do
1139
- described_class.decode( '%25%20value%5C%20%2B%3D%26%3B' ).should == '% value\ +=&;'
1158
+ expect(described_class.decode( '%25%20value%5C%20%2B%3D%26%3B' )).to eq('% value\ +=&;')
1159
+ end
1160
+
1161
+ it 'handles broken encodings' do
1162
+ expect(described_class.decode( '%g' )).to eq('%g')
1140
1163
  end
1141
1164
  end
1142
1165
  describe '#decode' do
1143
1166
  it 'form-decodes the passed string' do
1144
1167
  v = '%25%20value%5C%20%2B%3D%26%3B'
1145
- subject.decode( v ).should == described_class.decode( v )
1168
+ expect(subject.decode( v )).to eq(described_class.decode( v ))
1146
1169
  end
1147
1170
  end
1148
1171