arachni 1.3.2 → 1.4

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 (727) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +108 -0
  3. data/Gemfile +2 -6
  4. data/LICENSE.md +1 -1
  5. data/README.md +34 -16
  6. data/Rakefile +1 -1
  7. data/arachni.gemspec +28 -20
  8. data/bin/arachni +1 -1
  9. data/bin/arachni_console +1 -1
  10. data/bin/arachni_multi +1 -1
  11. data/bin/arachni_reporter +1 -1
  12. data/bin/arachni_rest_server +13 -0
  13. data/bin/arachni_restore +1 -1
  14. data/bin/arachni_rpc +1 -1
  15. data/bin/arachni_rpcd +1 -1
  16. data/bin/arachni_rpcd_monitor +1 -1
  17. data/bin/arachni_script +1 -1
  18. data/components/checks/active/code_injection.rb +8 -10
  19. data/components/checks/active/code_injection_php_input_wrapper.rb +5 -6
  20. data/components/checks/active/code_injection_timing.rb +1 -1
  21. data/components/checks/active/csrf.rb +1 -1
  22. data/components/checks/active/file_inclusion.rb +20 -26
  23. data/components/checks/active/ldap_injection.rb +4 -5
  24. data/components/checks/active/no_sql_injection.rb +11 -20
  25. data/components/checks/active/no_sql_injection/substrings/mongodb +1 -0
  26. data/components/checks/active/no_sql_injection_differential.rb +3 -4
  27. data/components/checks/active/os_cmd_injection.rb +5 -9
  28. data/components/checks/active/os_cmd_injection_timing.rb +1 -1
  29. data/components/checks/active/path_traversal.rb +4 -17
  30. data/components/checks/active/response_splitting.rb +8 -2
  31. data/components/checks/active/rfi.rb +4 -5
  32. data/components/checks/active/session_fixation.rb +9 -3
  33. data/components/checks/active/source_code_disclosure.rb +5 -20
  34. data/components/checks/active/sql_injection.rb +30 -18
  35. data/components/checks/active/sql_injection/{regexp_ignore.txt → ignore_substrings} +0 -0
  36. data/components/checks/active/sql_injection/regexps/db2.yaml +2 -0
  37. data/components/checks/active/sql_injection/regexps/frontbase.yaml +1 -0
  38. data/components/checks/active/sql_injection/regexps/informix.yaml +1 -0
  39. data/components/checks/active/sql_injection/regexps/ingres.yaml +2 -0
  40. data/components/checks/active/sql_injection/regexps/maxdb.yaml +2 -0
  41. data/components/checks/active/sql_injection/regexps/mssql.yaml +8 -0
  42. data/components/checks/active/sql_injection/regexps/mysql.yaml +4 -0
  43. data/components/checks/active/sql_injection/regexps/oracle.yaml +4 -0
  44. data/components/checks/active/sql_injection/regexps/pgsql.yaml +3 -0
  45. data/components/checks/active/sql_injection/regexps/sqlite.yaml +2 -0
  46. data/components/checks/active/sql_injection/regexps/sybase.yaml +2 -0
  47. data/components/checks/active/sql_injection/substrings/access +3 -0
  48. data/components/checks/active/sql_injection/substrings/db2 +2 -0
  49. data/components/checks/active/sql_injection/{patterns → substrings}/emc +1 -1
  50. data/components/checks/active/sql_injection/{patterns → substrings}/firebird +0 -1
  51. data/components/checks/active/sql_injection/substrings/hsqldb +1 -0
  52. data/components/checks/active/sql_injection/{patterns → substrings}/informix +1 -2
  53. data/components/checks/active/sql_injection/substrings/ingres +1 -0
  54. data/components/checks/active/sql_injection/{patterns → substrings}/interbase +0 -0
  55. data/components/checks/active/sql_injection/substrings/mssql +17 -0
  56. data/components/checks/active/sql_injection/{patterns → substrings}/mysql +3 -6
  57. data/components/checks/active/sql_injection/substrings/oracle +2 -0
  58. data/components/checks/active/sql_injection/{patterns → substrings}/pgsql +3 -6
  59. data/components/checks/active/sql_injection/substrings/sqlite +3 -0
  60. data/components/checks/active/sql_injection/substrings/sybase +1 -0
  61. data/components/checks/active/sql_injection_differential.rb +5 -7
  62. data/components/checks/active/sql_injection_differential/payloads.txt +1 -1
  63. data/components/checks/active/sql_injection_timing.rb +1 -1
  64. data/components/checks/active/trainer.rb +5 -4
  65. data/components/checks/active/unvalidated_redirect.rb +1 -1
  66. data/components/checks/active/unvalidated_redirect_dom.rb +1 -1
  67. data/components/checks/active/xpath_injection.rb +3 -4
  68. data/components/checks/active/xss.rb +33 -12
  69. data/components/checks/active/xss_dom.rb +7 -4
  70. data/components/checks/active/xss_dom_script_context.rb +1 -1
  71. data/components/checks/active/xss_event.rb +43 -20
  72. data/components/checks/active/xss_path.rb +5 -4
  73. data/components/checks/active/xss_script_context.rb +41 -11
  74. data/components/checks/active/xss_tag.rb +14 -15
  75. data/components/checks/active/xxe.rb +5 -16
  76. data/components/checks/passive/allowed_methods.rb +1 -1
  77. data/components/checks/passive/backdoors.rb +4 -2
  78. data/components/checks/passive/backup_directories.rb +4 -2
  79. data/components/checks/passive/backup_files.rb +4 -2
  80. data/components/checks/passive/common_admin_interfaces.rb +4 -3
  81. data/components/checks/passive/common_directories.rb +3 -1
  82. data/components/checks/passive/common_files.rb +3 -1
  83. data/components/checks/passive/directory_listing.rb +4 -4
  84. data/components/checks/passive/grep/captcha.rb +1 -1
  85. data/components/checks/passive/grep/cookie_set_for_parent_domain.rb +1 -1
  86. data/components/checks/passive/grep/credit_card.rb +5 -7
  87. data/components/checks/passive/grep/cvs_svn_users.rb +1 -1
  88. data/components/checks/passive/grep/emails.rb +135 -8
  89. data/components/checks/passive/grep/form_upload.rb +1 -1
  90. data/components/checks/passive/grep/hsts.rb +4 -3
  91. data/components/checks/passive/grep/html_objects.rb +1 -1
  92. data/components/checks/passive/grep/http_only_cookies.rb +5 -3
  93. data/components/checks/passive/grep/insecure_cookies.rb +5 -3
  94. data/components/checks/passive/grep/insecure_cors_policy.rb +1 -1
  95. data/components/checks/passive/grep/mixed_resource.rb +1 -1
  96. data/components/checks/passive/grep/password_autocomplete.rb +1 -1
  97. data/components/checks/passive/grep/private_ip.rb +1 -1
  98. data/components/checks/passive/grep/ssn.rb +6 -3
  99. data/components/checks/passive/grep/unencrypted_password_forms.rb +1 -1
  100. data/components/checks/passive/grep/x_frame_options.rb +4 -3
  101. data/components/checks/passive/htaccess_limit.rb +1 -1
  102. data/components/checks/passive/http_put.rb +1 -1
  103. data/components/checks/passive/insecure_client_access_policy.rb +2 -2
  104. data/components/checks/passive/insecure_cross_domain_policy_access.rb +2 -2
  105. data/components/checks/passive/insecure_cross_domain_policy_headers.rb +2 -2
  106. data/components/checks/passive/interesting_responses.rb +1 -1
  107. data/components/checks/passive/localstart_asp.rb +1 -1
  108. data/components/checks/passive/origin_spoof_access_restriction_bypass.rb +1 -1
  109. data/components/checks/passive/webdav.rb +1 -1
  110. data/components/checks/passive/xst.rb +1 -1
  111. data/components/fingerprinters/frameworks/aspx_mvc.rb +1 -1
  112. data/components/fingerprinters/frameworks/cakephp.rb +1 -1
  113. data/components/fingerprinters/frameworks/cherrypy.rb +1 -1
  114. data/components/fingerprinters/frameworks/django.rb +1 -1
  115. data/components/fingerprinters/frameworks/jsf.rb +1 -1
  116. data/components/fingerprinters/frameworks/nette.rb +1 -1
  117. data/components/fingerprinters/frameworks/rack.rb +1 -1
  118. data/components/fingerprinters/frameworks/rails.rb +1 -1
  119. data/components/fingerprinters/frameworks/symfony.rb +1 -1
  120. data/components/fingerprinters/languages/asp.rb +1 -1
  121. data/components/fingerprinters/languages/aspx.rb +1 -1
  122. data/components/fingerprinters/languages/java.rb +1 -1
  123. data/components/fingerprinters/languages/php.rb +1 -1
  124. data/components/fingerprinters/languages/python.rb +1 -1
  125. data/components/fingerprinters/languages/ruby.rb +1 -1
  126. data/components/fingerprinters/os/bsd.rb +1 -1
  127. data/components/fingerprinters/os/linux.rb +1 -1
  128. data/components/fingerprinters/os/solaris.rb +1 -1
  129. data/components/fingerprinters/os/unix.rb +1 -1
  130. data/components/fingerprinters/os/windows.rb +1 -1
  131. data/components/fingerprinters/servers/apache.rb +1 -1
  132. data/components/fingerprinters/servers/gunicorn.rb +1 -1
  133. data/components/fingerprinters/servers/iis.rb +1 -1
  134. data/components/fingerprinters/servers/jetty.rb +1 -1
  135. data/components/fingerprinters/servers/nginx.rb +1 -1
  136. data/components/fingerprinters/servers/tomcat.rb +1 -1
  137. data/components/path_extractors/anchors.rb +1 -1
  138. data/components/path_extractors/areas.rb +1 -1
  139. data/components/path_extractors/comments.rb +1 -1
  140. data/components/path_extractors/data_url.rb +1 -1
  141. data/components/path_extractors/forms.rb +1 -1
  142. data/components/path_extractors/frames.rb +1 -1
  143. data/components/path_extractors/generic.rb +1 -1
  144. data/components/path_extractors/links.rb +1 -1
  145. data/components/path_extractors/meta_refresh.rb +3 -3
  146. data/components/path_extractors/scripts.rb +1 -1
  147. data/components/plugins/autologin.rb +16 -24
  148. data/components/plugins/beep_notify.rb +1 -1
  149. data/components/plugins/content_types.rb +1 -1
  150. data/components/plugins/cookie_collector.rb +1 -1
  151. data/components/plugins/defaults/autothrottle.rb +1 -1
  152. data/components/plugins/defaults/healthmap.rb +1 -1
  153. data/components/plugins/defaults/meta/remedies/discovery.rb +10 -9
  154. data/components/plugins/defaults/meta/remedies/timing_attacks.rb +1 -1
  155. data/components/plugins/defaults/meta/uniformity.rb +1 -1
  156. data/components/plugins/email_notify.rb +3 -5
  157. data/components/plugins/exec.rb +1 -1
  158. data/components/plugins/form_dicattack.rb +1 -1
  159. data/components/plugins/headers_collector.rb +1 -1
  160. data/components/plugins/http_dicattack.rb +1 -1
  161. data/components/plugins/login_script.rb +47 -22
  162. data/components/plugins/metrics.rb +1 -1
  163. data/components/plugins/proxy.rb +69 -44
  164. data/components/plugins/proxy/panel/help.html.erb +1 -18
  165. data/components/plugins/proxy/panel/inspect.html.erb +4 -3
  166. data/components/plugins/proxy/panel/page_accordion.html.erb +78 -43
  167. data/components/plugins/proxy/panel/panel.html.erb +2 -7
  168. data/components/plugins/proxy/template_scope.rb +1 -1
  169. data/components/plugins/restrict_to_dom_state.rb +3 -15
  170. data/components/plugins/script.rb +1 -1
  171. data/components/plugins/uncommon_headers.rb +1 -1
  172. data/components/plugins/vector_collector.rb +1 -1
  173. data/components/plugins/vector_feed.rb +3 -11
  174. data/components/plugins/waf_detector.rb +1 -1
  175. data/components/reporters/ap.rb +1 -1
  176. data/components/reporters/html.rb +2 -2
  177. data/components/reporters/json.rb +1 -1
  178. data/components/reporters/marshal.rb +1 -1
  179. data/components/reporters/plugin_formatters/html/autologin.rb +1 -1
  180. data/components/reporters/plugin_formatters/html/content_types.rb +1 -1
  181. data/components/reporters/plugin_formatters/html/cookie_collector.rb +1 -1
  182. data/components/reporters/plugin_formatters/html/exec.rb +1 -1
  183. data/components/reporters/plugin_formatters/html/form_dicattack.rb +1 -1
  184. data/components/reporters/plugin_formatters/html/healthmap.rb +1 -1
  185. data/components/reporters/plugin_formatters/html/http_dicattack.rb +1 -1
  186. data/components/reporters/plugin_formatters/html/login_script.rb +1 -1
  187. data/components/reporters/plugin_formatters/html/metrics.rb +1 -1
  188. data/components/reporters/plugin_formatters/html/uncommon_headers.rb +1 -1
  189. data/components/reporters/plugin_formatters/html/uniformity.rb +1 -1
  190. data/components/reporters/plugin_formatters/html/vector_collector.rb +1 -1
  191. data/components/reporters/plugin_formatters/html/waf_detector.rb +1 -1
  192. data/components/reporters/plugin_formatters/stdout/autologin.rb +1 -1
  193. data/components/reporters/plugin_formatters/stdout/content_types.rb +1 -1
  194. data/components/reporters/plugin_formatters/stdout/cookie_collector.rb +1 -1
  195. data/components/reporters/plugin_formatters/stdout/exec.rb +1 -1
  196. data/components/reporters/plugin_formatters/stdout/form_dicattack.rb +1 -1
  197. data/components/reporters/plugin_formatters/stdout/healthmap.rb +1 -1
  198. data/components/reporters/plugin_formatters/stdout/http_dicattack.rb +1 -1
  199. data/components/reporters/plugin_formatters/stdout/login_script.rb +1 -1
  200. data/components/reporters/plugin_formatters/stdout/metrics.rb +1 -1
  201. data/components/reporters/plugin_formatters/stdout/uncommon_headers.rb +1 -1
  202. data/components/reporters/plugin_formatters/stdout/uniformity.rb +1 -1
  203. data/components/reporters/plugin_formatters/stdout/vector_collector.rb +1 -1
  204. data/components/reporters/plugin_formatters/stdout/waf_detector.rb +1 -1
  205. data/components/reporters/plugin_formatters/xml/autologin.rb +1 -1
  206. data/components/reporters/plugin_formatters/xml/content_types.rb +1 -1
  207. data/components/reporters/plugin_formatters/xml/cookie_collector.rb +1 -1
  208. data/components/reporters/plugin_formatters/xml/exec.rb +1 -1
  209. data/components/reporters/plugin_formatters/xml/form_dicattack.rb +1 -1
  210. data/components/reporters/plugin_formatters/xml/healthmap.rb +1 -1
  211. data/components/reporters/plugin_formatters/xml/http_dicattack.rb +1 -1
  212. data/components/reporters/plugin_formatters/xml/login_script.rb +1 -1
  213. data/components/reporters/plugin_formatters/xml/metrics.rb +1 -1
  214. data/components/reporters/plugin_formatters/xml/uncommon_headers.rb +1 -1
  215. data/components/reporters/plugin_formatters/xml/uniformity.rb +1 -1
  216. data/components/reporters/plugin_formatters/xml/vector_collector.rb +1 -1
  217. data/components/reporters/plugin_formatters/xml/waf_detector.rb +1 -1
  218. data/components/reporters/stdout.rb +1 -1
  219. data/components/reporters/txt.rb +1 -1
  220. data/components/reporters/xml.rb +29 -4
  221. data/components/reporters/yaml.rb +1 -1
  222. data/lib/arachni.rb +48 -3
  223. data/lib/arachni/banner.rb +1 -1
  224. data/lib/arachni/browser.rb +601 -358
  225. data/lib/arachni/browser/element_locator.rb +25 -6
  226. data/lib/arachni/browser/javascript.rb +103 -35
  227. data/lib/arachni/browser/javascript/dom_monitor.rb +1 -1
  228. data/lib/arachni/browser/javascript/proxy.rb +28 -16
  229. data/lib/arachni/browser/javascript/proxy/stub.rb +1 -1
  230. data/lib/arachni/browser/javascript/scripts/dom_monitor.js +138 -67
  231. data/lib/arachni/browser/javascript/scripts/polyfills.js +28 -0
  232. data/lib/arachni/browser/javascript/scripts/taint_tracer.js +27 -6
  233. data/lib/arachni/browser/javascript/taint_tracer.rb +1 -1
  234. data/lib/arachni/browser/javascript/taint_tracer/frame.rb +1 -1
  235. data/lib/arachni/browser/javascript/taint_tracer/frame/called_function.rb +1 -1
  236. data/lib/arachni/browser/javascript/taint_tracer/sink/base.rb +1 -1
  237. data/lib/arachni/browser/javascript/taint_tracer/sink/data_flow.rb +1 -1
  238. data/lib/arachni/browser/javascript/taint_tracer/sink/execution_flow.rb +1 -1
  239. data/lib/arachni/browser_cluster.rb +10 -14
  240. data/lib/arachni/browser_cluster/job.rb +1 -1
  241. data/lib/arachni/browser_cluster/job/result.rb +1 -1
  242. data/lib/arachni/browser_cluster/jobs/browser_provider.rb +1 -1
  243. data/lib/arachni/browser_cluster/jobs/{resource_exploration.rb → dom_exploration.rb} +5 -5
  244. data/lib/arachni/browser_cluster/jobs/{resource_exploration → dom_exploration}/event_trigger.rb +7 -4
  245. data/lib/arachni/browser_cluster/jobs/{resource_exploration → dom_exploration}/event_trigger/result.rb +3 -3
  246. data/lib/arachni/browser_cluster/jobs/{resource_exploration → dom_exploration}/result.rb +2 -2
  247. data/lib/arachni/browser_cluster/jobs/taint_trace.rb +3 -3
  248. data/lib/arachni/browser_cluster/jobs/taint_trace/event_trigger.rb +2 -2
  249. data/lib/arachni/browser_cluster/jobs/taint_trace/event_trigger/result.rb +2 -2
  250. data/lib/arachni/browser_cluster/jobs/taint_trace/result.rb +1 -1
  251. data/lib/arachni/browser_cluster/worker.rb +12 -40
  252. data/lib/arachni/check.rb +1 -1
  253. data/lib/arachni/check/auditor.rb +15 -1
  254. data/lib/arachni/check/base.rb +1 -1
  255. data/lib/arachni/check/manager.rb +1 -1
  256. data/lib/arachni/component.rb +1 -1
  257. data/lib/arachni/component/base.rb +5 -5
  258. data/lib/arachni/component/manager.rb +39 -13
  259. data/lib/arachni/component/options.rb +1 -1
  260. data/lib/arachni/component/options/address.rb +1 -1
  261. data/lib/arachni/component/options/base.rb +1 -1
  262. data/lib/arachni/component/options/bool.rb +1 -1
  263. data/lib/arachni/component/options/float.rb +1 -1
  264. data/lib/arachni/component/options/int.rb +1 -1
  265. data/lib/arachni/component/options/multiple_choice.rb +1 -1
  266. data/lib/arachni/component/options/object.rb +1 -1
  267. data/lib/arachni/component/options/path.rb +1 -1
  268. data/lib/arachni/component/options/port.rb +1 -1
  269. data/lib/arachni/component/options/string.rb +1 -1
  270. data/lib/arachni/component/options/url.rb +1 -1
  271. data/lib/arachni/component/output.rb +1 -1
  272. data/lib/arachni/component/utilities.rb +1 -1
  273. data/lib/arachni/data.rb +1 -1
  274. data/lib/arachni/data/framework.rb +1 -1
  275. data/lib/arachni/data/framework/rpc.rb +1 -1
  276. data/lib/arachni/data/issues.rb +1 -1
  277. data/lib/arachni/data/plugins.rb +1 -1
  278. data/lib/arachni/data/session.rb +1 -1
  279. data/lib/arachni/element/base.rb +19 -5
  280. data/lib/arachni/element/body.rb +1 -1
  281. data/lib/arachni/element/capabilities/analyzable.rb +1 -1
  282. data/lib/arachni/element/capabilities/analyzable/differential.rb +15 -5
  283. data/lib/arachni/element/capabilities/analyzable/signature.rb +147 -89
  284. data/lib/arachni/element/capabilities/analyzable/timeout.rb +43 -16
  285. data/lib/arachni/element/capabilities/auditable.rb +20 -15
  286. data/lib/arachni/element/capabilities/dom_only.rb +5 -4
  287. data/lib/arachni/element/capabilities/inputtable.rb +62 -12
  288. data/lib/arachni/element/capabilities/mutable.rb +74 -13
  289. data/lib/arachni/element/capabilities/refreshable.rb +1 -1
  290. data/lib/arachni/element/capabilities/submittable.rb +5 -2
  291. data/lib/arachni/element/capabilities/with_auditor.rb +1 -1
  292. data/lib/arachni/element/capabilities/with_auditor/output.rb +5 -5
  293. data/lib/arachni/element/capabilities/with_dom.rb +1 -1
  294. data/lib/arachni/element/capabilities/with_node.rb +2 -2
  295. data/lib/arachni/element/capabilities/with_scope.rb +1 -1
  296. data/lib/arachni/element/capabilities/with_scope/scope.rb +1 -1
  297. data/lib/arachni/element/capabilities/with_source.rb +4 -4
  298. data/lib/arachni/element/cookie.rb +57 -34
  299. data/lib/arachni/element/cookie/capabilities/inputtable.rb +1 -1
  300. data/lib/arachni/element/cookie/capabilities/mutable.rb +10 -1
  301. data/lib/arachni/element/cookie/capabilities/with_dom.rb +1 -1
  302. data/lib/arachni/element/cookie/dom.rb +1 -1
  303. data/lib/arachni/element/dom.rb +1 -15
  304. data/lib/arachni/element/dom/capabilities/auditable.rb +1 -1
  305. data/lib/arachni/element/dom/capabilities/inputtable.rb +1 -1
  306. data/lib/arachni/element/dom/capabilities/locatable.rb +29 -0
  307. data/lib/arachni/element/dom/capabilities/mutable.rb +11 -1
  308. data/lib/arachni/element/dom/capabilities/submittable.rb +2 -2
  309. data/lib/arachni/element/form.rb +33 -14
  310. data/lib/arachni/element/form/capabilities/auditable.rb +1 -1
  311. data/lib/arachni/element/form/capabilities/mutable.rb +18 -17
  312. data/lib/arachni/element/form/capabilities/submittable.rb +1 -1
  313. data/lib/arachni/element/form/capabilities/with_dom.rb +2 -1
  314. data/lib/arachni/element/form/dom.rb +3 -2
  315. data/lib/arachni/element/generic_dom.rb +1 -1
  316. data/lib/arachni/element/header.rb +16 -4
  317. data/lib/arachni/element/header/capabilities/inputtable.rb +1 -1
  318. data/lib/arachni/element/header/capabilities/mutable.rb +11 -1
  319. data/lib/arachni/element/json.rb +2 -2
  320. data/lib/arachni/element/json/capabilities/inputtable.rb +1 -1
  321. data/lib/arachni/element/json/capabilities/mutable.rb +8 -2
  322. data/lib/arachni/element/link.rb +14 -7
  323. data/lib/arachni/element/link/capabilities/auditable.rb +1 -1
  324. data/lib/arachni/element/link/capabilities/submittable.rb +1 -1
  325. data/lib/arachni/element/link/capabilities/with_dom.rb +8 -1
  326. data/lib/arachni/element/link/dom.rb +2 -1
  327. data/lib/arachni/element/link/dom/capabilities/submittable.rb +1 -1
  328. data/lib/arachni/element/link_template.rb +8 -3
  329. data/lib/arachni/element/link_template/capabilities/auditable.rb +1 -1
  330. data/lib/arachni/element/link_template/capabilities/inputtable.rb +1 -1
  331. data/lib/arachni/element/link_template/capabilities/with_dom.rb +1 -1
  332. data/lib/arachni/element/link_template/dom.rb +2 -1
  333. data/lib/arachni/element/link_template/dom/capabilities/submittable.rb +1 -1
  334. data/lib/arachni/element/path.rb +1 -1
  335. data/lib/arachni/element/server.rb +3 -3
  336. data/lib/arachni/element/ui_form.rb +24 -21
  337. data/lib/arachni/element/ui_form/dom.rb +12 -3
  338. data/lib/arachni/element/ui_input.rb +17 -11
  339. data/lib/arachni/element/{input → ui_input}/dom.rb +11 -2
  340. data/lib/arachni/element/xml.rb +3 -3
  341. data/lib/arachni/element/xml/capabilities/inputtable.rb +7 -1
  342. data/lib/arachni/element/xml/capabilities/mutable.rb +7 -13
  343. data/lib/arachni/element_filter.rb +1 -1
  344. data/lib/arachni/error.rb +1 -1
  345. data/lib/arachni/ethon/easy.rb +1 -1
  346. data/lib/arachni/framework.rb +2 -5
  347. data/lib/arachni/framework/parts/audit.rb +8 -2
  348. data/lib/arachni/framework/parts/browser.rb +8 -9
  349. data/lib/arachni/framework/parts/check.rb +2 -6
  350. data/lib/arachni/framework/parts/data.rb +23 -8
  351. data/lib/arachni/framework/parts/platform.rb +1 -1
  352. data/lib/arachni/framework/parts/plugin.rb +2 -8
  353. data/lib/arachni/framework/parts/report.rb +3 -9
  354. data/lib/arachni/framework/parts/scope.rb +1 -1
  355. data/lib/arachni/framework/parts/state.rb +8 -8
  356. data/lib/arachni/http.rb +1 -1
  357. data/lib/arachni/http/client.rb +72 -68
  358. data/lib/arachni/http/client/dynamic_404_handler.rb +85 -60
  359. data/lib/arachni/http/cookie_jar.rb +48 -27
  360. data/lib/arachni/http/headers.rb +4 -3
  361. data/lib/arachni/http/message.rb +17 -3
  362. data/lib/arachni/http/message/scope.rb +1 -1
  363. data/lib/arachni/http/proxy_server.rb +46 -344
  364. data/lib/arachni/http/proxy_server/connection.rb +316 -0
  365. data/lib/arachni/http/proxy_server/ssl_interceptor.rb +102 -0
  366. data/lib/arachni/http/proxy_server/tunnel.rb +54 -0
  367. data/lib/arachni/http/request.rb +126 -29
  368. data/lib/arachni/http/request/scope.rb +1 -1
  369. data/lib/arachni/http/response.rb +42 -12
  370. data/lib/arachni/http/response/scope.rb +1 -1
  371. data/lib/arachni/issue.rb +2 -2
  372. data/lib/arachni/issue/severity.rb +1 -1
  373. data/lib/arachni/issue/severity/base.rb +1 -1
  374. data/lib/arachni/option_group.rb +1 -1
  375. data/lib/arachni/option_groups.rb +1 -1
  376. data/lib/arachni/option_groups/audit.rb +20 -4
  377. data/lib/arachni/option_groups/browser_cluster.rb +8 -4
  378. data/lib/arachni/option_groups/datastore.rb +1 -1
  379. data/lib/arachni/option_groups/dispatcher.rb +1 -1
  380. data/lib/arachni/option_groups/http.rb +2 -2
  381. data/lib/arachni/option_groups/input.rb +6 -3
  382. data/lib/arachni/option_groups/output.rb +1 -1
  383. data/lib/arachni/option_groups/paths.rb +10 -3
  384. data/lib/arachni/option_groups/rpc.rb +1 -1
  385. data/lib/arachni/option_groups/scope.rb +35 -6
  386. data/lib/arachni/option_groups/session.rb +1 -1
  387. data/lib/arachni/option_groups/snapshot.rb +1 -1
  388. data/lib/arachni/options.rb +1 -1
  389. data/lib/arachni/page.rb +26 -12
  390. data/lib/arachni/page/dom.rb +29 -22
  391. data/lib/arachni/page/dom/transition.rb +2 -2
  392. data/lib/arachni/page/scope.rb +1 -1
  393. data/lib/arachni/parser.rb +42 -5
  394. data/lib/arachni/platform.rb +1 -1
  395. data/lib/arachni/platform/fingerprinter.rb +1 -1
  396. data/lib/arachni/platform/list.rb +1 -1
  397. data/lib/arachni/platform/manager.rb +2 -2
  398. data/lib/arachni/plugin.rb +1 -1
  399. data/lib/arachni/plugin/base.rb +1 -1
  400. data/lib/arachni/plugin/formatter.rb +1 -1
  401. data/lib/arachni/plugin/manager.rb +7 -13
  402. data/lib/arachni/processes.rb +1 -1
  403. data/lib/arachni/processes/dispatchers.rb +2 -2
  404. data/lib/arachni/processes/executables/base.rb +45 -4
  405. data/lib/arachni/processes/executables/browser.rb +91 -0
  406. data/lib/arachni/processes/executables/rest_service.rb +14 -0
  407. data/lib/arachni/processes/helpers.rb +1 -1
  408. data/lib/arachni/processes/helpers/dispatchers.rb +1 -1
  409. data/lib/arachni/processes/helpers/instances.rb +1 -1
  410. data/lib/arachni/processes/helpers/processes.rb +1 -1
  411. data/lib/arachni/processes/instances.rb +5 -5
  412. data/lib/arachni/processes/manager.rb +68 -9
  413. data/lib/arachni/report.rb +1 -1
  414. data/lib/arachni/reporter.rb +1 -1
  415. data/lib/arachni/reporter/base.rb +1 -1
  416. data/lib/arachni/reporter/formatter_manager.rb +4 -2
  417. data/lib/arachni/reporter/manager.rb +3 -2
  418. data/lib/arachni/reporter/options.rb +1 -1
  419. data/lib/arachni/rest/server.rb +231 -0
  420. data/lib/arachni/rest/server/instance_helpers.rb +37 -0
  421. data/lib/arachni/rpc/client/base.rb +1 -1
  422. data/lib/arachni/rpc/client/dispatcher.rb +1 -1
  423. data/lib/arachni/rpc/client/instance.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/serializer.rb +1 -1
  427. data/lib/arachni/rpc/server/active_options.rb +20 -3
  428. data/lib/arachni/rpc/server/base.rb +1 -1
  429. data/lib/arachni/rpc/server/check/manager.rb +1 -1
  430. data/lib/arachni/rpc/server/dispatcher.rb +4 -4
  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/framework.rb +3 -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/instance.rb +1 -3
  439. data/lib/arachni/rpc/server/output.rb +1 -1
  440. data/lib/arachni/rpc/server/plugin/manager.rb +1 -1
  441. data/lib/arachni/ruby.rb +1 -2
  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 +15 -1
  445. data/lib/arachni/ruby/set.rb +1 -1
  446. data/lib/arachni/ruby/string.rb +23 -4
  447. data/lib/arachni/ruby/webrick.rb +1 -1
  448. data/lib/arachni/ruby/webrick/cookie.rb +1 -1
  449. data/lib/arachni/ruby/webrick/httprequest.rb +1 -1
  450. data/lib/arachni/scope.rb +1 -1
  451. data/lib/arachni/{watir → selenium/webdriver}/element.rb +12 -13
  452. data/lib/arachni/session.rb +19 -4
  453. data/lib/arachni/snapshot.rb +9 -5
  454. data/lib/arachni/state.rb +1 -1
  455. data/lib/arachni/state/audit.rb +1 -1
  456. data/lib/arachni/state/element_filter.rb +1 -1
  457. data/lib/arachni/state/framework.rb +1 -1
  458. data/lib/arachni/state/framework/rpc.rb +1 -1
  459. data/lib/arachni/state/http.rb +1 -1
  460. data/lib/arachni/state/options.rb +1 -1
  461. data/lib/arachni/state/plugins.rb +1 -1
  462. data/lib/arachni/support.rb +2 -1
  463. data/lib/arachni/support/buffer.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/cache.rb +1 -1
  467. data/lib/arachni/support/cache/base.rb +20 -8
  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 +8 -9
  471. data/lib/arachni/support/cache/preference.rb +7 -20
  472. data/lib/arachni/support/cache/random_replacement.rb +1 -1
  473. data/lib/arachni/support/crypto.rb +1 -1
  474. data/lib/arachni/support/crypto/rsa_aes_cbc.rb +1 -1
  475. data/lib/arachni/support/database.rb +1 -1
  476. data/lib/arachni/support/database/base.rb +2 -2
  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/glob.rb +35 -0
  480. data/lib/arachni/support/lookup.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/mixins.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/profiler.rb +12 -10
  488. data/lib/arachni/support/signature.rb +12 -5
  489. data/lib/arachni/trainer.rb +18 -4
  490. data/lib/arachni/ui/foo/output.rb +17 -1
  491. data/lib/arachni/uri.rb +285 -203
  492. data/lib/arachni/uri/scope.rb +13 -2
  493. data/lib/arachni/utilities.rb +22 -5
  494. data/lib/arachni/version.rb +1 -1
  495. data/lib/version +1 -1
  496. data/spec/arachni/browser/element_locator_spec.rb +42 -14
  497. data/spec/arachni/browser/javascript/dom_monitor_spec.rb +34 -304
  498. data/spec/arachni/browser/javascript/polyfills_spec.rb +35 -0
  499. data/spec/arachni/browser/javascript/taint_tracer_spec.rb +24 -4
  500. data/spec/arachni/browser/javascript_spec.rb +92 -65
  501. data/spec/arachni/browser_cluster/job_spec.rb +3 -3
  502. data/spec/arachni/browser_cluster/jobs/{resource_exploration → dom_exploration}/event_trigger/result_spec.rb +1 -1
  503. data/spec/arachni/browser_cluster/jobs/{resource_exploration → dom_exploration}/event_trigger_spec.rb +4 -4
  504. data/spec/arachni/browser_cluster/jobs/{resource_exploration → dom_exploration}/result_spec.rb +1 -1
  505. data/spec/arachni/browser_cluster/jobs/{resource_exploration_spec.rb → dom_exploration_spec.rb} +4 -4
  506. data/spec/arachni/browser_cluster/jobs/taint_tracer_spec.rb +9 -9
  507. data/spec/arachni/browser_cluster/worker_spec.rb +46 -67
  508. data/spec/arachni/browser_cluster_spec.rb +19 -17
  509. data/spec/arachni/browser_spec.rb +506 -183
  510. data/spec/arachni/check/auditor_spec.rb +70 -25
  511. data/spec/arachni/component/manager_spec.rb +19 -20
  512. data/spec/arachni/data/framework/rpc_spec.rb +1 -1
  513. data/spec/arachni/data/framework_spec.rb +1 -1
  514. data/spec/arachni/data/issues_spec.rb +3 -3
  515. data/spec/arachni/element/capabilities/analyzable/differential_spec.rb +44 -0
  516. data/spec/arachni/element/capabilities/analyzable/signature_spec.rb +33 -162
  517. data/spec/arachni/element/capabilities/analyzable/timeout_spec.rb +4 -4
  518. data/spec/arachni/element/cookie_spec.rb +98 -49
  519. data/spec/arachni/element/form/dom_spec.rb +1 -22
  520. data/spec/arachni/element/form_spec.rb +7 -7
  521. data/spec/arachni/element/header_spec.rb +2 -2
  522. data/spec/arachni/element/json_spec.rb +2 -2
  523. data/spec/arachni/element/link/dom_spec.rb +1 -22
  524. data/spec/arachni/element/link_spec.rb +17 -1
  525. data/spec/arachni/element/link_template/dom_spec.rb +1 -22
  526. data/spec/arachni/element/link_template_spec.rb +3 -3
  527. data/spec/arachni/element/ui_form/{ui_form_dom_spec.rb → dom_spec.rb} +72 -22
  528. data/spec/arachni/element/ui_form_spec.rb +1 -0
  529. data/spec/arachni/element/ui_input/dom_spec.rb +64 -22
  530. data/spec/arachni/element/ui_input_spec.rb +1 -0
  531. data/spec/arachni/element/xml_spec.rb +1 -0
  532. data/spec/arachni/framework/parts/audit_spec.rb +7 -5
  533. data/spec/arachni/framework/parts/browser_spec.rb +8 -8
  534. data/spec/arachni/framework/parts/check_spec.rb +1 -1
  535. data/spec/arachni/framework/parts/data_spec.rb +4 -4
  536. data/spec/arachni/framework/parts/scope_spec.rb +2 -2
  537. data/spec/arachni/framework_spec.rb +1 -1
  538. data/spec/arachni/http/client/dynamic_404_handlers_spec.rb +26 -13
  539. data/spec/arachni/http/client_spec.rb +80 -45
  540. data/spec/arachni/http/cookie_jar_spec.rb +6 -6
  541. data/spec/arachni/http/proxy_server_spec.rb +69 -66
  542. data/spec/arachni/http/request_spec.rb +147 -23
  543. data/spec/arachni/http/response/scope_spec.rb +12 -12
  544. data/spec/arachni/http/response_spec.rb +62 -4
  545. data/spec/arachni/issue_spec.rb +6 -6
  546. data/spec/arachni/option_groups/audit_spec.rb +25 -8
  547. data/spec/arachni/option_groups/browser_cluster_spec.rb +27 -1
  548. data/spec/arachni/option_groups/dispatcher_spec.rb +3 -3
  549. data/spec/arachni/option_groups/input_spec.rb +9 -9
  550. data/spec/arachni/option_groups/paths_spec.rb +2 -2
  551. data/spec/arachni/option_groups/scope_spec.rb +32 -16
  552. data/spec/arachni/options_spec.rb +4 -4
  553. data/spec/arachni/page/dom/transition_spec.rb +17 -10
  554. data/spec/arachni/page/dom_spec.rb +19 -0
  555. data/spec/arachni/page/scope_spec.rb +4 -4
  556. data/spec/arachni/page_spec.rb +15 -15
  557. data/spec/arachni/platform/manager_spec.rb +2 -2
  558. data/spec/arachni/plugin/base_spec.rb +1 -0
  559. data/spec/arachni/reporter/base_spec.rb +2 -2
  560. data/spec/arachni/reporter/manager_spec.rb +2 -2
  561. data/spec/arachni/rest/server_spec.rb +495 -0
  562. data/spec/arachni/rpc/server/active_options_spec.rb +63 -12
  563. data/spec/arachni/rpc/server/base_spec.rb +1 -1
  564. data/spec/arachni/rpc/server/framework/distributor_spec.rb +2 -2
  565. data/spec/arachni/rpc/server/framework_multi_spec.rb +6 -6
  566. data/spec/arachni/rpc/server/framework_spec.rb +4 -4
  567. data/spec/arachni/rpc/server/instance_spec.rb +24 -24
  568. data/spec/arachni/ruby/array_spec.rb +2 -2
  569. data/spec/arachni/ruby/string_spec.rb +52 -0
  570. data/spec/arachni/session_spec.rb +19 -2
  571. data/spec/arachni/snapshot_spec.rb +1 -1
  572. data/spec/arachni/state/audit_spec.rb +1 -1
  573. data/spec/arachni/state/framework_spec.rb +2 -2
  574. data/spec/arachni/support/cache/least_recently_used_spec.rb +0 -2
  575. data/spec/arachni/support/glob_spec.rb +75 -0
  576. data/spec/arachni/support/lookup/hash_set_spec.rb +1 -1
  577. data/spec/arachni/support/lookup/moolb_spec.rb +2 -2
  578. data/spec/arachni/support/signature_spec.rb +4 -4
  579. data/spec/arachni/trainer_spec.rb +48 -4
  580. data/spec/arachni/uri/scope_spec.rb +54 -10
  581. data/spec/arachni/uri_spec.rb +110 -89
  582. data/spec/arachni/utilities_spec.rb +8 -8
  583. data/spec/components/checks/active/code_injection_spec.rb +9 -9
  584. data/spec/components/checks/active/file_inclusion_spec.rb +20 -20
  585. data/spec/components/checks/active/ldap_injection_spec.rb +1 -1
  586. data/spec/components/checks/active/no_sql_injection_spec.rb +1 -1
  587. data/spec/components/checks/active/os_cmd_injection_spec.rb +3 -3
  588. data/spec/components/checks/active/path_traversal_spec.rb +11 -11
  589. data/spec/components/checks/active/response_splitting_spec.rb +2 -2
  590. data/spec/components/checks/active/rfi_spec.rb +3 -3
  591. data/spec/components/checks/active/session_fixation_spec.rb +1 -1
  592. data/spec/components/checks/active/source_code_disclosure_spec.rb +4 -4
  593. data/spec/components/checks/active/sql_injection_spec.rb +58 -59
  594. data/spec/components/checks/active/unvalidated_redirect_spec.rb +2 -2
  595. data/spec/components/checks/active/xpath_injection_spec.rb +3 -3
  596. data/spec/components/checks/active/xss_dom_script_context_spec.rb +1 -1
  597. data/spec/components/checks/active/xss_dom_spec.rb +1 -1
  598. data/spec/components/checks/active/xss_script_context_spec.rb +5 -5
  599. data/spec/components/checks/active/xss_spec.rb +5 -5
  600. data/spec/components/checks/passive/grep/credit_card_spec.rb +1 -1
  601. data/spec/components/checks/passive/grep/emails_spec.rb +12 -2
  602. data/spec/components/checks/passive/grep/ssn_spec.rb +1 -1
  603. data/spec/components/path_extractors/meta_refresh_spec.rb +3 -1
  604. data/spec/components/plugins/exec_spec.rb +2 -2
  605. data/spec/components/plugins/login_script_spec.rb +22 -2
  606. data/spec/components/plugins/vector_feed_spec.rb +3 -3
  607. data/spec/spec_helper.rb +10 -4
  608. data/spec/support/factories/browser_cluster/job.rb +1 -0
  609. data/spec/support/fixtures/check_with_invalid_platforms/with_invalid_platforms.rb +1 -1
  610. data/spec/support/fixtures/checks/test.rb +1 -1
  611. data/spec/support/fixtures/checks/test2.rb +1 -1
  612. data/spec/support/fixtures/checks/test3.rb +1 -1
  613. data/spec/support/fixtures/fingerprinters/test.rb +1 -1
  614. data/spec/support/fixtures/plugins/bad.rb +1 -1
  615. data/spec/support/fixtures/plugins/defaults/default.rb +1 -1
  616. data/spec/support/fixtures/plugins/distributable.rb +1 -1
  617. data/spec/support/fixtures/plugins/loop.rb +1 -1
  618. data/spec/support/fixtures/plugins/suspendable.rb +1 -1
  619. data/spec/support/fixtures/plugins/wait.rb +1 -1
  620. data/spec/support/fixtures/plugins/with_options.rb +1 -1
  621. data/spec/support/fixtures/plugins_with_priorities/p0.rb +1 -1
  622. data/spec/support/fixtures/plugins_with_priorities/p00.rb +1 -1
  623. data/spec/support/fixtures/plugins_with_priorities/p1.rb +1 -1
  624. data/spec/support/fixtures/plugins_with_priorities/p2.rb +1 -1
  625. data/spec/support/fixtures/plugins_with_priorities/p22.rb +1 -1
  626. data/spec/support/fixtures/plugins_with_priorities/p222.rb +1 -1
  627. data/spec/support/fixtures/plugins_with_priorities/p_nil.rb +1 -1
  628. data/spec/support/fixtures/plugins_with_priorities/p_nil2.rb +1 -1
  629. data/spec/support/fixtures/report.afr +0 -0
  630. data/spec/support/fixtures/reporters/base_spec/plugin_formatters/with_formatters/foobar.rb +1 -1
  631. data/spec/support/fixtures/reporters/base_spec/with_formatters.rb +1 -1
  632. data/spec/support/fixtures/reporters/base_spec/with_outfile.rb +1 -1
  633. data/spec/support/fixtures/reporters/base_spec/without_outfile.rb +1 -1
  634. data/spec/support/fixtures/reporters/manager_spec/afr.rb +1 -1
  635. data/spec/support/fixtures/reporters/manager_spec/error.rb +1 -1
  636. data/spec/support/fixtures/reporters/manager_spec/foo.rb +1 -1
  637. data/spec/support/fixtures/run_check/body.rb +1 -1
  638. data/spec/support/fixtures/run_check/cookies.rb +1 -1
  639. data/spec/support/fixtures/run_check/empty.rb +1 -1
  640. data/spec/support/fixtures/run_check/flch.rb +1 -1
  641. data/spec/support/fixtures/run_check/forms.rb +1 -1
  642. data/spec/support/fixtures/run_check/headers.rb +1 -1
  643. data/spec/support/fixtures/run_check/links.rb +1 -1
  644. data/spec/support/fixtures/run_check/nil.rb +1 -1
  645. data/spec/support/fixtures/run_check/path.rb +1 -1
  646. data/spec/support/fixtures/run_check/server.rb +1 -1
  647. data/spec/support/fixtures/signature_check/signature.rb +1 -1
  648. data/spec/support/fixtures/wait_check/wait.rb +1 -1
  649. data/spec/support/helpers/framework.rb +1 -1
  650. data/spec/support/helpers/misc.rb +1 -1
  651. data/spec/support/helpers/paths.rb +1 -1
  652. data/spec/support/helpers/request_helpers.rb +38 -0
  653. data/spec/support/helpers/requires.rb +1 -1
  654. data/spec/support/helpers/resets.rb +1 -1
  655. data/spec/support/helpers/web_server.rb +1 -1
  656. data/spec/support/lib/factory.rb +1 -1
  657. data/spec/support/lib/web_server_client.rb +1 -1
  658. data/spec/support/lib/web_server_dispatcher.rb +1 -1
  659. data/spec/support/lib/web_server_manager.rb +2 -2
  660. data/spec/support/servers/arachni/browser.rb +182 -15
  661. data/spec/support/servers/arachni/browser/javascript/angular-1.2.8.js +1 -1
  662. data/spec/support/servers/arachni/browser/javascript/angular-route.js +1 -1
  663. data/spec/support/servers/arachni/browser/javascript/dom_monitor.rb +27 -4
  664. data/spec/support/servers/arachni/element/capabilities/analyzable/differential.rb +103 -0
  665. data/spec/support/servers/arachni/element/capabilities/analyzable/timeout.rb +5 -2
  666. data/spec/support/servers/arachni/element/header.rb +1 -1
  667. data/spec/support/servers/arachni/http/client.rb +46 -0
  668. data/spec/support/servers/arachni/http/client/dynamic_404_handler.rb +7 -1
  669. data/spec/support/servers/checks/active/code_injection.rb +5 -5
  670. data/spec/support/servers/checks/active/no_sql_injection.rb +0 -6
  671. data/spec/support/servers/checks/active/no_sql_injection_differential.rb +1 -1
  672. data/spec/support/servers/checks/active/sql_injection.rb +5 -2
  673. data/spec/support/servers/checks/active/sql_injection_differential.rb +1 -1
  674. data/spec/support/servers/checks/active/trainer_check.rb +6 -6
  675. data/spec/support/servers/checks/passive/backdoors.rb +1 -0
  676. data/spec/support/servers/checks/passive/backup_directories.rb +2 -0
  677. data/spec/support/servers/checks/passive/backup_files.rb +2 -0
  678. data/spec/support/servers/checks/passive/grep/emails.rb +6 -6
  679. data/spec/support/shared/check.rb +28 -0
  680. data/spec/support/shared/element/capabilities/auditable.rb +76 -13
  681. data/spec/support/shared/element/capabilities/dom_only.rb +5 -6
  682. data/spec/support/shared/element/capabilities/inputtable.rb +74 -4
  683. data/spec/support/shared/element/capabilities/mutable.rb +86 -14
  684. data/spec/support/shared/element/capabilities/submittable.rb +12 -0
  685. data/spec/support/shared/element/capabilities/with_dom.rb +13 -4
  686. data/spec/support/shared/element/capabilities/with_node.rb +1 -1
  687. data/spec/support/shared/element/capabilities/with_source.rb +1 -6
  688. data/spec/support/shared/element/dom/locatable.rb +20 -0
  689. data/spec/support/shared/element/dom/submittable.rb +4 -17
  690. data/spec/support/shared/http/message.rb +37 -5
  691. data/spec/support/shared/support/cache.rb +5 -4
  692. data/ui/cli/framework.rb +4 -3
  693. data/ui/cli/framework/option_parser.rb +20 -8
  694. data/ui/cli/option_parser.rb +1 -1
  695. data/ui/cli/output.rb +40 -4
  696. data/ui/cli/reporter.rb +1 -1
  697. data/ui/cli/reporter/option_parser.rb +4 -4
  698. data/ui/cli/rest/server.rb +43 -0
  699. data/ui/cli/rest/server/option_parser.rb +115 -0
  700. data/ui/cli/restored_framework.rb +1 -1
  701. data/ui/cli/restored_framework/option_parser.rb +1 -1
  702. data/ui/cli/rpc/client/dispatcher_monitor.rb +1 -1
  703. data/ui/cli/rpc/client/dispatcher_monitor/option_parser.rb +1 -1
  704. data/ui/cli/rpc/client/instance.rb +1 -1
  705. data/ui/cli/rpc/client/local.rb +1 -1
  706. data/ui/cli/rpc/client/local/option_parser.rb +1 -1
  707. data/ui/cli/rpc/client/remote.rb +1 -1
  708. data/ui/cli/rpc/client/remote/option_parser.rb +1 -1
  709. data/ui/cli/rpc/server/dispatcher.rb +1 -1
  710. data/ui/cli/rpc/server/dispatcher/option_parser.rb +1 -1
  711. data/ui/cli/utilities.rb +1 -1
  712. metadata +197 -84
  713. data/components/checks/active/no_sql_injection/patterns/mongodb +0 -1
  714. data/components/checks/active/no_sql_injection/regexp_ignore.txt +0 -0
  715. data/components/checks/active/sql_injection/patterns/access +0 -3
  716. data/components/checks/active/sql_injection/patterns/db2 +0 -5
  717. data/components/checks/active/sql_injection/patterns/frontbase +0 -1
  718. data/components/checks/active/sql_injection/patterns/hsqldb +0 -1
  719. data/components/checks/active/sql_injection/patterns/ingres +0 -3
  720. data/components/checks/active/sql_injection/patterns/maxdb +0 -2
  721. data/components/checks/active/sql_injection/patterns/mssql +0 -25
  722. data/components/checks/active/sql_injection/patterns/oracle +0 -6
  723. data/components/checks/active/sql_injection/patterns/sqlite +0 -5
  724. data/components/checks/active/sql_injection/patterns/sybase +0 -3
  725. data/lib/arachni/ruby/io.rb +0 -39
  726. data/lib/arachni/selenium/webdriver/remote/http/typhoeus.rb +0 -63
  727. data/spec/arachni/ruby/io_spec.rb +0 -26
@@ -222,6 +222,23 @@ describe Arachni::Session do
222
222
  end
223
223
 
224
224
  context 'when a login check is available' do
225
+ it 'takes into account #check_options' do
226
+ subject.check_options = {
227
+ cookies: {
228
+ 'custom-cookie' => 'value'
229
+ }
230
+ }
231
+
232
+ Arachni::Options.session.check_url = @url
233
+
234
+ expect(subject.http).to receive(:request).with(
235
+ Arachni::Options.session.check_url,
236
+ hash_including( subject.check_options )
237
+ )
238
+
239
+ configured.logged_in?
240
+ end
241
+
225
242
  context 'and a valid session is available' do
226
243
  it 'returns true' do
227
244
  configured.login
@@ -365,7 +382,7 @@ describe Arachni::Session do
365
382
  end
366
383
  end
367
384
  context 'when passed an :action' do
368
- context Regexp do
385
+ context 'Regexp' do
369
386
  it 'should use it to match against form actions' do
370
387
  expect(subject.find_login_form(
371
388
  url: @url + '/multiple',
@@ -373,7 +390,7 @@ describe Arachni::Session do
373
390
  ).coverage_id).to eq(@id)
374
391
  end
375
392
  end
376
- context String do
393
+ context 'String' do
377
394
  it 'should use it to match against form actions' do
378
395
  expect(subject.find_login_form(
379
396
  url: @url + '/multiple',
@@ -8,7 +8,7 @@ describe Arachni::Snapshot do
8
8
 
9
9
  subject { described_class }
10
10
  let(:dump_archive) do
11
- @dump_archive = "#{Dir.tmpdir}/snapshot-#{Arachni::Utilities.generate_token}.afs"
11
+ @dump_archive = "#{Arachni.tmpdir}/snapshot-#{Arachni::Utilities.generate_token}.afs"
12
12
  end
13
13
 
14
14
  describe '.summary' do
@@ -37,7 +37,7 @@ describe Arachni::State::Audit do
37
37
  context 'when an operation is not included' do
38
38
  it 'returns false' do
39
39
  subject << audit_id
40
- expect(subject).not_to include "#{audit_id}2"
40
+ expect(subject.include?( "#{audit_id}2")).to be_falsey
41
41
  end
42
42
  end
43
43
  end
@@ -40,7 +40,7 @@ describe Arachni::State::Framework do
40
40
 
41
41
  describe '#add_status_message' do
42
42
  context 'when given a message of type' do
43
- context String do
43
+ context 'String' do
44
44
  it 'pushes it to #status_messages' do
45
45
  message = 'Hey!'
46
46
  subject.add_status_message message
@@ -49,7 +49,7 @@ describe Arachni::State::Framework do
49
49
  end
50
50
  end
51
51
 
52
- context Symbol do
52
+ context 'Symbol' do
53
53
  context 'and it exists in #available_status_messages' do
54
54
  it 'pushes the associated message to #status_messages' do
55
55
  subject.add_status_message :suspending
@@ -14,8 +14,6 @@ describe Arachni::Support::Cache::LeastRecentlyUsed do
14
14
 
15
15
  expect(subject.size).to eq(3)
16
16
 
17
- ap subject
18
-
19
17
  expect(subject[:k]).to be_truthy
20
18
  expect(subject[:k4]).to be_truthy
21
19
  expect(subject[:k3]).to be_truthy
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe Arachni::Support::Glob do
4
+
5
+ let(:conversions) do
6
+ {
7
+ '*' => /^.*?$/i,
8
+ 'test*' => /^test.*?$/i,
9
+ '*test*' => /^.*?test.*?$/i,
10
+ '*/*' => /^.*?\/.*?$/i
11
+ }
12
+ end
13
+
14
+ let(:matches) do
15
+ [
16
+ ['*', '', true],
17
+ ['*', 'stuff', true],
18
+
19
+ ['test*', 'stuff', false],
20
+ ['test*', 'teststuff', true],
21
+ ['test*', 'tEsTstuff', true],
22
+ ['test*', 'stuffteststuff', false],
23
+
24
+ ['*test*', 'stuffteststuff', true],
25
+ ['*test*', 'stufftEsTstuff', true],
26
+ ['*test*', 'stuff', false],
27
+ ['*test*', 'teststuff', true],
28
+ ['*test*', 'stufftest', true],
29
+
30
+ ['*/*', 'test', false],
31
+ ['*/*', 'test/', true],
32
+ ['*/*', 'test/stuff', true]
33
+ ]
34
+ end
35
+
36
+ describe '.to_regexp' do
37
+ it 'converts a glog to a regexp' do
38
+ conversions.each do |glob, regexp|
39
+ expect(described_class.to_regexp( glob )).to eq regexp
40
+ end
41
+ end
42
+ end
43
+
44
+ describe '#regexp' do
45
+ it 'returns the glob as a regexp' do
46
+ conversions.each do |glob, regexp|
47
+ expect(described_class.new( glob ).regexp).to eq regexp
48
+ end
49
+ end
50
+ end
51
+
52
+ describe '#match?' do
53
+ it 'checks whether or not the glob matches the string' do
54
+ matches.each do |glob, string, result|
55
+ expect(described_class.new( glob ).match?( string )).to eq result
56
+ end
57
+ end
58
+ end
59
+
60
+ describe '#matches?' do
61
+ it 'checks whether or not the glob matches the string' do
62
+ matches.each do |glob, string, result|
63
+ expect(described_class.new( glob ).matches?( string )).to eq result
64
+ end
65
+ end
66
+ end
67
+
68
+ describe '=~' do
69
+ it 'checks whether or not the glob matches the string' do
70
+ matches.each do |glob, string, result|
71
+ expect(described_class.new( glob ) =~ string ).to eq result
72
+ end
73
+ end
74
+ end
75
+ end
@@ -25,7 +25,7 @@ describe Arachni::Support::LookUp::HashSet do
25
25
 
26
26
  subject.replace new
27
27
  expect(subject).to include 'test2'
28
- expect(subject).not_to include 'test'
28
+ expect(subject.include?( 'test' )).to be_falsey
29
29
  end
30
30
  end
31
31
 
@@ -4,7 +4,7 @@ describe Arachni::Support::LookUp::Moolb do
4
4
  it_behaves_like 'lookup'
5
5
 
6
6
  describe '#initialize' do
7
- describe :strategy do
7
+ describe ':strategy' do
8
8
  it 'sets the strategy for the internal cache' do
9
9
  options = {
10
10
  strategy: Arachni::Support::Cache::LeastRecentlyUsed,
@@ -24,7 +24,7 @@ describe Arachni::Support::LookUp::Moolb do
24
24
  end
25
25
  end
26
26
  end
27
- describe :max_size do
27
+ describe ':max_size' do
28
28
  it 'sets the maximum size of the cache' do
29
29
  options = { max_size: 3 }
30
30
 
@@ -19,7 +19,7 @@ describe Arachni::Support::Signature do
19
19
 
20
20
  describe '#initialize' do
21
21
  describe 'option' do
22
- describe :threshold do
22
+ describe ':threshold' do
23
23
  it 'sets the maximum difference ratio when performing comparisons' do
24
24
  seed1 = 'test this here 1'
25
25
  seed2 = 'test that here 2'
@@ -98,12 +98,12 @@ describe Arachni::Support::Signature do
98
98
  signature3 = described_class.new( different_string_with_noise )
99
99
  signature4 = described_class.new( different_string_with_noise )
100
100
 
101
- expect(signature1.differences( signature2 ).round(3)).to eq(0.348)
101
+ expect(signature1.differences( signature2 ).round(3)).to eq(0.4)
102
102
  expect(signature2.differences( signature2 )).to eq(0)
103
103
 
104
- expect(signature3.differences( signature4 )).to eq(0.2)
104
+ expect(signature3.differences( signature4 ).round(3)).to eq(0.286)
105
105
  expect(signature4.differences( signature4 )).to eq(0)
106
- expect(signature1.differences( signature3 ).round(3)).to eq(0.667)
106
+ expect(signature1.differences( signature3 ).round(3)).to eq(0.778)
107
107
  end
108
108
  end
109
109
 
@@ -84,7 +84,7 @@ describe Arachni::Trainer do
84
84
  expect(@framework.pages.size).to eq(0)
85
85
  end
86
86
  end
87
- describe false do
87
+ describe 'false' do
88
88
  it 'skips the Trainer' do
89
89
  expect(@framework.pages.size).to eq(0)
90
90
 
@@ -94,7 +94,7 @@ describe Arachni::Trainer do
94
94
  expect(@framework.pages.size).to eq(0)
95
95
  end
96
96
  end
97
- describe true do
97
+ describe 'true' do
98
98
  it 'passes the response to the Trainer' do
99
99
  expect(@framework.pages.size).to eq(0)
100
100
 
@@ -213,6 +213,50 @@ describe Arachni::Trainer do
213
213
  end
214
214
  end
215
215
 
216
+ context 'when the response has already been seen' do
217
+ before do
218
+ @trainer.page = @page
219
+
220
+ r = request( @url )
221
+ expect(@trainer).to receive(:analyze).with(r)
222
+ expect(@trainer.push( r )).to be_truthy
223
+ end
224
+
225
+ it 'returns nil' do
226
+ r = request( @url )
227
+ expect(@trainer).to_not receive(:analyze)
228
+ expect(@trainer.push( r )).to be_nil
229
+ end
230
+
231
+ context 'but URL param names are different' do
232
+ it 'returns true' do
233
+ r = request( "#{@url}/?stuff=1" )
234
+ expect(@trainer).to receive(:analyze).with(r)
235
+ expect(@trainer.push( r )).to be_truthy
236
+ end
237
+ end
238
+
239
+ context 'but cookie names are different' do
240
+ it 'returns true' do
241
+ r = request( @url )
242
+ r.headers['set-cookie'] = 'name=val'
243
+
244
+ expect(@trainer).to receive(:analyze).with(r)
245
+ expect(@trainer.push( r )).to be_truthy
246
+ end
247
+ end
248
+
249
+ context 'but the body is different' do
250
+ it 'returns true' do
251
+ r = request( @url )
252
+ r.body = '1'
253
+
254
+ expect(@trainer).to receive(:analyze).with(r)
255
+ expect(@trainer.push( r )).to be_truthy
256
+ end
257
+ end
258
+ end
259
+
216
260
  context 'when the resource is out-of-scope' do
217
261
  it 'returns false' do
218
262
  @trainer.page = @page
@@ -309,7 +353,7 @@ describe Arachni::Trainer do
309
353
 
310
354
  let(:subject) { TrainerMockFramework.new.trainer }
311
355
 
312
- context true do
356
+ context 'true' do
313
357
  before { allow_any_instance_of(TrainerMockFramework).to receive(:accepts_more_pages?){ true } }
314
358
 
315
359
  it 'processes pages' do
@@ -322,7 +366,7 @@ describe Arachni::Trainer do
322
366
  end
323
367
  end
324
368
 
325
- context false do
369
+ context 'false' do
326
370
  before { allow_any_instance_of(TrainerMockFramework).to receive(:accepts_more_pages?){ false } }
327
371
 
328
372
  it 'does not process the page' do
@@ -199,6 +199,50 @@ describe Arachni::URI::Scope do
199
199
  expect(subject.exclude?).to be_falsey
200
200
  end
201
201
  end
202
+
203
+ context 'when #exclude_file_extension?' do
204
+ context 'is true' do
205
+ before do
206
+ expect(subject).to receive(:exclude_file_extension?).and_return( true )
207
+ end
208
+
209
+ it 'returns true' do
210
+ expect(subject.exclude?).to be_truthy
211
+ end
212
+ end
213
+ end
214
+
215
+ context 'when #exclude_file_extension?' do
216
+ context 'is false' do
217
+ before do
218
+ expect(subject).to receive(:exclude_file_extension?).and_return( false )
219
+ end
220
+
221
+ it 'returns false' do
222
+ expect(subject.exclude?).to be_falsey
223
+ end
224
+ end
225
+ end
226
+ end
227
+
228
+ describe '#exclude_file_extension?' do
229
+ subject { Arachni::URI.parse( 'http://test.com/exclude.gif' ).scope }
230
+
231
+ context 'when self matches the provided exclude rules' do
232
+ it 'returns true' do
233
+ scope.exclude_file_extensions = [ 'gif' ]
234
+
235
+ expect(subject.exclude?).to be_truthy
236
+ end
237
+ end
238
+
239
+ context 'when self does not match the provided exclude rules' do
240
+ it 'returns false' do
241
+ scope.exclude_file_extensions = [ 'gi' ]
242
+
243
+ expect(subject.exclude?).to be_falsey
244
+ end
245
+ end
202
246
  end
203
247
 
204
248
  describe '#include?' do
@@ -231,7 +275,7 @@ describe Arachni::URI::Scope do
231
275
  let(:without_subdomain) { Arachni::URI.parse( url_without_subdomain ).scope }
232
276
 
233
277
  context "when #{Arachni::OptionGroups::Scope}#include_subdomains is" do
234
- context true do
278
+ context 'true' do
235
279
  before :each do
236
280
  scope.include_subdomains = true
237
281
  end
@@ -281,7 +325,7 @@ describe Arachni::URI::Scope do
281
325
  end
282
326
  end
283
327
 
284
- context false do
328
+ context 'false' do
285
329
  before :each do
286
330
  scope.include_subdomains = false
287
331
  end
@@ -347,14 +391,14 @@ describe Arachni::URI::Scope do
347
391
  context 'and the checked URL uses' do
348
392
  context 'HTTPS' do
349
393
  context 'and Options#scope_https_only is' do
350
- context true do
394
+ context 'true' do
351
395
  it 'returns true' do
352
396
  scope.https_only = true
353
397
  expect(https.follow_protocol?).to be_truthy
354
398
  end
355
399
  end
356
400
 
357
- context false do
401
+ context 'false' do
358
402
  it 'returns true' do
359
403
  scope.https_only = false
360
404
  expect(https.follow_protocol?).to be_truthy
@@ -365,14 +409,14 @@ describe Arachni::URI::Scope do
365
409
 
366
410
  context 'HTTP' do
367
411
  context 'and Options#scope_https_only is' do
368
- context true do
412
+ context 'true' do
369
413
  it 'returns false' do
370
414
  scope.https_only = true
371
415
  expect(http.follow_protocol?).to be_falsey
372
416
  end
373
417
  end
374
418
 
375
- context false do
419
+ context 'false' do
376
420
  it 'returns true' do
377
421
  scope.https_only = false
378
422
  expect(http.follow_protocol?).to be_truthy
@@ -391,14 +435,14 @@ describe Arachni::URI::Scope do
391
435
  context 'and the checked URL uses' do
392
436
  context 'HTTPS' do
393
437
  context 'and Options#scope_https_only is' do
394
- context true do
438
+ context 'true' do
395
439
  it 'returns true' do
396
440
  scope.https_only = true
397
441
  expect(https.follow_protocol?).to be_truthy
398
442
  end
399
443
  end
400
444
 
401
- context false do
445
+ context 'false' do
402
446
  it 'returns true' do
403
447
  scope.https_only = false
404
448
  expect(https.follow_protocol?).to be_truthy
@@ -408,14 +452,14 @@ describe Arachni::URI::Scope do
408
452
  end
409
453
  context 'HTTP' do
410
454
  context 'and Options#scope_https_only is' do
411
- context true do
455
+ context 'true' do
412
456
  it 'returns true' do
413
457
  scope.https_only = true
414
458
  expect(http.follow_protocol?).to be_truthy
415
459
  end
416
460
  end
417
461
 
418
- context false do
462
+ context 'false' do
419
463
  it 'returns true' do
420
464
  scope.https_only = false
421
465
  expect(http.follow_protocol?).to be_truthy
@@ -35,7 +35,8 @@ describe Arachni::URI do
35
35
  'http://testfire.net/bank/queryxpath.aspx?__EVENTVALIDATION=%2FwEWAwLNx%2B2YBwKw59eKCgKcjoPABw%3D%3D&__VIEWSTATE=%2FwEPDwUKMTEzMDczNTAxOWRk&_ctl0%3A_ctl0%3AContent%3AMain%3AButton1=Query&_ctl0%3A_ctl0%3AContent%3AMain%3ATextBox1=Enter+title+%28e.g.+IBM%29%27%3Becho+287630581954%2B4196403186331128%3B%23',
36
36
  'http://192.168.0.232/dvwa/phpinfo.php?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000%23%5E%28%24%21%40%24%29%28%28%29%29%29%2A%2A%2A%2A%2A%2A&_arachni_trainer_c987fdb6d3955bd60191449bc465bb5ca760f60661fa4bcdf28736ae04aa2a1e=c987fdb6d3955bd60191449bc465bb5ca760f60661fa4bcdf28736ae04aa2a1e',
37
37
  'http://foo.com/user/login?user%5Bname%5D=bar&user%5Bpass%5D=asdasd%26asdihbasd',
38
- 'http://stuff.host.fdfd/web/seguros/auto;jsessionid=6CB5A6A4597FFFA80C4D23B235072588.000?test=tet'
38
+ 'http://stuff.host.fdfd/web/seguros/auto;jsessionid=6CB5A6A4597FFFA80C4D23B235072588.000?test=tet',
39
+ 'http://127.0.0.2:51453/link-template/append/input/default%23%5E($!@$)(()))******/stuff'
39
40
  ]
40
41
 
41
42
  @normalized = {
@@ -84,7 +85,9 @@ describe Arachni::URI do
84
85
  "http://foo.com/user/login?user%5Bname%5D=bar&user%5Bpass%5D=asdasd%26asdihbasd"=>
85
86
  "http://foo.com/user/login?user%5Bname%5D=bar&user%5Bpass%5D=asdasd%26asdihbasd",
86
87
  "http://stuff.host.fdfd/web/seguros/auto;jsessionid=6CB5A6A4597FFFA80C4D23B235072588.000?test=tet"=>
87
- "http://stuff.host.fdfd/web/seguros/auto?test=tet"
88
+ "http://stuff.host.fdfd/web/seguros/auto?test=tet",
89
+ 'http://127.0.0.2:51453/link-template/append/input/default%23%5E($!@$)(()))******/stuff' =>
90
+ 'http://127.0.0.2:51453/link-template/append/input/default%23%5E($!@$)(()))******/stuff'
88
91
  }
89
92
 
90
93
  @ref_normalizer = proc do |p|
@@ -208,28 +211,6 @@ describe Arachni::URI do
208
211
  end
209
212
  end
210
213
 
211
- describe '.ruby_parse' do
212
- it 'cleans the URL' do
213
- @urls.each do |url|
214
- expect(described_class.ruby_parse( url ).to_s).to eq(@ref_normalizer.call( url ))
215
- end
216
- end
217
-
218
- it 'ignores javascript: URLs' do
219
- expect(described_class.ruby_parse( 'javascript:stuff()' )).to be_nil
220
- expect(described_class.ruby_parse( 'jAvaScRipT:stuff()' )).to be_nil
221
- end
222
-
223
- context 'when an error occurs' do
224
- it 'returns nil' do
225
- allow(described_class).to receive(:fast_parse){ raise }
226
- allow(described_class).to receive(:normalize){ raise }
227
-
228
- expect(described_class.ruby_parse( 'http://test.com/222' )).to be_nil
229
- end
230
- end
231
- end
232
-
233
214
  describe '.fast_parse' do
234
215
  it 'parses a URI and return its components as a hash' do
235
216
  scheme = 'http'
@@ -268,19 +249,59 @@ describe Arachni::URI do
268
249
  it 'ignores javascript: URLs' do
269
250
  expect(described_class.fast_parse( 'javascript:stuff()' )).to be_nil
270
251
  end
252
+
253
+ it 'ignores fragment-only URLs' do
254
+ expect(described_class.fast_parse( '#/stuff/here?blah=1' )).to be_nil
255
+ end
271
256
  end
272
257
 
273
258
  describe '.to_absolute' do
259
+ let(:reference) do
260
+ 'http://test.com/blah/ha?name=val#/!/stuff/?fname=fval'
261
+ end
262
+ let(:sanitized_reference) do
263
+ 'http://test.com/blah/ha?name=val'
264
+ end
265
+
274
266
  it 'converts a relative path to absolute using the reference URL' do
275
- abs = 'http://test.com/blah/ha'
267
+ abs = reference
268
+
269
+ expect(described_class.to_absolute( '', abs )).to eq('http://test.com/blah/ha?name=val')
270
+
276
271
  rel = '/test'
272
+ expect(described_class.to_absolute( rel, abs )).to eq('http://test.com/test')
273
+
274
+ rel = '/test?name2=val2'
275
+ expect(described_class.to_absolute( rel, abs )).to eq('http://test.com/test?name2=val2')
276
+
277
+ rel = '?name2=val2'
278
+ expect(described_class.to_absolute( rel, abs )).to eq('http://test.com/blah/ha?name2=val2')
279
+
277
280
  rel2 = 'test2'
278
- expect(described_class.to_absolute( rel, abs )).to eq("http://test.com" + rel)
279
- expect(described_class.to_absolute( rel2, abs )).to eq("http://test.com/blah/" + rel2)
280
- expect(described_class.to_absolute( rel2, abs + '/' )).to eq("http://test.com/blah/ha/" + rel2)
281
+ expect(described_class.to_absolute( rel2, abs )).to eq('http://test.com/blah/test2')
282
+
283
+ abs = 'http://test.com/blah/ha/?name=val#/!/stuff/?fname=fval'
284
+ expect(described_class.to_absolute( rel2, abs )).to eq('http://test.com/blah/ha/test2')
281
285
 
282
286
  rel = '//domain-name.com/stuff'
283
- expect(described_class.to_absolute( rel, abs )).to eq("http:" + rel)
287
+ expect(described_class.to_absolute( rel, abs )).to eq('http://domain-name.com/stuff')
288
+
289
+ rel = '//domain-name.com'
290
+ expect(described_class.to_absolute( rel, abs )).to eq('http://domain-name.com/')
291
+ end
292
+
293
+ context 'when the URL starts with javascript:' do
294
+ it 'returns the sanitized reference URL' do
295
+ rel = 'javascript:stuff()'
296
+ expect(described_class.to_absolute( rel, reference )).to eq(sanitized_reference)
297
+ end
298
+ end
299
+
300
+ context 'when the URL only has fragment data' do
301
+ it 'returns the sanitized reference URL' do
302
+ rel = '#/stuff/here?blah=1'
303
+ expect(described_class.to_absolute( rel, reference )).to eq(sanitized_reference)
304
+ end
284
305
  end
285
306
  end
286
307
 
@@ -315,74 +336,68 @@ describe Arachni::URI do
315
336
  end
316
337
 
317
338
  describe '#initialize' do
318
- context String do
319
- it 'normalizes and parse the string' do
320
- @urls.each do |url|
321
- uri = described_class.new( url )
322
- expect(uri.is_a?( Arachni::URI )).to be_truthy
323
- expect(uri.to_s).to eq(@ref_normalizer.call( url ))
324
- end
339
+ it 'normalizes and parses the string' do
340
+ @urls.each do |url|
341
+ uri = described_class.new( url )
342
+ expect(uri.is_a?( Arachni::URI )).to be_truthy
343
+ expect(uri.to_s).to eq(@ref_normalizer.call( url ))
325
344
  end
326
345
  end
346
+ end
327
347
 
328
- context Hash do
329
- it 'normalizes and construct a URI from a Hash of components' do
330
- @urls.each do |url|
331
- uri = described_class.new( described_class.fast_parse( url ) )
332
- expect(uri.is_a?( Arachni::URI )).to be_truthy
333
- expect(uri.to_s).to eq(@ref_normalizer.call( url ))
334
- end
348
+ describe '#==' do
349
+ it 'converts both objects to strings and compare them' do
350
+ @urls.each do |url|
351
+ normalized_str = described_class.normalize( url )
352
+
353
+ a_uri = described_class.new( url )
354
+ expect(a_uri.is_a?( Arachni::URI )).to be_truthy
355
+
356
+ expect(a_uri).to eq(normalized_str)
357
+ expect(a_uri).to eq(a_uri)
335
358
  end
336
359
  end
360
+ end
337
361
 
338
- context URI do
339
- it 'normalizes and construct a URI from a Hash of components' do
340
- @urls.each do |url|
341
- uri = ::URI.parse( described_class.normalize( url ) )
342
- expect(uri.is_a?( ::URI )).to be_truthy
362
+ describe '#seed_in_host?' do
363
+ let(:parsed) { described_class.new( url ) }
343
364
 
344
- a_uri = described_class.new( url )
345
- expect(a_uri.is_a?( Arachni::URI )).to be_truthy
346
- expect(a_uri.to_s).to eq(@ref_normalizer.call( url ))
347
- end
365
+ context 'when the seed is in the domain' do
366
+ let(:url) { "http://www.#{Arachni::Utilities.random_seed}.com/stuff" }
367
+
368
+ it 'returns true' do
369
+ expect(parsed.seed_in_host?).to be_truthy
348
370
  end
349
371
  end
350
372
 
351
- context Arachni::URI do
352
- it 'normalizes and construct a URI from a Hash of components' do
353
- @urls.each do |url|
354
- uri = described_class.new( url )
355
- a_uri = described_class.new( uri )
356
- expect(a_uri.is_a?( Arachni::URI )).to be_truthy
357
- expect(a_uri).to eq(uri)
358
- end
373
+ context 'when the seed is in the subdomain' do
374
+ let(:url) { "http://#{Arachni::Utilities.random_seed}.test.com" }
375
+
376
+ it 'returns true' do
377
+ expect(parsed.seed_in_host?).to be_truthy
359
378
  end
360
379
  end
361
380
 
362
- context 'else' do
363
- it 'raises a ArgumentError' do
364
- expect { described_class.new( [] ) }.to raise_error ArgumentError
381
+ context 'when the seed is in the TLD' do
382
+ let(:url) { "http://test.#{Arachni::Utilities.random_seed}" }
383
+
384
+ it 'returns true' do
385
+ expect(parsed.seed_in_host?).to be_truthy
365
386
  end
366
387
  end
367
- end
368
388
 
369
- describe '#==' do
370
- it 'converts both objects to strings and compare them' do
371
- @urls.each do |url|
372
- normalized_str = described_class.normalize( url )
373
- uri = ::URI.parse( normalized_str )
374
- expect(uri.is_a?( ::URI )).to be_truthy
389
+ context 'when the seed is not in the host' do
390
+ let(:url) { "http://test.com" }
375
391
 
376
- a_uri = described_class.new( url )
377
- expect(a_uri.is_a?( Arachni::URI )).to be_truthy
378
-
379
- expect(a_uri).to eq(uri)
380
- expect(a_uri).to eq(normalized_str)
381
- expect(a_uri).to eq(a_uri)
392
+ it 'returns false' do
393
+ expect(parsed.seed_in_host?).to be_falsey
382
394
  end
383
395
  end
384
396
  end
385
397
 
398
+ describe '#relative?'
399
+ describe '#absolute?'
400
+
386
401
  describe '#query=' do
387
402
  subject { described_class.new( 'http://test.com/?my=val' ) }
388
403
 
@@ -463,6 +478,25 @@ describe Arachni::URI do
463
478
  end
464
479
  end
465
480
 
481
+ describe '#up_to_port' do
482
+ it 'returns the URL up to its port' do
483
+ url = 'http://test.com/path/goes/here.php?query=goes&here=.!#frag'
484
+ expect(described_class.parse( url ).up_to_port).to eq('http://test.com')
485
+
486
+ url = 'http://test.com:80/path/goes/here/?query=goes&here=.!#frag'
487
+ expect(described_class.parse( url ).up_to_port).to eq('http://test.com')
488
+
489
+ url = 'http://test.com:23/path/goes/here?query=goes&here=.!#frag'
490
+ expect(described_class.parse( url ).up_to_port).to eq('http://test.com:23')
491
+
492
+ url = 'https://test.com:443/'
493
+ expect(described_class.parse( url ).up_to_port).to eq('https://test.com')
494
+
495
+ url = 'https://test.com:54/'
496
+ expect(described_class.parse( url ).up_to_port).to eq('https://test.com:54')
497
+ end
498
+ end
499
+
466
500
  describe '#domain' do
467
501
  it 'removes the deepest subdomain from the host' do
468
502
  url = 'http://test.com/'
@@ -568,19 +602,6 @@ describe Arachni::URI do
568
602
  end
569
603
  end
570
604
 
571
- describe '#mailto?' do
572
- context 'when the URI has a mailto scheme' do
573
- it 'returns true' do
574
- expect(described_class.new( 'mailto:stuff@blah.com' ).mailto?).to be_truthy
575
- end
576
- end
577
- context 'when the URI does not have a mailto scheme' do
578
- it 'returns false' do
579
- expect(described_class.new( 'blah.com' ).mailto?).to be_falsey
580
- end
581
- end
582
- end
583
-
584
605
  describe '#hash' do
585
606
  it 'returns a hash uniquely identifying the URI' do
586
607
  uri = described_class.new( 'http://stuff/' )