arachni 1.0.6 → 1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (634) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +193 -0
  3. data/Gemfile +0 -1
  4. data/LICENSE.md +1 -1
  5. data/README.md +23 -18
  6. data/Rakefile +5 -3
  7. data/arachni.gemspec +11 -8
  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_restore +1 -1
  13. data/bin/arachni_rpc +1 -1
  14. data/bin/arachni_rpcd +1 -1
  15. data/bin/arachni_rpcd_monitor +1 -1
  16. data/bin/arachni_script +1 -1
  17. data/components/checks/active/code_injection.rb +5 -7
  18. data/components/checks/active/code_injection_php_input_wrapper.rb +1 -1
  19. data/components/checks/active/code_injection_timing.rb +2 -3
  20. data/components/checks/active/csrf.rb +9 -5
  21. data/components/checks/active/file_inclusion.rb +4 -5
  22. data/components/checks/active/ldap_injection.rb +6 -8
  23. data/components/checks/active/no_sql_injection.rb +4 -6
  24. data/components/checks/active/no_sql_injection_differential.rb +1 -1
  25. data/components/checks/active/os_cmd_injection.rb +7 -9
  26. data/components/checks/active/os_cmd_injection_timing.rb +6 -8
  27. data/components/checks/active/path_traversal.rb +6 -7
  28. data/components/checks/active/response_splitting.rb +7 -15
  29. data/components/checks/active/rfi.rb +4 -8
  30. data/components/checks/active/session_fixation.rb +1 -1
  31. data/components/checks/active/source_code_disclosure.rb +9 -7
  32. data/components/checks/active/sql_injection.rb +6 -9
  33. data/components/checks/active/sql_injection_differential.rb +3 -3
  34. data/components/checks/active/sql_injection_timing.rb +6 -8
  35. data/components/checks/active/trainer.rb +4 -4
  36. data/components/checks/active/unvalidated_redirect.rb +7 -6
  37. data/components/checks/active/unvalidated_redirect_dom.rb +97 -0
  38. data/components/checks/active/xpath_injection.rb +7 -8
  39. data/components/checks/active/xss.rb +11 -10
  40. data/components/checks/active/xss_dom.rb +3 -4
  41. data/components/checks/active/xss_dom_inputs.rb +1 -1
  42. data/components/checks/active/xss_dom_script_context.rb +6 -7
  43. data/components/checks/active/xss_event.rb +4 -4
  44. data/components/checks/active/xss_path.rb +1 -1
  45. data/components/checks/active/xss_script_context.rb +11 -4
  46. data/components/checks/active/xss_tag.rb +6 -6
  47. data/components/checks/active/xxe.rb +110 -0
  48. data/components/checks/passive/allowed_methods.rb +1 -1
  49. data/components/checks/passive/backdoors.rb +1 -1
  50. data/components/checks/passive/backup_directories.rb +1 -1
  51. data/components/checks/passive/backup_files.rb +1 -1
  52. data/components/checks/passive/common_directories.rb +1 -1
  53. data/components/checks/passive/common_directories/directories.txt +2 -0
  54. data/components/checks/passive/common_files.rb +1 -1
  55. data/components/checks/passive/directory_listing.rb +1 -1
  56. data/components/checks/passive/grep/captcha.rb +2 -2
  57. data/components/checks/passive/grep/cookie_set_for_parent_domain.rb +1 -1
  58. data/components/checks/passive/grep/credit_card.rb +1 -1
  59. data/components/checks/passive/grep/cvs_svn_users.rb +1 -1
  60. data/components/checks/passive/grep/emails.rb +1 -1
  61. data/components/checks/passive/grep/form_upload.rb +2 -2
  62. data/components/checks/passive/grep/hsts.rb +2 -2
  63. data/components/checks/passive/grep/html_objects.rb +4 -4
  64. data/components/checks/passive/grep/http_only_cookies.rb +1 -1
  65. data/components/checks/passive/grep/insecure_cookies.rb +1 -1
  66. data/components/checks/passive/grep/insecure_cors_policy.rb +66 -0
  67. data/components/checks/passive/grep/mixed_resource.rb +1 -1
  68. data/components/checks/passive/grep/password_autocomplete.rb +2 -2
  69. data/components/checks/passive/grep/private_ip.rb +1 -1
  70. data/components/checks/passive/grep/ssn.rb +1 -1
  71. data/components/checks/passive/grep/unencrypted_password_forms.rb +2 -2
  72. data/components/checks/passive/grep/x_frame_options.rb +61 -0
  73. data/components/checks/passive/htaccess_limit.rb +1 -1
  74. data/components/checks/passive/http_put.rb +10 -3
  75. data/components/checks/passive/insecure_client_access_policy.rb +91 -0
  76. data/components/checks/passive/insecure_cross_domain_policy_access.rb +91 -0
  77. data/components/checks/passive/insecure_cross_domain_policy_headers.rb +91 -0
  78. data/components/checks/passive/interesting_responses.rb +1 -1
  79. data/components/checks/passive/localstart_asp.rb +1 -1
  80. data/components/checks/passive/origin_spoof_access_restriction_bypass.rb +1 -1
  81. data/components/checks/passive/webdav.rb +1 -1
  82. data/components/checks/passive/xst.rb +1 -1
  83. data/components/fingerprinters/frameworks/rack.rb +1 -1
  84. data/components/fingerprinters/languages/asp.rb +1 -1
  85. data/components/fingerprinters/languages/aspx.rb +1 -1
  86. data/components/fingerprinters/languages/jsp.rb +1 -1
  87. data/components/fingerprinters/languages/php.rb +1 -1
  88. data/components/fingerprinters/languages/python.rb +1 -1
  89. data/components/fingerprinters/languages/ruby.rb +1 -1
  90. data/components/fingerprinters/os/bsd.rb +1 -1
  91. data/components/fingerprinters/os/linux.rb +1 -1
  92. data/components/fingerprinters/os/solaris.rb +1 -1
  93. data/components/fingerprinters/os/unix.rb +1 -1
  94. data/components/fingerprinters/os/windows.rb +1 -1
  95. data/components/fingerprinters/servers/apache.rb +1 -1
  96. data/components/fingerprinters/servers/iis.rb +1 -1
  97. data/components/fingerprinters/servers/jetty.rb +1 -1
  98. data/components/fingerprinters/servers/nginx.rb +1 -1
  99. data/components/fingerprinters/servers/tomcat.rb +1 -1
  100. data/components/path_extractors/anchors.rb +1 -1
  101. data/components/path_extractors/areas.rb +1 -1
  102. data/components/path_extractors/comments.rb +5 -5
  103. data/components/path_extractors/forms.rb +1 -1
  104. data/components/path_extractors/frames.rb +1 -1
  105. data/components/path_extractors/generic.rb +1 -1
  106. data/components/path_extractors/links.rb +1 -1
  107. data/components/path_extractors/meta_refresh.rb +1 -1
  108. data/components/path_extractors/scripts.rb +1 -1
  109. data/components/plugins/autologin.rb +6 -6
  110. data/components/plugins/beep_notify.rb +1 -1
  111. data/components/plugins/content_types.rb +1 -1
  112. data/components/plugins/cookie_collector.rb +1 -1
  113. data/components/plugins/defaults/autothrottle.rb +1 -1
  114. data/components/plugins/defaults/healthmap.rb +1 -1
  115. data/components/plugins/defaults/meta/remedies/discovery.rb +2 -4
  116. data/components/plugins/defaults/meta/remedies/timing_attacks.rb +1 -1
  117. data/components/plugins/defaults/meta/uniformity.rb +1 -1
  118. data/components/plugins/email_notify.rb +24 -12
  119. data/components/plugins/exec.rb +153 -0
  120. data/components/plugins/form_dicattack.rb +4 -4
  121. data/components/plugins/headers_collector.rb +102 -0
  122. data/components/plugins/http_dicattack.rb +4 -4
  123. data/components/plugins/login_script.rb +4 -5
  124. data/components/plugins/proxy.rb +19 -7
  125. data/components/plugins/proxy/template_scope.rb +1 -1
  126. data/components/plugins/script.rb +1 -1
  127. data/components/plugins/uncommon_headers.rb +9 -2
  128. data/components/plugins/vector_collector.rb +73 -0
  129. data/components/plugins/vector_feed.rb +3 -5
  130. data/components/plugins/waf_detector.rb +3 -3
  131. data/components/reporters/ap.rb +1 -1
  132. data/components/reporters/html.rb +138 -14
  133. data/components/reporters/html/default.erb +1 -1
  134. data/components/reporters/html/default/configuration.erb +2 -2
  135. data/components/reporters/html/default/issue/page.erb +1 -1
  136. data/components/reporters/html/default/issue/vector.erb +2 -2
  137. data/components/reporters/html/default/js/charts.js.erb +7 -4
  138. data/components/reporters/html/default/js/helpers.js +2 -0
  139. data/components/reporters/html/default/summary.erb +7 -0
  140. data/components/reporters/html/default/summary/charts.erb +3 -3
  141. data/components/reporters/html/default/summary/issues.erb +1 -91
  142. data/components/reporters/html/default/summary/issues/by_name.erb +90 -0
  143. data/components/reporters/html/default/summary/owasp_top_10.erb +43 -0
  144. data/components/reporters/json.rb +1 -1
  145. data/components/reporters/marshal.rb +1 -1
  146. data/components/reporters/plugin_formatters/html/autologin.rb +1 -1
  147. data/components/reporters/plugin_formatters/html/content_types.rb +1 -1
  148. data/components/reporters/plugin_formatters/html/cookie_collector.rb +1 -1
  149. data/components/reporters/plugin_formatters/html/exec.rb +63 -0
  150. data/components/reporters/plugin_formatters/html/form_dicattack.rb +1 -1
  151. data/components/reporters/plugin_formatters/html/healthmap.rb +1 -1
  152. data/components/reporters/plugin_formatters/html/http_dicattack.rb +1 -1
  153. data/components/reporters/plugin_formatters/html/login_script.rb +1 -1
  154. data/components/reporters/plugin_formatters/html/uncommon_headers.rb +1 -1
  155. data/components/reporters/plugin_formatters/html/uniformity.rb +1 -1
  156. data/components/reporters/plugin_formatters/html/vector_collector.rb +59 -0
  157. data/components/reporters/plugin_formatters/html/waf_detector.rb +1 -1
  158. data/components/reporters/plugin_formatters/stdout/autologin.rb +1 -1
  159. data/components/reporters/plugin_formatters/stdout/content_types.rb +1 -1
  160. data/components/reporters/plugin_formatters/stdout/cookie_collector.rb +1 -1
  161. data/components/reporters/plugin_formatters/stdout/exec.rb +26 -0
  162. data/components/reporters/plugin_formatters/stdout/form_dicattack.rb +1 -1
  163. data/components/reporters/plugin_formatters/stdout/healthmap.rb +1 -1
  164. data/components/reporters/plugin_formatters/stdout/http_dicattack.rb +1 -1
  165. data/components/reporters/plugin_formatters/stdout/login_script.rb +1 -1
  166. data/components/reporters/plugin_formatters/stdout/uncommon_headers.rb +1 -1
  167. data/components/reporters/plugin_formatters/stdout/uniformity.rb +1 -1
  168. data/components/reporters/plugin_formatters/stdout/vector_collector.rb +40 -0
  169. data/components/reporters/plugin_formatters/stdout/waf_detector.rb +1 -1
  170. data/components/reporters/plugin_formatters/xml/autologin.rb +1 -1
  171. data/components/reporters/plugin_formatters/xml/content_types.rb +1 -1
  172. data/components/reporters/plugin_formatters/xml/cookie_collector.rb +1 -1
  173. data/components/reporters/plugin_formatters/xml/exec.rb +26 -0
  174. data/components/reporters/plugin_formatters/xml/form_dicattack.rb +1 -1
  175. data/components/reporters/plugin_formatters/xml/healthmap.rb +1 -1
  176. data/components/reporters/plugin_formatters/xml/http_dicattack.rb +1 -1
  177. data/components/reporters/plugin_formatters/xml/login_script.rb +1 -1
  178. data/components/reporters/plugin_formatters/xml/uncommon_headers.rb +1 -1
  179. data/components/reporters/plugin_formatters/xml/uniformity.rb +1 -1
  180. data/components/reporters/plugin_formatters/xml/vector_collector.rb +44 -0
  181. data/components/reporters/plugin_formatters/xml/waf_detector.rb +1 -1
  182. data/components/reporters/stdout.rb +1 -1
  183. data/components/reporters/txt.rb +1 -1
  184. data/components/reporters/xml.rb +18 -9
  185. data/components/reporters/xml/schema.xsd +73 -8
  186. data/components/reporters/yaml.rb +1 -1
  187. data/config/write_paths.yml +15 -0
  188. data/lib/arachni.rb +1 -1
  189. data/lib/arachni/banner.rb +1 -1
  190. data/lib/arachni/browser.rb +221 -77
  191. data/lib/arachni/browser/element_locator.rb +7 -2
  192. data/lib/arachni/browser/javascript.rb +40 -24
  193. data/lib/arachni/browser/javascript/dom_monitor.rb +1 -1
  194. data/lib/arachni/browser/javascript/proxy.rb +1 -1
  195. data/lib/arachni/browser/javascript/proxy/stub.rb +1 -1
  196. data/lib/arachni/browser/javascript/scripts/dom_monitor.js +8 -3
  197. data/lib/arachni/browser/javascript/scripts/taint_tracer.js +57 -39
  198. data/lib/arachni/browser/javascript/taint_tracer.rb +12 -8
  199. data/lib/arachni/browser/javascript/taint_tracer/frame.rb +1 -1
  200. data/lib/arachni/browser/javascript/taint_tracer/frame/called_function.rb +1 -1
  201. data/lib/arachni/browser/javascript/taint_tracer/sink/base.rb +1 -1
  202. data/lib/arachni/browser/javascript/taint_tracer/sink/data_flow.rb +1 -1
  203. data/lib/arachni/browser/javascript/taint_tracer/sink/execution_flow.rb +1 -1
  204. data/lib/arachni/browser_cluster.rb +5 -3
  205. data/lib/arachni/browser_cluster/job.rb +1 -1
  206. data/lib/arachni/browser_cluster/job/result.rb +1 -1
  207. data/lib/arachni/browser_cluster/jobs/browser_provider.rb +2 -1
  208. data/lib/arachni/browser_cluster/jobs/resource_exploration.rb +2 -1
  209. data/lib/arachni/browser_cluster/jobs/resource_exploration/event_trigger.rb +1 -1
  210. data/lib/arachni/browser_cluster/jobs/resource_exploration/event_trigger/result.rb +1 -1
  211. data/lib/arachni/browser_cluster/jobs/resource_exploration/result.rb +1 -1
  212. data/lib/arachni/browser_cluster/jobs/taint_trace.rb +2 -1
  213. data/lib/arachni/browser_cluster/jobs/taint_trace/event_trigger.rb +1 -1
  214. data/lib/arachni/browser_cluster/jobs/taint_trace/event_trigger/result.rb +1 -1
  215. data/lib/arachni/browser_cluster/jobs/taint_trace/result.rb +1 -1
  216. data/lib/arachni/browser_cluster/worker.rb +16 -16
  217. data/lib/arachni/check.rb +1 -1
  218. data/lib/arachni/check/auditor.rb +40 -17
  219. data/lib/arachni/check/base.rb +1 -1
  220. data/lib/arachni/check/manager.rb +1 -1
  221. data/lib/arachni/component.rb +1 -1
  222. data/lib/arachni/component/base.rb +1 -1
  223. data/lib/arachni/component/manager.rb +1 -1
  224. data/lib/arachni/component/options.rb +1 -1
  225. data/lib/arachni/component/options/address.rb +1 -1
  226. data/lib/arachni/component/options/base.rb +1 -1
  227. data/lib/arachni/component/options/bool.rb +1 -1
  228. data/lib/arachni/component/options/float.rb +1 -1
  229. data/lib/arachni/component/options/int.rb +1 -1
  230. data/lib/arachni/component/options/multiple_choice.rb +1 -1
  231. data/lib/arachni/component/options/object.rb +1 -1
  232. data/lib/arachni/component/options/path.rb +1 -1
  233. data/lib/arachni/component/options/port.rb +1 -1
  234. data/lib/arachni/component/options/string.rb +1 -1
  235. data/lib/arachni/component/options/url.rb +1 -1
  236. data/lib/arachni/component/output.rb +1 -1
  237. data/lib/arachni/component/utilities.rb +1 -1
  238. data/lib/arachni/data.rb +1 -1
  239. data/lib/arachni/data/framework.rb +1 -1
  240. data/lib/arachni/data/framework/rpc.rb +1 -1
  241. data/lib/arachni/data/issues.rb +1 -1
  242. data/lib/arachni/data/plugins.rb +1 -1
  243. data/lib/arachni/data/session.rb +1 -1
  244. data/lib/arachni/element/base.rb +10 -4
  245. data/lib/arachni/element/body.rb +1 -6
  246. data/lib/arachni/element/capabilities/analyzable.rb +1 -1
  247. data/lib/arachni/element/capabilities/analyzable/differential.rb +41 -6
  248. data/lib/arachni/element/capabilities/analyzable/taint.rb +10 -2
  249. data/lib/arachni/element/capabilities/analyzable/timeout.rb +61 -8
  250. data/lib/arachni/element/capabilities/auditable.rb +9 -2
  251. data/lib/arachni/element/capabilities/auditable/dom.rb +6 -7
  252. data/lib/arachni/element/capabilities/inputtable.rb +5 -3
  253. data/lib/arachni/element/capabilities/mutable.rb +182 -67
  254. data/lib/arachni/element/capabilities/refreshable.rb +1 -1
  255. data/lib/arachni/element/capabilities/submittable.rb +3 -3
  256. data/lib/arachni/element/capabilities/with_auditor.rb +1 -1
  257. data/lib/arachni/element/capabilities/with_auditor/output.rb +1 -1
  258. data/lib/arachni/element/capabilities/with_dom.rb +17 -5
  259. data/lib/arachni/element/capabilities/with_node.rb +6 -31
  260. data/lib/arachni/element/capabilities/with_scope.rb +1 -1
  261. data/lib/arachni/element/capabilities/with_scope/scope.rb +8 -2
  262. data/lib/arachni/element/capabilities/with_source.rb +55 -0
  263. data/lib/arachni/element/cookie.rb +39 -112
  264. data/lib/arachni/element/cookie/capabilities/inputtable.rb +53 -0
  265. data/lib/arachni/element/cookie/capabilities/mutable.rb +95 -0
  266. data/lib/arachni/element/cookie/capabilities/with_dom.rb +31 -0
  267. data/lib/arachni/element/cookie/dom.rb +2 -2
  268. data/lib/arachni/element/form.rb +65 -153
  269. data/lib/arachni/element/form/capabilities/auditable.rb +45 -0
  270. data/lib/arachni/element/form/capabilities/mutable.rb +126 -0
  271. data/lib/arachni/element/form/capabilities/submittable.rb +36 -0
  272. data/lib/arachni/element/form/capabilities/with_dom.rb +32 -0
  273. data/lib/arachni/element/form/dom.rb +13 -4
  274. data/lib/arachni/element/generic_dom.rb +5 -3
  275. data/lib/arachni/element/header.rb +16 -11
  276. data/lib/arachni/element/json.rb +145 -0
  277. data/lib/arachni/element/json/capabilities/inputtable.rb +139 -0
  278. data/lib/arachni/element/json/capabilities/mutable.rb +121 -0
  279. data/lib/arachni/element/link.rb +14 -40
  280. data/lib/arachni/element/link/capabilities/auditable.rb +27 -0
  281. data/lib/arachni/element/link/capabilities/submittable.rb +37 -0
  282. data/lib/arachni/element/link/capabilities/with_dom.rb +43 -0
  283. data/lib/arachni/element/link/dom.rb +9 -2
  284. data/lib/arachni/element/link_template.rb +23 -51
  285. data/lib/arachni/element/link_template/capabilities/auditable.rb +27 -0
  286. data/lib/arachni/element/link_template/capabilities/inputtable.rb +47 -0
  287. data/lib/arachni/element/link_template/capabilities/with_dom.rb +42 -0
  288. data/lib/arachni/element/link_template/dom.rb +3 -2
  289. data/lib/arachni/element/path.rb +1 -1
  290. data/lib/arachni/element/server.rb +99 -18
  291. data/lib/arachni/element/xml.rb +195 -0
  292. data/lib/arachni/element/xml/capabilities/inputtable.rb +34 -0
  293. data/lib/arachni/element/xml/capabilities/mutable.rb +39 -0
  294. data/lib/arachni/element_filter.rb +54 -3
  295. data/lib/arachni/error.rb +1 -1
  296. data/lib/arachni/ethon/easy.rb +1 -1
  297. data/lib/arachni/framework.rb +20 -1
  298. data/lib/arachni/framework/parts/audit.rb +29 -22
  299. data/lib/arachni/framework/parts/browser.rb +53 -5
  300. data/lib/arachni/framework/parts/check.rb +11 -2
  301. data/lib/arachni/framework/parts/data.rb +8 -6
  302. data/lib/arachni/framework/parts/platform.rb +1 -1
  303. data/lib/arachni/framework/parts/plugin.rb +1 -1
  304. data/lib/arachni/framework/parts/report.rb +1 -1
  305. data/lib/arachni/framework/parts/scope.rb +1 -1
  306. data/lib/arachni/framework/parts/state.rb +5 -4
  307. data/lib/arachni/http.rb +1 -1
  308. data/lib/arachni/http/client.rb +13 -242
  309. data/lib/arachni/http/client/dynamic_404_handler.rb +474 -0
  310. data/lib/arachni/http/cookie_jar.rb +1 -1
  311. data/lib/arachni/http/headers.rb +11 -2
  312. data/lib/arachni/http/message.rb +1 -1
  313. data/lib/arachni/http/message/scope.rb +1 -1
  314. data/lib/arachni/http/proxy_server.rb +7 -4
  315. data/lib/arachni/http/request.rb +39 -8
  316. data/lib/arachni/http/request/scope.rb +1 -1
  317. data/lib/arachni/http/response.rb +10 -4
  318. data/lib/arachni/http/response/scope.rb +1 -1
  319. data/lib/arachni/issue.rb +17 -7
  320. data/lib/arachni/issue/severity.rb +1 -1
  321. data/lib/arachni/issue/severity/base.rb +1 -1
  322. data/lib/arachni/option_group.rb +1 -1
  323. data/lib/arachni/option_groups.rb +1 -1
  324. data/lib/arachni/option_groups/audit.rb +74 -6
  325. data/lib/arachni/option_groups/browser_cluster.rb +2 -2
  326. data/lib/arachni/option_groups/datastore.rb +1 -1
  327. data/lib/arachni/option_groups/dispatcher.rb +1 -1
  328. data/lib/arachni/option_groups/http.rb +143 -7
  329. data/lib/arachni/option_groups/input.rb +1 -1
  330. data/lib/arachni/option_groups/output.rb +1 -1
  331. data/lib/arachni/option_groups/paths.rb +1 -1
  332. data/lib/arachni/option_groups/rpc.rb +1 -1
  333. data/lib/arachni/option_groups/scope.rb +9 -9
  334. data/lib/arachni/option_groups/session.rb +1 -1
  335. data/lib/arachni/option_groups/snapshot.rb +1 -1
  336. data/lib/arachni/options.rb +1 -1
  337. data/lib/arachni/page.rb +81 -45
  338. data/lib/arachni/page/dom.rb +13 -3
  339. data/lib/arachni/page/dom/transition.rb +1 -1
  340. data/lib/arachni/page/scope.rb +1 -1
  341. data/lib/arachni/parser.rb +11 -1
  342. data/lib/arachni/platform.rb +1 -1
  343. data/lib/arachni/platform/fingerprinter.rb +1 -1
  344. data/lib/arachni/platform/list.rb +1 -1
  345. data/lib/arachni/platform/manager.rb +1 -1
  346. data/lib/arachni/plugin.rb +1 -1
  347. data/lib/arachni/plugin/base.rb +11 -4
  348. data/lib/arachni/plugin/formatter.rb +1 -1
  349. data/lib/arachni/plugin/manager.rb +13 -5
  350. data/lib/arachni/processes.rb +1 -1
  351. data/lib/arachni/processes/dispatchers.rb +1 -1
  352. data/lib/arachni/processes/helpers.rb +1 -1
  353. data/lib/arachni/processes/helpers/dispatchers.rb +1 -1
  354. data/lib/arachni/processes/helpers/instances.rb +1 -1
  355. data/lib/arachni/processes/helpers/processes.rb +1 -1
  356. data/lib/arachni/processes/instances.rb +1 -1
  357. data/lib/arachni/processes/manager.rb +8 -3
  358. data/lib/arachni/report.rb +12 -2
  359. data/lib/arachni/reporter.rb +1 -1
  360. data/lib/arachni/reporter/base.rb +1 -1
  361. data/lib/arachni/reporter/formatter_manager.rb +1 -1
  362. data/lib/arachni/reporter/manager.rb +1 -1
  363. data/lib/arachni/reporter/options.rb +1 -1
  364. data/lib/arachni/rpc/client/base.rb +1 -1
  365. data/lib/arachni/rpc/client/dispatcher.rb +1 -1
  366. data/lib/arachni/rpc/client/instance.rb +1 -1
  367. data/lib/arachni/rpc/client/instance/framework.rb +1 -1
  368. data/lib/arachni/rpc/client/instance/service.rb +1 -1
  369. data/lib/arachni/rpc/serializer.rb +3 -1
  370. data/lib/arachni/rpc/server/active_options.rb +1 -25
  371. data/lib/arachni/rpc/server/base.rb +1 -1
  372. data/lib/arachni/rpc/server/check/manager.rb +1 -1
  373. data/lib/arachni/rpc/server/dispatcher.rb +1 -1
  374. data/lib/arachni/rpc/server/dispatcher/node.rb +1 -1
  375. data/lib/arachni/rpc/server/dispatcher/service.rb +1 -1
  376. data/lib/arachni/rpc/server/framework.rb +1 -1
  377. data/lib/arachni/rpc/server/framework/distributor.rb +2 -6
  378. data/lib/arachni/rpc/server/framework/master.rb +1 -1
  379. data/lib/arachni/rpc/server/framework/multi_instance.rb +1 -1
  380. data/lib/arachni/rpc/server/framework/slave.rb +1 -1
  381. data/lib/arachni/rpc/server/instance.rb +9 -1
  382. data/lib/arachni/rpc/server/output.rb +1 -1
  383. data/lib/arachni/rpc/server/plugin/manager.rb +1 -1
  384. data/lib/arachni/ruby.rb +1 -1
  385. data/lib/arachni/ruby/array.rb +1 -1
  386. data/lib/arachni/ruby/hash.rb +1 -1
  387. data/lib/arachni/ruby/io.rb +1 -1
  388. data/lib/arachni/ruby/object.rb +1 -1
  389. data/lib/arachni/ruby/set.rb +1 -1
  390. data/lib/arachni/ruby/string.rb +1 -1
  391. data/lib/arachni/ruby/webrick.rb +1 -1
  392. data/lib/arachni/ruby/webrick/cookie.rb +1 -1
  393. data/lib/arachni/ruby/webrick/httprequest.rb +1 -1
  394. data/lib/arachni/scope.rb +1 -1
  395. data/lib/arachni/selenium/webdriver/remote/http/typhoeus.rb +19 -2
  396. data/lib/arachni/session.rb +8 -3
  397. data/lib/arachni/snapshot.rb +1 -1
  398. data/lib/arachni/state.rb +1 -1
  399. data/lib/arachni/state/audit.rb +1 -1
  400. data/lib/arachni/state/element_filter.rb +12 -20
  401. data/lib/arachni/state/framework.rb +1 -1
  402. data/lib/arachni/state/framework/rpc.rb +1 -1
  403. data/lib/arachni/state/http.rb +1 -1
  404. data/lib/arachni/state/options.rb +1 -1
  405. data/lib/arachni/state/plugins.rb +1 -1
  406. data/lib/arachni/support.rb +1 -1
  407. data/lib/arachni/support/buffer.rb +1 -1
  408. data/lib/arachni/support/buffer/autoflush.rb +1 -1
  409. data/lib/arachni/support/buffer/base.rb +1 -1
  410. data/lib/arachni/support/cache.rb +1 -1
  411. data/lib/arachni/support/cache/base.rb +1 -1
  412. data/lib/arachni/support/cache/least_cost_replacement.rb +1 -1
  413. data/lib/arachni/support/cache/least_recently_used.rb +1 -1
  414. data/lib/arachni/support/cache/preference.rb +1 -1
  415. data/lib/arachni/support/cache/random_replacement.rb +1 -1
  416. data/lib/arachni/support/crypto.rb +1 -1
  417. data/lib/arachni/support/crypto/rsa_aes_cbc.rb +1 -1
  418. data/lib/arachni/support/database.rb +1 -1
  419. data/lib/arachni/support/database/base.rb +1 -1
  420. data/lib/arachni/support/database/hash.rb +1 -1
  421. data/lib/arachni/support/database/queue.rb +1 -1
  422. data/lib/arachni/support/lookup.rb +1 -1
  423. data/lib/arachni/support/lookup/base.rb +1 -1
  424. data/lib/arachni/support/lookup/hash_set.rb +1 -1
  425. data/lib/arachni/support/lookup/moolb.rb +1 -1
  426. data/lib/arachni/support/mixins.rb +1 -1
  427. data/lib/arachni/support/mixins/observable.rb +1 -1
  428. data/lib/arachni/support/mixins/terminal.rb +1 -1
  429. data/lib/arachni/support/profiler.rb +1 -1
  430. data/lib/arachni/support/signature.rb +1 -1
  431. data/lib/arachni/trainer.rb +8 -1
  432. data/lib/arachni/ui/foo/output.rb +1 -1
  433. data/lib/arachni/uri.rb +79 -57
  434. data/lib/arachni/uri/scope.rb +17 -6
  435. data/lib/arachni/utilities.rb +8 -3
  436. data/lib/arachni/version.rb +1 -1
  437. data/lib/arachni/watir/element.rb +22 -1
  438. data/lib/version +1 -1
  439. data/spec/arachni/browser/element_locator_spec.rb +38 -1
  440. data/spec/arachni/browser/javascript/dom_monitor_spec.rb +21 -6
  441. data/spec/arachni/browser/javascript/taint_tracer_spec.rb +351 -216
  442. data/spec/arachni/browser/javascript_spec.rb +26 -6
  443. data/spec/arachni/browser_spec.rb +205 -53
  444. data/spec/arachni/check/auditor_spec.rb +36 -12
  445. data/spec/arachni/element/capabilities/analyzable/differential_spec.rb +84 -42
  446. data/spec/arachni/element/capabilities/analyzable/taint_spec.rb +2 -0
  447. data/spec/arachni/element/capabilities/analyzable/timeout_spec.rb +87 -19
  448. data/spec/arachni/element/capabilities/with_scope/scope_spec.rb +9 -0
  449. data/spec/arachni/element/cookie/dom_spec.rb +2 -2
  450. data/spec/arachni/element/cookie_spec.rb +28 -7
  451. data/spec/arachni/element/form/dom_spec.rb +2 -2
  452. data/spec/arachni/element/form_spec.rb +39 -7
  453. data/spec/arachni/element/generic_dom_spec.rb +13 -6
  454. data/spec/arachni/element/header_spec.rb +2 -2
  455. data/spec/arachni/element/json_spec.rb +522 -0
  456. data/spec/arachni/element/link/dom_spec.rb +2 -2
  457. data/spec/arachni/element/link_spec.rb +12 -12
  458. data/spec/arachni/element/link_template/dom_spec.rb +1 -1
  459. data/spec/arachni/element/link_template_spec.rb +13 -13
  460. data/spec/arachni/element/server_spec.rb +50 -8
  461. data/spec/arachni/element/xml_spec.rb +247 -0
  462. data/spec/arachni/framework/parts/audit_spec.rb +13 -6
  463. data/spec/arachni/framework/parts/browser_spec.rb +276 -10
  464. data/spec/arachni/framework/parts/state_spec.rb +20 -2
  465. data/spec/arachni/http/client/dynamic_404_handlers_spec.rb +274 -0
  466. data/spec/arachni/http/client_spec.rb +4 -241
  467. data/spec/arachni/http/proxy_server_spec.rb +8 -0
  468. data/spec/arachni/http/request_spec.rb +129 -1
  469. data/spec/arachni/http/response_spec.rb +20 -0
  470. data/spec/arachni/issue_spec.rb +3 -3
  471. data/spec/arachni/option_groups/audit_spec.rb +32 -0
  472. data/spec/arachni/option_groups/http_spec.rb +70 -4
  473. data/spec/arachni/options_spec.rb +6 -6
  474. data/spec/arachni/page_spec.rb +89 -1
  475. data/spec/arachni/report_spec.rb +17 -0
  476. data/spec/arachni/session_spec.rb +3 -14
  477. data/spec/arachni/trainer_spec.rb +24 -5
  478. data/spec/arachni/uri/scope_spec.rb +97 -7
  479. data/spec/arachni/uri_spec.rb +41 -0
  480. data/spec/arachni/utilities_spec.rb +2 -1
  481. data/spec/components/checks/active/code_injection_spec.rb +47 -7
  482. data/spec/components/checks/active/code_injection_timing_spec.rb +4 -2
  483. data/spec/components/checks/active/file_inclusion_spec.rb +16 -6
  484. data/spec/components/checks/active/ldap_injection_spec.rb +13 -4
  485. data/spec/components/checks/active/no_sql_injection_spec.rb +4 -2
  486. data/spec/components/checks/active/os_cmd_injection_spec.rb +15 -11
  487. data/spec/components/checks/active/os_cmd_injection_timing_spec.rb +4 -2
  488. data/spec/components/checks/active/path_traversal_spec.rb +11 -5
  489. data/spec/components/checks/active/response_splitting_spec.rb +4 -2
  490. data/spec/components/checks/active/rfi_spec.rb +5 -2
  491. data/spec/components/checks/active/source_code_disclosure_spec.rb +6 -4
  492. data/spec/components/checks/active/sql_injection_spec.rb +52 -26
  493. data/spec/components/checks/active/sql_injection_timing_spec.rb +29 -5
  494. data/spec/components/checks/active/unvalidated_redirect_dom_spec.rb +19 -0
  495. data/spec/components/checks/active/unvalidated_redirect_spec.rb +5 -2
  496. data/spec/components/checks/active/xpath_injection_spec.rb +11 -3
  497. data/spec/components/checks/active/xss_dom_script_context_spec.rb +4 -4
  498. data/spec/components/checks/active/xss_script_context_spec.rb +5 -5
  499. data/spec/components/checks/active/xss_tag_spec.rb +1 -1
  500. data/spec/components/checks/active/xxe_spec.rb +19 -0
  501. data/spec/components/checks/passive/grep/hsts_spec.rb +10 -2
  502. data/spec/components/checks/passive/grep/insecure_cors_policy_spec.rb +25 -0
  503. data/spec/components/checks/passive/grep/x_frame_options_spec.rb +25 -0
  504. data/spec/components/checks/passive/insecure_client_access_policy_spec.rb +15 -0
  505. data/spec/components/checks/passive/insecure_cross_domain_policy_access_spec.rb +15 -0
  506. data/spec/components/checks/passive/insecure_cross_domain_policy_headers_spec.rb +15 -0
  507. data/spec/components/plugins/exec_spec.rb +56 -0
  508. data/spec/components/plugins/headers_collector_spec.rb +126 -0
  509. data/spec/components/plugins/vector_collector_spec.rb +55 -0
  510. data/spec/spec_helper.rb +2 -1
  511. data/spec/support/factories/element/form.rb +1 -1
  512. data/spec/support/factories/element/json.rb +5 -0
  513. data/spec/support/factories/element/link.rb +1 -1
  514. data/spec/support/factories/element/link_template.rb +1 -1
  515. data/spec/support/factories/element/xml.rb +5 -0
  516. data/spec/support/factories/page.rb +11 -2
  517. data/spec/support/fixtures/check_with_invalid_platforms/with_invalid_platforms.rb +1 -1
  518. data/spec/support/fixtures/checks/test.rb +1 -1
  519. data/spec/support/fixtures/checks/test2.rb +1 -1
  520. data/spec/support/fixtures/checks/test3.rb +1 -1
  521. data/spec/support/fixtures/fingerprinters/test.rb +1 -1
  522. data/spec/support/fixtures/plugins/bad.rb +1 -1
  523. data/spec/support/fixtures/plugins/defaults/default.rb +1 -1
  524. data/spec/support/fixtures/plugins/distributable.rb +1 -1
  525. data/spec/support/fixtures/plugins/loop.rb +1 -1
  526. data/spec/support/fixtures/plugins/suspendable.rb +1 -1
  527. data/spec/support/fixtures/plugins/wait.rb +1 -1
  528. data/spec/support/fixtures/plugins/with_options.rb +1 -1
  529. data/spec/support/fixtures/plugins_with_priorities/p0.rb +1 -1
  530. data/spec/support/fixtures/plugins_with_priorities/p00.rb +1 -1
  531. data/spec/support/fixtures/plugins_with_priorities/p1.rb +1 -1
  532. data/spec/support/fixtures/plugins_with_priorities/p2.rb +1 -1
  533. data/spec/support/fixtures/plugins_with_priorities/p22.rb +1 -1
  534. data/spec/support/fixtures/plugins_with_priorities/p222.rb +1 -1
  535. data/spec/support/fixtures/plugins_with_priorities/p_nil.rb +1 -1
  536. data/spec/support/fixtures/plugins_with_priorities/p_nil2.rb +1 -1
  537. data/spec/support/fixtures/report.afr +0 -0
  538. data/spec/support/fixtures/reporters/base_spec/plugin_formatters/with_formatters/foobar.rb +1 -1
  539. data/spec/support/fixtures/reporters/base_spec/with_formatters.rb +1 -1
  540. data/spec/support/fixtures/reporters/base_spec/with_outfile.rb +1 -1
  541. data/spec/support/fixtures/reporters/base_spec/without_outfile.rb +1 -1
  542. data/spec/support/fixtures/reporters/manager_spec/afr.rb +1 -1
  543. data/spec/support/fixtures/reporters/manager_spec/foo.rb +1 -1
  544. data/spec/support/fixtures/run_check/body.rb +1 -1
  545. data/spec/support/fixtures/run_check/cookies.rb +1 -1
  546. data/spec/support/fixtures/run_check/empty.rb +1 -1
  547. data/spec/support/fixtures/run_check/flch.rb +1 -1
  548. data/spec/support/fixtures/run_check/forms.rb +1 -1
  549. data/spec/support/fixtures/run_check/headers.rb +1 -1
  550. data/spec/support/fixtures/run_check/links.rb +1 -1
  551. data/spec/support/fixtures/run_check/nil.rb +1 -1
  552. data/spec/support/fixtures/run_check/path.rb +1 -1
  553. data/spec/support/fixtures/run_check/server.rb +1 -1
  554. data/spec/support/fixtures/taint_check/taint.rb +1 -1
  555. data/spec/support/fixtures/wait_check/wait.rb +1 -1
  556. data/spec/support/helpers/framework.rb +1 -1
  557. data/spec/support/helpers/misc.rb +1 -1
  558. data/spec/support/helpers/pages.rb +23 -14
  559. data/spec/support/helpers/paths.rb +1 -1
  560. data/spec/support/helpers/requires.rb +1 -1
  561. data/spec/support/helpers/resets.rb +1 -1
  562. data/spec/support/helpers/web_server.rb +1 -1
  563. data/spec/support/lib/factory.rb +1 -1
  564. data/spec/support/lib/web_server_client.rb +1 -1
  565. data/spec/support/lib/web_server_dispatcher.rb +1 -1
  566. data/spec/support/lib/web_server_manager.rb +1 -1
  567. data/spec/support/servers/arachni/browser.rb +77 -3
  568. data/spec/support/servers/arachni/browser/javascript/angular-1.2.8.js +1 -1
  569. data/spec/support/servers/arachni/browser/javascript/angular-route.js +1 -1
  570. data/spec/support/servers/arachni/browser/javascript/dom_monitor.rb +24 -1
  571. data/spec/support/servers/arachni/browser/javascript/jquery.cookie.js +117 -0
  572. data/spec/support/servers/arachni/browser/javascript/taint_tracer.rb +58 -1
  573. data/spec/support/servers/arachni/element/capabilities/analyzable/timeout.rb +6 -0
  574. data/spec/support/servers/arachni/element/json.rb +5 -0
  575. data/spec/support/servers/arachni/element/xml.rb +5 -0
  576. data/spec/support/servers/arachni/http/client.rb +0 -22
  577. data/spec/support/servers/arachni/http/client/dynamic_404_handler.rb +47 -0
  578. data/spec/support/servers/arachni/trainer.rb +10 -0
  579. data/spec/support/servers/checks/active/code_injection.rb +69 -42
  580. data/spec/support/servers/checks/active/code_injection_timing.rb +115 -0
  581. data/spec/support/servers/checks/active/file_inclusion.rb +117 -2
  582. data/spec/support/servers/checks/active/ldap_injection.rb +114 -0
  583. data/spec/support/servers/checks/active/no_sql_injection.rb +81 -0
  584. data/spec/support/servers/checks/active/os_cmd_injection.rb +116 -0
  585. data/spec/support/servers/checks/active/os_cmd_injection_timing.rb +77 -5
  586. data/spec/support/servers/checks/active/path_traversal.rb +154 -2
  587. data/spec/support/servers/checks/active/response_splitting.rb +117 -0
  588. data/spec/support/servers/checks/active/rfi.rb +117 -0
  589. data/spec/support/servers/checks/active/source_code_disclosure.rb +109 -0
  590. data/spec/support/servers/checks/active/sql_injection.rb +125 -0
  591. data/spec/support/servers/checks/active/sql_injection_timing.rb +114 -0
  592. data/spec/support/servers/checks/active/unvalidated_redirect.rb +117 -1
  593. data/spec/support/servers/checks/active/unvalidated_redirect_dom.rb +115 -0
  594. data/spec/support/servers/checks/active/xpath_injection.rb +117 -0
  595. data/spec/support/servers/checks/active/xss_script_context.rb +16 -32
  596. data/spec/support/servers/checks/active/xss_tag.rb +12 -12
  597. data/spec/support/servers/checks/active/xxe.rb +85 -0
  598. data/spec/support/servers/checks/passive/grep/insecure_cors_policy.rb +8 -0
  599. data/spec/support/servers/checks/passive/grep/x_frame_options.rb +9 -0
  600. data/spec/support/servers/checks/passive/insecure_client_access_policy.rb +9 -0
  601. data/spec/support/servers/checks/passive/insecure_cross_domain_policy_access.rb +13 -0
  602. data/spec/support/servers/checks/passive/insecure_cross_domain_policy_headers.rb +13 -0
  603. data/spec/support/servers/plugins/headers_collector.rb +16 -0
  604. data/spec/support/servers/plugins/vector_collector.rb +13 -0
  605. data/spec/support/shared/check.rb +6 -1
  606. data/spec/support/shared/element/base.rb +16 -9
  607. data/spec/support/shared/element/capabilities/auditable.rb +22 -15
  608. data/spec/support/shared/element/capabilities/auditable/dom.rb +7 -14
  609. data/spec/support/shared/element/capabilities/inputtable.rb +46 -61
  610. data/spec/support/shared/element/capabilities/mutable.rb +159 -64
  611. data/spec/support/shared/element/capabilities/with_dom.rb +52 -3
  612. data/spec/support/shared/element/capabilities/with_node.rb +2 -44
  613. data/spec/support/shared/element/capabilities/with_scope.rb +1 -1
  614. data/spec/support/shared/element/capabilities/with_source.rb +55 -0
  615. data/ui/cli/framework.rb +9 -9
  616. data/ui/cli/framework/option_parser.rb +75 -3
  617. data/ui/cli/option_parser.rb +1 -1
  618. data/ui/cli/output.rb +1 -1
  619. data/ui/cli/reporter.rb +1 -1
  620. data/ui/cli/reporter/option_parser.rb +1 -1
  621. data/ui/cli/restored_framework.rb +1 -1
  622. data/ui/cli/restored_framework/option_parser.rb +1 -1
  623. data/ui/cli/rpc/client/dispatcher_monitor.rb +1 -1
  624. data/ui/cli/rpc/client/dispatcher_monitor/option_parser.rb +1 -1
  625. data/ui/cli/rpc/client/instance.rb +5 -4
  626. data/ui/cli/rpc/client/local.rb +1 -1
  627. data/ui/cli/rpc/client/local/option_parser.rb +1 -1
  628. data/ui/cli/rpc/client/remote.rb +1 -1
  629. data/ui/cli/rpc/client/remote/option_parser.rb +1 -1
  630. data/ui/cli/rpc/server/dispatcher.rb +1 -1
  631. data/ui/cli/rpc/server/dispatcher/option_parser.rb +1 -1
  632. data/ui/cli/utilities.rb +4 -1
  633. metadata +129 -19
  634. data/lib/arachni/nokogiri/xml/node.rb +0 -42
@@ -1,5 +1,5 @@
1
1
  =begin
2
- Copyright 2010-2014 Tasos Laskos <tasos.laskos@arachni-scanner.com>
2
+ Copyright 2010-2015 Tasos Laskos <tasos.laskos@arachni-scanner.com>
3
3
 
4
4
  This file is part of the Arachni Framework project and is subject to
5
5
  redistribution and commercial restrictions. Please see the Arachni Framework
@@ -96,18 +96,22 @@ class Scope < Arachni::Scope
96
96
  # @note Will decrease the redundancy counter.
97
97
  # @note Will first check with {#auto_redundant?}.
98
98
  #
99
+ # @param [Bool] update_counters
100
+ # Whether or not to decrement the counters if `self` is redundant.
101
+ #
99
102
  # @return [Bool]
100
103
  # `true` if the URL is redundant, `false` otherwise.
101
104
  #
102
105
  # @see OptionGroups::Scope#redundant_path_patterns
103
- def redundant?
104
- return true if auto_redundant?
106
+ def redundant?( update_counters = false )
107
+ return true if auto_redundant?( update_counters )
105
108
  url_string = @url.to_s
106
109
 
107
110
  options.redundant_path_patterns.each do |regexp, count|
108
111
  next if !(url_string =~ regexp)
109
112
  return true if count == 0
110
113
 
114
+ next if !update_counters
111
115
  options.redundant_path_patterns[regexp] -= 1
112
116
  end
113
117
 
@@ -116,21 +120,28 @@ class Scope < Arachni::Scope
116
120
 
117
121
  # @note Will decrease the redundancy counter.
118
122
  #
123
+ # @param [Bool] update_counters
124
+ # Whether or not to increment the counters if `self` is redundant.
125
+ #
119
126
  # @return [Bool]
120
127
  # `true` if the URL is redundant based on {OptionGroups::Scope#auto_redundant_paths},
121
128
  # `false` otherwise.
122
129
  #
123
130
  # @see OptionGroups::Scope#auto_redundant_paths
124
- def auto_redundant?
131
+ def auto_redundant?( update_counters = false )
125
132
  return false if !options.auto_redundant?
133
+ return false if (params = @url.query_parameters).empty?
126
134
 
127
- h = "#{@url.without_query}#{@url.query_parameters.keys.sort}".hash
135
+ h = "#{@url.without_query}#{params.keys.sort}".hash
128
136
 
129
137
  if options.auto_redundant_counter[h] >= options.auto_redundant_paths
130
138
  return true
131
139
  end
132
140
 
133
- options.auto_redundant_counter[h] += 1
141
+ if update_counters
142
+ options.auto_redundant_counter[h] += 1
143
+ end
144
+
134
145
  false
135
146
  end
136
147
 
@@ -1,5 +1,5 @@
1
1
  =begin
2
- Copyright 2010-2014 Tasos Laskos <tasos.laskos@arachni-scanner.com>
2
+ Copyright 2010-2015 Tasos Laskos <tasos.laskos@arachni-scanner.com>
3
3
 
4
4
  This file is part of the Arachni Framework project and is subject to
5
5
  redistribution and commercial restrictions. Please see the Arachni Framework
@@ -158,6 +158,11 @@ module Utilities
158
158
  URI.normalize( url )
159
159
  end
160
160
 
161
+ # @see URI.full_and_absolute?
162
+ def full_and_absolute_url?( url )
163
+ Arachni::URI.full_and_absolute?( url.to_s )
164
+ end
165
+
161
166
  # @param [String] url
162
167
  #
163
168
  # @return [String] path
@@ -227,8 +232,8 @@ module Utilities
227
232
  # `true` if the `url` is redundant, `false` otherwise.
228
233
  #
229
234
  # @see OptionGroups::Scope#redundant_path_patterns?
230
- def redundant_path?( url )
231
- uri_parse( url ).scope.redundant?
235
+ def redundant_path?( url, update_counters = false )
236
+ uri_parse( url ).scope.redundant?( update_counters )
232
237
  end
233
238
 
234
239
  #
@@ -1,5 +1,5 @@
1
1
  =begin
2
- Copyright 2010-2014 Tasos Laskos <tasos.laskos@arachni-scanner.com>
2
+ Copyright 2010-2015 Tasos Laskos <tasos.laskos@arachni-scanner.com>
3
3
 
4
4
  This file is part of the Arachni Framework project and is subject to
5
5
  redistribution and commercial restrictions. Please see the Arachni Framework
@@ -1,5 +1,5 @@
1
1
  =begin
2
- Copyright 2010-2014 Tasos Laskos <tasos.laskos@arachni-scanner.com>
2
+ Copyright 2010-2015 Tasos Laskos <tasos.laskos@arachni-scanner.com>
3
3
 
4
4
  This file is part of the Arachni Framework project and is subject to
5
5
  redistribution and commercial restrictions. Please see the Arachni Framework
@@ -13,5 +13,26 @@ class Element
13
13
  html.match( /<#{tag_name}.*?>/im )[0]
14
14
  end
15
15
 
16
+ def events
17
+ (browser.execute_script( 'return arguments[0].events;', self ) || []).
18
+ map { |event, fn| [event.to_sym, fn] } |
19
+ (::Arachni::Browser::Javascript.events.flatten.map(&:to_s) & attributes).
20
+ map { |event| [event.to_sym, attribute_value( event )] }
21
+ end
22
+
23
+ def attributes
24
+ browser.execute_script(
25
+ %Q[
26
+ var s = [];
27
+ var attrs = arguments[0].attributes;
28
+ for( var l = 0; l < attrs.length; ++l ) {
29
+ s.push( attrs[l].name );
30
+ }
31
+ return s;
32
+ ],
33
+ self
34
+ )
35
+ end
36
+
16
37
  end
17
38
  end
@@ -1 +1 @@
1
- 1.0.6
1
+ 1.1
@@ -95,7 +95,7 @@ describe Arachni::Browser::ElementLocator do
95
95
 
96
96
  l = described_class.new( tag_name: :a, attributes: { href: '#stuff'} )
97
97
  element = l.locate( browser )
98
- element.should be_kind_of Watir::Anchor
98
+ element.should be_kind_of Watir::HTMLElement
99
99
  element.exists?.should be_true
100
100
  end
101
101
 
@@ -107,6 +107,37 @@ describe Arachni::Browser::ElementLocator do
107
107
  end
108
108
  end
109
109
 
110
+ describe '#css' do
111
+ context 'when there are no attributes' do
112
+ it 'returns a CSS locator with just the tag name' do
113
+ described_class.new( tag_name: :a ).css.should == 'a'
114
+ end
115
+ end
116
+
117
+ context 'when there is an attribute' do
118
+ it 'returns a CSS locator with the attribute' do
119
+ described_class.new(
120
+ tag_name: :a,
121
+ attributes: {
122
+ stuff: 'blah'
123
+ }
124
+ ).css.should == 'a[stuff="blah"]'
125
+ end
126
+ end
127
+
128
+ context 'when there are multiple attributes' do
129
+ it 'returns a CSS locator with the attributes' do
130
+ described_class.new(
131
+ tag_name: :a,
132
+ attributes: {
133
+ stuff: 'blah',
134
+ stuff2: 'blah2'
135
+ }
136
+ ).css.should == 'a[stuff="blah"][stuff2="blah2"]'
137
+ end
138
+ end
139
+ end
140
+
110
141
  describe '#tag_name=' do
111
142
  it 'sets #tag_name' do
112
143
  l = described_class.new
@@ -170,6 +201,12 @@ describe Arachni::Browser::ElementLocator do
170
201
  end
171
202
  end
172
203
 
204
+ describe '#inspect' do
205
+ it 'is aliased to #to_s' do
206
+ subject.to_s.should == subject.inspect
207
+ end
208
+ end
209
+
173
210
  describe '#to_hash' do
174
211
  it 'converts it to a Hash' do
175
212
  subject.to_hash.should == options
@@ -68,12 +68,27 @@ describe Arachni::Browser::Javascript::DOMMonitor do
68
68
  describe '#digest' do
69
69
  it 'returns a string digest of the current DOM tree' do
70
70
  load '/digest'
71
- subject.digest.should ==
72
- '<HTML><HEAD><SCRIPT src=http://javascript.browser.arachni/tai' +
73
- 'nt_tracer.js><SCRIPT><SCRIPT src=http://javascript.browser.' +
74
- 'arachni/dom_monitor.js><SCRIPT><BODY onload=void();><DIV ' +
75
- 'id=my-id-div><DIV class=my-class-div><STRONG><EM><I><B>' +
76
- '<STRONG><SCRIPT><A href=#stuff>'
71
+ subject.digest.should == '<HTML><HEAD><SCRIPT src=http://javascri' <<
72
+ 'pt.browser.arachni/' <<'taint_tracer.js><SCRIPT><SCRIPT src' <<
73
+ '=http://javascript.browser.arachni/dom_monitor.js><SCRIPT>' <<
74
+ '<BODY onload=void();><DIV id=my-id-div><DIV class=my-class' <<
75
+ '-div><STRONG><EM><I><B><STRONG><SCRIPT><SCRIPT type=text/' <<
76
+ 'javascript><A href=#stuff>'
77
+ end
78
+
79
+ it 'does not include <p> elements' do
80
+ load '/digest/p'
81
+ subject.digest.should == '<HTML><HEAD><SCRIPT src=http://javascript' <<
82
+ '.browser.arachni/taint_tracer.js><SCRIPT><SCRIPT src=http://' <<
83
+ 'javascript.browser.arachni/dom_monitor.js><SCRIPT><BODY><STRONG>'
84
+ end
85
+
86
+ it "does not include 'data-arachni-id' attributes" do
87
+ load '/digest/data-arachni-id'
88
+ subject.digest.should == '<HTML><HEAD><SCRIPT src=http://javascript' <<
89
+ '.browser.arachni/taint_tracer.js><SCRIPT><SCRIPT src=http://' <<
90
+ 'javascript.browser.arachni/dom_monitor.js><SCRIPT><BODY><DIV ' <<
91
+ 'id=my-id-div><DIV class=my-class-div>'
77
92
  end
78
93
  end
79
94
 
@@ -22,7 +22,7 @@ describe Arachni::Browser::Javascript::TaintTracer do
22
22
  end
23
23
 
24
24
  subject { @taint_tracer }
25
- let(:taint) { 'my_taint' }
25
+ let(:taint) { @browser.generate_token }
26
26
 
27
27
  after( :each ) do
28
28
  @browser.shutdown
@@ -52,20 +52,93 @@ describe Arachni::Browser::Javascript::TaintTracer do
52
52
  subject.execution_flow_sinks.should be_any
53
53
  end
54
54
 
55
- describe '#taint=' do
56
- it 'sets the taint to be traced' do
57
- subject.taint = taint
58
- subject.taint.should == taint
55
+ describe '#taints=' do
56
+ it 'sets the taints to be traced' do
57
+ subject.taints = [taint]
58
+ subject.taints.should == [taint]
59
+ end
60
+
61
+ context 'when multiple taints are set' do
62
+ it 'logs them in groups' do
63
+ taint1 = 'taint1'
64
+ taint2 = 'taint2'
65
+
66
+ @javascript.custom_code = @taint_tracer.stub.function( :taints=, [taint1, taint2] )
67
+
68
+ load "/data_trace/multiple-taints?taint1=#{taint1}&taint2=#{taint2}"
69
+
70
+ sink = subject.data_flow_sinks[taint1]
71
+ sink.size.should == 2
72
+
73
+ entry = sink[0]
74
+ entry.object.should == 'DOMWindow'
75
+ entry.function.name.should == 'process'
76
+ entry.function.source.should start_with 'function process'
77
+ entry.function.arguments.should == [
78
+ {
79
+ 'my_data11' => 'blah11',
80
+ 'input11' => taint1
81
+ }
82
+ ]
83
+ entry.tainted_value.should == taint1
84
+ entry.taint.should == taint1
85
+ @browser.source.split("\n")[entry.trace[0].line-1].should include 'process('
86
+
87
+ entry = sink[1]
88
+ entry.object.should == 'DOMWindow'
89
+ entry.function.name.should == 'process'
90
+ entry.function.source.should start_with 'function process'
91
+ entry.function.arguments.should == [
92
+ {
93
+ 'my_data12' => 'blah12',
94
+ 'input12' => taint1
95
+ }
96
+ ]
97
+ entry.tainted_value.should == taint1
98
+ entry.taint.should == taint1
99
+ @browser.source.split("\n")[entry.trace[0].line-1].should include 'process('
100
+
101
+ sink = subject.data_flow_sinks[taint2]
102
+ sink.size.should == 2
103
+
104
+ entry = sink[0]
105
+ entry.object.should == 'DOMWindow'
106
+ entry.function.name.should == 'process'
107
+ entry.function.source.should start_with 'function process'
108
+ entry.function.arguments.should == [
109
+ {
110
+ 'my_data21' => 'blah21',
111
+ 'input21' => taint2
112
+ }
113
+ ]
114
+ entry.tainted_value.should == taint2
115
+ entry.taint.should == taint2
116
+ @browser.source.split("\n")[entry.trace[0].line].should include 'process('
117
+
118
+ entry = sink[1]
119
+ entry.object.should == 'DOMWindow'
120
+ entry.function.name.should == 'process'
121
+ entry.function.source.should start_with 'function process'
122
+ entry.function.arguments.should == [
123
+ {
124
+ 'my_data22' => 'blah22',
125
+ 'input22' => taint2
126
+ }
127
+ ]
128
+ entry.tainted_value.should == taint2
129
+ entry.taint.should == taint2
130
+ @browser.source.split("\n")[entry.trace[0].line].should include 'process('
131
+ end
59
132
  end
60
133
 
61
134
  context 'when tainted data pass through' do
62
- before { @javascript.taint = @browser.generate_token }
135
+ before { @javascript.taint = taint }
63
136
 
64
137
  context 'user-defined global functions' do
65
138
  it 'logs it' do
66
139
  load_with_taint 'data_trace/user-defined-global-functions'
67
140
 
68
- sink = subject.data_flow_sinks
141
+ sink = subject.data_flow_sinks[taint]
69
142
  sink.size.should == 1
70
143
 
71
144
  entry = sink[0]
@@ -75,31 +148,31 @@ describe Arachni::Browser::Javascript::TaintTracer do
75
148
  entry.function.arguments.should == [
76
149
  {
77
150
  'my_data' => 'blah',
78
- 'input' => @javascript.taint
151
+ 'input' => taint
79
152
  }
80
153
  ]
81
- entry.tainted_value.should == @javascript.taint
82
- entry.taint.should == @javascript.taint
154
+ entry.tainted_value.should == taint
155
+ entry.taint.should == taint
83
156
  @browser.source.split("\n")[entry.trace[0].line-1].should include 'process('
84
157
  end
85
158
  end
86
159
 
87
160
  context 'window' do
88
- %w(encodeURIComponent decodeURIComponent encodeURI decodeURI).each do |function|
161
+ %w(escape unescape encodeURIComponent decodeURIComponent encodeURI decodeURI).each do |function|
89
162
  context ".#{function}" do
90
163
  it 'logs it' do
91
164
  load_with_taint "data_trace/window.#{function}"
92
165
 
93
- sink = subject.data_flow_sinks
166
+ sink = subject.data_flow_sinks[taint]
94
167
  sink.size.should == 1
95
168
 
96
169
  entry = sink[0]
97
170
  entry.object.should == 'DOMWindow'
98
171
  entry.function.name.should == function
99
172
  entry.function.source.should start_with "function #{function}"
100
- entry.function.arguments.should == [ @javascript.taint ]
101
- entry.tainted_value.should == @javascript.taint
102
- entry.taint.should == @javascript.taint
173
+ entry.function.arguments.should == [ taint ]
174
+ entry.tainted_value.should == taint
175
+ entry.taint.should == taint
103
176
  @browser.source.split("\n")[entry.trace[0].line].should include "#{function}("
104
177
  end
105
178
  end
@@ -111,17 +184,17 @@ describe Arachni::Browser::Javascript::TaintTracer do
111
184
  it 'logs it' do
112
185
  load_with_taint 'data_trace/XMLHttpRequest.open'
113
186
 
114
- sink = subject.data_flow_sinks
187
+ sink = subject.data_flow_sinks[taint]
115
188
  sink.size.should == 1
116
189
 
117
190
  entry = sink[0]
118
191
  entry.object.should == 'XMLHttpRequestPrototype'
119
192
  entry.function.name.should == 'open'
120
193
  entry.function.arguments.should == [
121
- 'GET', "/?taint=#{@javascript.taint}", true
194
+ 'GET', "/?taint=#{taint}", true
122
195
  ]
123
- entry.tainted_value.should == "/?taint=#{@javascript.taint}"
124
- entry.taint.should == @javascript.taint
196
+ entry.tainted_value.should == "/?taint=#{taint}"
197
+ entry.taint.should == taint
125
198
 
126
199
  trace = entry.trace[0]
127
200
  @browser.source.split("\n")[trace.line].should include 'open('
@@ -133,15 +206,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
133
206
  it 'logs it' do
134
207
  load_with_taint 'data_trace/XMLHttpRequest.send'
135
208
 
136
- sink = subject.data_flow_sinks
209
+ sink = subject.data_flow_sinks[taint]
137
210
  sink.size.should == 1
138
211
 
139
212
  entry = sink[0]
140
213
  entry.object.should == 'XMLHttpRequestPrototype'
141
214
  entry.function.name.should == 'send'
142
- entry.function.arguments.should == [ "taint=#{@javascript.taint}" ]
143
- entry.tainted_value.should == "taint=#{@javascript.taint}"
144
- entry.taint.should == @javascript.taint
215
+ entry.function.arguments.should == [ "taint=#{taint}" ]
216
+ entry.tainted_value.should == "taint=#{taint}"
217
+ entry.taint.should == taint
145
218
 
146
219
  trace = entry.trace[0]
147
220
  @browser.source.split("\n")[trace.line].should include 'send('
@@ -153,15 +226,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
153
226
  it 'logs it' do
154
227
  load_with_taint 'data_trace/XMLHttpRequest.setRequestHeader'
155
228
 
156
- sink = subject.data_flow_sinks
229
+ sink = subject.data_flow_sinks[taint]
157
230
  sink.size.should == 1
158
231
 
159
232
  entry = sink[0]
160
233
  entry.object.should == 'XMLHttpRequestPrototype'
161
234
  entry.function.name.should == 'setRequestHeader'
162
- entry.function.arguments.should == [ 'X-My-Header', "stuff-#{@javascript.taint}" ]
163
- entry.tainted_value.should == "stuff-#{@javascript.taint}"
164
- entry.taint.should == @javascript.taint
235
+ entry.function.arguments.should == [ 'X-My-Header', "stuff-#{taint}" ]
236
+ entry.tainted_value.should == "stuff-#{taint}"
237
+ entry.taint.should == taint
165
238
 
166
239
  trace = entry.trace[0]
167
240
  @browser.source.split("\n")[trace.line].should include 'setRequestHeader('
@@ -175,15 +248,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
175
248
  it 'logs it' do
176
249
  load_with_taint 'data_trace/AngularJS.element'
177
250
 
178
- sink = subject.data_flow_sinks
251
+ sink = subject.data_flow_sinks[taint]
179
252
  sink.size.should == 2
180
253
 
181
254
  entry = sink[1]
182
255
  entry.object.should == 'angular'
183
256
  entry.function.name.should == 'JQLite'
184
- entry.function.arguments.should == ["<div>Stuff #{@javascript.taint}</div>"]
185
- entry.tainted_value.should == "<div>Stuff #{@javascript.taint}</div>"
186
- entry.taint.should == @javascript.taint
257
+ entry.function.arguments.should == ["<div>Stuff #{taint}</div>"]
258
+ entry.tainted_value.should == "<div>Stuff #{taint}</div>"
259
+ entry.taint.should == taint
187
260
 
188
261
  trace = entry.trace[0]
189
262
  @browser.source.split("\n")[trace.line].should include 'angular.element('
@@ -196,25 +269,25 @@ describe Arachni::Browser::Javascript::TaintTracer do
196
269
  it 'logs it' do
197
270
  load_with_taint 'data_trace/AngularJS/$http.delete'
198
271
 
199
- sink = subject.data_flow_sinks
272
+ sink = subject.data_flow_sinks[taint]
200
273
  sink.size.should == 4
201
274
 
202
275
  entry = sink[1]
203
276
  entry.object.should == 'angular.$http'
204
277
  entry.function.name.should == 'delete'
205
- entry.function.arguments.should == [ "/#{@javascript.taint}" ]
206
- entry.tainted_value.should == "/#{@javascript.taint}"
207
- entry.taint.should == @javascript.taint
278
+ entry.function.arguments.should == [ "/#{taint}" ]
279
+ entry.tainted_value.should == "/#{taint}"
280
+ entry.taint.should == taint
208
281
  entry.trace[0].url.should == @browser.url
209
282
 
210
283
  entry = sink[3]
211
284
  entry.object.should == 'XMLHttpRequestPrototype'
212
285
  entry.function.name.should == 'open'
213
286
  entry.function.arguments.should == [
214
- 'DELETE', "/#{@javascript.taint}", true
287
+ 'DELETE', "/#{taint}", true
215
288
  ]
216
- entry.tainted_value.should == "/#{@javascript.taint}"
217
- entry.taint.should == @javascript.taint
289
+ entry.tainted_value.should == "/#{taint}"
290
+ entry.taint.should == taint
218
291
  entry.trace[0].url.should == "#{@url}angular.js"
219
292
  end
220
293
  end
@@ -223,25 +296,25 @@ describe Arachni::Browser::Javascript::TaintTracer do
223
296
  it 'logs it' do
224
297
  load_with_taint 'data_trace/AngularJS/$http.head'
225
298
 
226
- sink = subject.data_flow_sinks
299
+ sink = subject.data_flow_sinks[taint]
227
300
  sink.size.should == 4
228
301
 
229
302
  entry = sink[1]
230
303
  entry.object.should == 'angular.$http'
231
304
  entry.function.name.should == 'head'
232
- entry.function.arguments.should == [ "/#{@javascript.taint}" ]
233
- entry.tainted_value.should == "/#{@javascript.taint}"
234
- entry.taint.should == @javascript.taint
305
+ entry.function.arguments.should == [ "/#{taint}" ]
306
+ entry.tainted_value.should == "/#{taint}"
307
+ entry.taint.should == taint
235
308
  entry.trace[0].url.should == @browser.url
236
309
 
237
310
  entry = sink[3]
238
311
  entry.object.should == 'XMLHttpRequestPrototype'
239
312
  entry.function.name.should == 'open'
240
313
  entry.function.arguments.should == [
241
- 'HEAD', "/#{@javascript.taint}", true
314
+ 'HEAD', "/#{taint}", true
242
315
  ]
243
- entry.tainted_value.should == "/#{@javascript.taint}"
244
- entry.taint.should == @javascript.taint
316
+ entry.tainted_value.should == "/#{taint}"
317
+ entry.taint.should == taint
245
318
  entry.trace[0].url.should == "#{@url}angular.js"
246
319
  end
247
320
  end
@@ -250,25 +323,25 @@ describe Arachni::Browser::Javascript::TaintTracer do
250
323
  it 'logs it' do
251
324
  load_with_taint 'data_trace/AngularJS/$http.jsonp'
252
325
 
253
- sink = subject.data_flow_sinks
326
+ sink = subject.data_flow_sinks[taint]
254
327
  sink.size.should == 3
255
328
 
256
329
  entry = sink[1]
257
330
  entry.object.should == 'angular.$http'
258
331
  entry.function.name.should == 'jsonp'
259
- entry.function.arguments.should == [ "/jsonp-#{@javascript.taint}" ]
260
- entry.tainted_value.should == "/jsonp-#{@javascript.taint}"
261
- entry.taint.should == @javascript.taint
332
+ entry.function.arguments.should == [ "/jsonp-#{taint}" ]
333
+ entry.tainted_value.should == "/jsonp-#{taint}"
334
+ entry.taint.should == taint
262
335
  entry.trace[0].url.should == @browser.url
263
336
 
264
337
  entry = sink[2]
265
338
  entry.object.should == 'ElementPrototype'
266
339
  entry.function.name.should == 'setAttribute'
267
340
  entry.function.arguments.should == [
268
- 'href', "/jsonp-#{@javascript.taint}"
341
+ 'href', "/jsonp-#{taint}"
269
342
  ]
270
- entry.tainted_value.should == "/jsonp-#{@javascript.taint}"
271
- entry.taint.should == @javascript.taint
343
+ entry.tainted_value.should == "/jsonp-#{taint}"
344
+ entry.taint.should == taint
272
345
  entry.trace[0].url.should == "#{@url}angular.js"
273
346
  end
274
347
  end
@@ -277,25 +350,25 @@ describe Arachni::Browser::Javascript::TaintTracer do
277
350
  it 'logs it' do
278
351
  load_with_taint 'data_trace/AngularJS/$http.put'
279
352
 
280
- sink = subject.data_flow_sinks
353
+ sink = subject.data_flow_sinks[taint]
281
354
  sink.size.should == 3
282
355
 
283
356
  entry = sink[1]
284
357
  entry.object.should == 'angular.$http'
285
358
  entry.function.name.should == 'put'
286
359
  entry.function.arguments.should == [
287
- '/', "Stuff #{@javascript.taint}"
360
+ '/', "Stuff #{taint}"
288
361
  ]
289
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
290
- entry.taint.should == @javascript.taint
362
+ entry.tainted_value.should == "Stuff #{taint}"
363
+ entry.taint.should == taint
291
364
  entry.trace[0].url.should == @browser.url
292
365
 
293
366
  entry = sink[2]
294
367
  entry.object.should == 'XMLHttpRequestPrototype'
295
368
  entry.function.name.should == 'send'
296
- entry.function.arguments.should == [ "Stuff #{@javascript.taint}" ]
297
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
298
- entry.taint.should == @javascript.taint
369
+ entry.function.arguments.should == [ "Stuff #{taint}" ]
370
+ entry.tainted_value.should == "Stuff #{taint}"
371
+ entry.taint.should == taint
299
372
  entry.trace[0].url.should == "#{@url}angular.js"
300
373
  end
301
374
  end
@@ -304,25 +377,25 @@ describe Arachni::Browser::Javascript::TaintTracer do
304
377
  it 'logs it' do
305
378
  load_with_taint 'data_trace/AngularJS/$http.get'
306
379
 
307
- sink = subject.data_flow_sinks
380
+ sink = subject.data_flow_sinks[taint]
308
381
  sink.size.should == 4
309
382
 
310
383
  entry = sink[1]
311
384
  entry.object.should == 'angular.$http'
312
385
  entry.function.name.should == 'get'
313
- entry.function.arguments.should == [ "/#{@javascript.taint}" ]
314
- entry.tainted_value.should == "/#{@javascript.taint}"
315
- entry.taint.should == @javascript.taint
386
+ entry.function.arguments.should == [ "/#{taint}" ]
387
+ entry.tainted_value.should == "/#{taint}"
388
+ entry.taint.should == taint
316
389
  entry.trace[0].url.should == @browser.url
317
390
 
318
391
  entry = sink[3]
319
392
  entry.object.should == 'XMLHttpRequestPrototype'
320
393
  entry.function.name.should == 'open'
321
394
  entry.function.arguments.should == [
322
- 'GET', "/#{@javascript.taint}", true
395
+ 'GET', "/#{taint}", true
323
396
  ]
324
- entry.tainted_value.should == "/#{@javascript.taint}"
325
- entry.taint.should == @javascript.taint
397
+ entry.tainted_value.should == "/#{taint}"
398
+ entry.taint.should == taint
326
399
  entry.trace[0].url.should == "#{@url}angular.js"
327
400
  end
328
401
  end
@@ -331,7 +404,7 @@ describe Arachni::Browser::Javascript::TaintTracer do
331
404
  it 'logs it' do
332
405
  load_with_taint 'data_trace/AngularJS/$http.post'
333
406
 
334
- sink = subject.data_flow_sinks
407
+ sink = subject.data_flow_sinks[taint]
335
408
  sink.size.should == 4
336
409
 
337
410
  entry = sink[1]
@@ -341,25 +414,25 @@ describe Arachni::Browser::Javascript::TaintTracer do
341
414
  '/', '',
342
415
  {
343
416
  'params' => {
344
- 'stuff' => "Stuff #{@javascript.taint}"
417
+ 'stuff' => "Stuff #{taint}"
345
418
  },
346
419
  'method' => 'post',
347
420
  'url' => '/',
348
421
  'data' => ''
349
422
  }
350
423
  ]
351
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
352
- entry.taint.should == @javascript.taint
424
+ entry.tainted_value.should == "Stuff #{taint}"
425
+ entry.taint.should == taint
353
426
  entry.trace[0].url.should == @browser.url
354
427
 
355
428
  entry = sink[3]
356
429
  entry.object.should == 'XMLHttpRequestPrototype'
357
430
  entry.function.name.should == 'open'
358
431
  entry.function.arguments.should == [
359
- 'POST', "/?stuff=Stuff+#{@javascript.taint}", true
432
+ 'POST', "/?stuff=Stuff+#{taint}", true
360
433
  ]
361
- entry.tainted_value.should == "/?stuff=Stuff+#{@javascript.taint}"
362
- entry.taint.should == @javascript.taint
434
+ entry.tainted_value.should == "/?stuff=Stuff+#{taint}"
435
+ entry.taint.should == taint
363
436
  entry.trace[0].url.should == "#{@url}angular.js"
364
437
  end
365
438
  end
@@ -370,28 +443,28 @@ describe Arachni::Browser::Javascript::TaintTracer do
370
443
  it 'logs it' do
371
444
  load_with_taint 'data_trace/AngularJS/ngRoute/'
372
445
 
373
- sink = subject.data_flow_sinks
374
- sink.size.should == 6
446
+ sink = subject.data_flow_sinks[taint]
447
+ sink.size.should == 8
375
448
 
376
449
  # ngRoute module first schedules an HTTP request to grab
377
450
  # the template from the given 'templateUrl'...
378
- entry = sink[4]
451
+ entry = sink[6]
379
452
  entry.object.should == 'XMLHttpRequestPrototype'
380
453
  entry.function.name.should == 'open'
381
454
  entry.function.arguments.should == [
382
- 'GET', "template.html?taint=#{@javascript.taint}", true
455
+ 'GET', "template.html?taint=#{taint}", true
383
456
  ]
384
- entry.tainted_value.should == "template.html?taint=#{@javascript.taint}"
385
- entry.taint.should == @javascript.taint
457
+ entry.tainted_value.should == "template.html?taint=#{taint}"
458
+ entry.taint.should == taint
386
459
  entry.trace[0].url.should == "#{@url}angular.js"
387
460
 
388
461
  #... and then updates the app with the (tainted) template content.
389
- entry = sink[5]
462
+ entry = sink[7]
390
463
  entry.object.should == 'angular.element'
391
464
  entry.function.name.should == 'html'
392
- entry.function.arguments.should == ["Blah blah blah #{@javascript.taint}\n"]
393
- entry.tainted_value.should == "Blah blah blah #{@javascript.taint}\n"
394
- entry.taint.should == @javascript.taint
465
+ entry.function.arguments.should == ["Blah blah blah #{taint}\n"]
466
+ entry.tainted_value.should == "Blah blah blah #{taint}\n"
467
+ entry.taint.should == taint
395
468
  entry.trace[0].url.should == "#{@url}angular-route.js"
396
469
  end
397
470
  end
@@ -402,15 +475,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
402
475
  it 'logs it' do
403
476
  load_with_taint 'data_trace/AngularJS/jqLite.html'
404
477
 
405
- sink = subject.data_flow_sinks
478
+ sink = subject.data_flow_sinks[taint]
406
479
  sink.size.should == 2
407
480
 
408
481
  entry = sink[1]
409
482
  entry.object.should == 'angular.element'
410
483
  entry.function.name.should == 'html'
411
- entry.function.arguments.should == ["Stuff #{@javascript.taint}"]
412
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
413
- entry.taint.should == @javascript.taint
484
+ entry.function.arguments.should == ["Stuff #{taint}"]
485
+ entry.tainted_value.should == "Stuff #{taint}"
486
+ entry.taint.should == taint
414
487
 
415
488
  trace = entry.trace[0]
416
489
  @browser.source.split("\n")[trace.line-1].should include 'html('
@@ -422,15 +495,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
422
495
  it 'logs it' do
423
496
  load_with_taint 'data_trace/AngularJS/jqLite.text'
424
497
 
425
- sink = subject.data_flow_sinks
498
+ sink = subject.data_flow_sinks[taint]
426
499
  sink.size.should == 2
427
500
 
428
501
  entry = sink[1]
429
502
  entry.object.should == 'angular.element'
430
503
  entry.function.name.should == 'text'
431
- entry.function.arguments.should == ["Stuff #{@javascript.taint}"]
432
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
433
- entry.taint.should == @javascript.taint
504
+ entry.function.arguments.should == ["Stuff #{taint}"]
505
+ entry.tainted_value.should == "Stuff #{taint}"
506
+ entry.taint.should == taint
434
507
 
435
508
  trace = entry.trace[0]
436
509
  @browser.source.split("\n")[trace.line-1].should include 'text('
@@ -442,15 +515,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
442
515
  it 'logs it' do
443
516
  load_with_taint 'data_trace/AngularJS/jqLite.append'
444
517
 
445
- sink = subject.data_flow_sinks
518
+ sink = subject.data_flow_sinks[taint]
446
519
  sink.size.should == 2
447
520
 
448
521
  entry = sink[1]
449
522
  entry.object.should == 'angular.element'
450
523
  entry.function.name.should == 'append'
451
- entry.function.arguments.should == ["Stuff #{@javascript.taint}"]
452
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
453
- entry.taint.should == @javascript.taint
524
+ entry.function.arguments.should == ["Stuff #{taint}"]
525
+ entry.tainted_value.should == "Stuff #{taint}"
526
+ entry.taint.should == taint
454
527
 
455
528
  trace = entry.trace[0]
456
529
  @browser.source.split("\n")[trace.line].should include 'append('
@@ -462,15 +535,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
462
535
  it 'logs it' do
463
536
  load_with_taint 'data_trace/AngularJS/jqLite.prepend'
464
537
 
465
- sink = subject.data_flow_sinks
538
+ sink = subject.data_flow_sinks[taint]
466
539
  sink.size.should == 2
467
540
 
468
541
  entry = sink[1]
469
542
  entry.object.should == 'angular.element'
470
543
  entry.function.name.should == 'prepend'
471
- entry.function.arguments.should == ["Stuff #{@javascript.taint}"]
472
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
473
- entry.taint.should == @javascript.taint
544
+ entry.function.arguments.should == ["Stuff #{taint}"]
545
+ entry.tainted_value.should == "Stuff #{taint}"
546
+ entry.taint.should == taint
474
547
 
475
548
  trace = entry.trace[0]
476
549
  @browser.source.split("\n")[trace.line].should include 'prepend('
@@ -482,15 +555,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
482
555
  it 'logs it' do
483
556
  load_with_taint 'data_trace/AngularJS/jqLite.prop'
484
557
 
485
- sink = subject.data_flow_sinks
558
+ sink = subject.data_flow_sinks[taint]
486
559
  sink.size.should == 2
487
560
 
488
561
  entry = sink[1]
489
562
  entry.object.should == 'angular.element'
490
563
  entry.function.name.should == 'prop'
491
- entry.function.arguments.should == [ 'stuff', "Stuff #{@javascript.taint}"]
492
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
493
- entry.taint.should == @javascript.taint
564
+ entry.function.arguments.should == [ 'stuff', "Stuff #{taint}"]
565
+ entry.tainted_value.should == "Stuff #{taint}"
566
+ entry.taint.should == taint
494
567
 
495
568
  trace = entry.trace[0]
496
569
  @browser.source.split("\n")[trace.line].should include 'prop('
@@ -502,15 +575,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
502
575
  it 'logs it' do
503
576
  load_with_taint 'data_trace/AngularJS/jqLite.replaceWith'
504
577
 
505
- sink = subject.data_flow_sinks
578
+ sink = subject.data_flow_sinks[taint]
506
579
  sink.size.should == 2
507
580
 
508
581
  entry = sink[1]
509
582
  entry.object.should == 'angular.element'
510
583
  entry.function.name.should == 'replaceWith'
511
- entry.function.arguments.should == [ "Stuff #{@javascript.taint}"]
512
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
513
- entry.taint.should == @javascript.taint
584
+ entry.function.arguments.should == [ "Stuff #{taint}"]
585
+ entry.tainted_value.should == "Stuff #{taint}"
586
+ entry.taint.should == taint
514
587
 
515
588
  trace = entry.trace[0]
516
589
  @browser.source.split("\n")[trace.line-1].should include 'replaceWith('
@@ -522,15 +595,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
522
595
  it 'logs it' do
523
596
  load_with_taint 'data_trace/AngularJS/jqLite.val'
524
597
 
525
- sink = subject.data_flow_sinks
598
+ sink = subject.data_flow_sinks[taint]
526
599
  sink.size.should == 2
527
600
 
528
601
  entry = sink[1]
529
602
  entry.object.should == 'angular.element'
530
603
  entry.function.name.should == 'val'
531
- entry.function.arguments.should == [ "Stuff #{@javascript.taint}"]
532
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
533
- entry.taint.should == @javascript.taint
604
+ entry.function.arguments.should == [ "Stuff #{taint}"]
605
+ entry.tainted_value.should == "Stuff #{taint}"
606
+ entry.taint.should == taint
534
607
 
535
608
  trace = entry.trace[0]
536
609
  @browser.source.split("\n")[trace.line].should include 'val('
@@ -541,11 +614,31 @@ describe Arachni::Browser::Javascript::TaintTracer do
541
614
  end
542
615
 
543
616
  context 'jQuery' do
617
+ context '.cookie' do
618
+ it 'logs it' do
619
+ load_with_taint 'data_trace/jQuery.cookie'
620
+
621
+ sink = subject.data_flow_sinks[taint]
622
+ sink.size.should == 2
623
+
624
+ entry = sink[0]
625
+ entry.object.should == 'jQuery'
626
+ entry.function.name.should == 'cookie'
627
+ entry.function.arguments.should == ['cname', "mystuff #{taint}"]
628
+ entry.tainted_value.should == "mystuff #{taint}"
629
+ entry.taint.should == taint
630
+
631
+ trace = entry.trace[0]
632
+ @browser.source.split("\n")[trace.line].should include 'cookie('
633
+ trace.url.should == @browser.url
634
+ end
635
+ end
636
+
544
637
  context '.ajax' do
545
638
  it 'logs it' do
546
639
  load_with_taint 'data_trace/jQuery.ajax'
547
640
 
548
- sink = subject.data_flow_sinks
641
+ sink = subject.data_flow_sinks[taint]
549
642
  sink.size.should == 3
550
643
 
551
644
  entry = sink[0]
@@ -555,12 +648,12 @@ describe Arachni::Browser::Javascript::TaintTracer do
555
648
  {
556
649
  'url' => '/',
557
650
  'data' => {
558
- 'stuff' => "mystuff #{@javascript.taint}"
651
+ 'stuff' => "mystuff #{taint}"
559
652
  }
560
653
  }
561
654
  ]
562
- entry.tainted_value.should == "mystuff #{@javascript.taint}"
563
- entry.taint.should == @javascript.taint
655
+ entry.tainted_value.should == "mystuff #{taint}"
656
+ entry.taint.should == taint
564
657
 
565
658
  trace = entry.trace[0]
566
659
  @browser.source.split("\n")[trace.line].should include 'ajax('
@@ -572,7 +665,7 @@ describe Arachni::Browser::Javascript::TaintTracer do
572
665
  it 'logs it' do
573
666
  load_with_taint 'data_trace/jQuery.get'
574
667
 
575
- sink = subject.data_flow_sinks
668
+ sink = subject.data_flow_sinks[taint]
576
669
  sink.size.should == 4
577
670
 
578
671
  entry = sink[0]
@@ -580,10 +673,10 @@ describe Arachni::Browser::Javascript::TaintTracer do
580
673
  entry.function.name.should == 'get'
581
674
  entry.function.arguments.should == [
582
675
  '/',
583
- { 'stuff' => "mystuff #{@javascript.taint}" }
676
+ { 'stuff' => "mystuff #{taint}" }
584
677
  ]
585
- entry.tainted_value.should == "mystuff #{@javascript.taint}"
586
- entry.taint.should == @javascript.taint
678
+ entry.tainted_value.should == "mystuff #{taint}"
679
+ entry.taint.should == taint
587
680
 
588
681
  trace = entry.trace[0]
589
682
  @browser.source.split("\n")[trace.line].should include 'get('
@@ -595,15 +688,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
595
688
  it 'logs it' do
596
689
  load_with_taint 'data_trace/jQuery.post'
597
690
 
598
- sink = subject.data_flow_sinks
691
+ sink = subject.data_flow_sinks[taint]
599
692
  sink.size.should == 3
600
693
 
601
694
  entry = sink[0]
602
695
  entry.object.should == 'jQuery'
603
696
  entry.function.name.should == 'post'
604
- entry.function.arguments.should == [ "/#{@javascript.taint}" ]
605
- entry.tainted_value.should == "/#{@javascript.taint}"
606
- entry.taint.should == @javascript.taint
697
+ entry.function.arguments.should == [ "/#{taint}" ]
698
+ entry.tainted_value.should == "/#{taint}"
699
+ entry.taint.should == taint
607
700
 
608
701
  trace = entry.trace[0]
609
702
  @browser.source.split("\n")[trace.line].should include 'post('
@@ -615,15 +708,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
615
708
  it 'logs it' do
616
709
  load_with_taint 'data_trace/jQuery.load'
617
710
 
618
- sink = subject.data_flow_sinks
711
+ sink = subject.data_flow_sinks[taint]
619
712
  sink.size.should == 3
620
713
 
621
714
  entry = sink[0]
622
715
  entry.object.should == 'jQuery'
623
716
  entry.function.name.should == 'load'
624
- entry.function.arguments.should == [ "/#{@javascript.taint}" ]
625
- entry.tainted_value.should == "/#{@javascript.taint}"
626
- entry.taint.should == @javascript.taint
717
+ entry.function.arguments.should == [ "/#{taint}" ]
718
+ entry.tainted_value.should == "/#{taint}"
719
+ entry.taint.should == taint
627
720
 
628
721
  trace = entry.trace[0]
629
722
  @browser.source.split("\n")[trace.line].should include 'load('
@@ -635,15 +728,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
635
728
  it 'logs it' do
636
729
  load_with_taint 'data_trace/jQuery.html'
637
730
 
638
- sink = subject.data_flow_sinks
731
+ sink = subject.data_flow_sinks[taint]
639
732
  sink.size.should == 1
640
733
 
641
734
  entry = sink[0]
642
735
  entry.object.should == 'jQuery'
643
736
  entry.function.name.should == 'html'
644
- entry.function.arguments.should == ["Stuff #{@javascript.taint}"]
645
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
646
- entry.taint.should == @javascript.taint
737
+ entry.function.arguments.should == ["Stuff #{taint}"]
738
+ entry.tainted_value.should == "Stuff #{taint}"
739
+ entry.taint.should == taint
647
740
 
648
741
  trace = entry.trace[0]
649
742
  @browser.source.split("\n")[trace.line-1].should include 'html('
@@ -655,15 +748,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
655
748
  it 'logs it' do
656
749
  load_with_taint 'data_trace/jQuery.text'
657
750
 
658
- sink = subject.data_flow_sinks
751
+ sink = subject.data_flow_sinks[taint]
659
752
  sink.size.should == 2
660
753
 
661
754
  entry = sink[0]
662
755
  entry.object.should == 'jQuery'
663
756
  entry.function.name.should == 'text'
664
- entry.function.arguments.should == ["Stuff #{@javascript.taint}"]
665
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
666
- entry.taint.should == @javascript.taint
757
+ entry.function.arguments.should == ["Stuff #{taint}"]
758
+ entry.tainted_value.should == "Stuff #{taint}"
759
+ entry.taint.should == taint
667
760
 
668
761
  trace = entry.trace[0]
669
762
  @browser.source.split("\n")[trace.line-1].should include 'text('
@@ -675,15 +768,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
675
768
  it 'logs it' do
676
769
  load_with_taint 'data_trace/jQuery.append'
677
770
 
678
- sink = subject.data_flow_sinks
771
+ sink = subject.data_flow_sinks[taint]
679
772
  sink.size.should == 2
680
773
 
681
774
  entry = sink[0]
682
775
  entry.object.should == 'jQuery'
683
776
  entry.function.name.should == 'append'
684
- entry.function.arguments.should == ["Stuff #{@javascript.taint}"]
685
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
686
- entry.taint.should == @javascript.taint
777
+ entry.function.arguments.should == ["Stuff #{taint}"]
778
+ entry.tainted_value.should == "Stuff #{taint}"
779
+ entry.taint.should == taint
687
780
 
688
781
  trace = entry.trace[0]
689
782
  @browser.source.split("\n")[trace.line].should include 'append('
@@ -695,15 +788,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
695
788
  it 'logs it' do
696
789
  load_with_taint 'data_trace/jQuery.prepend'
697
790
 
698
- sink = subject.data_flow_sinks
791
+ sink = subject.data_flow_sinks[taint]
699
792
  sink.size.should == 2
700
793
 
701
794
  entry = sink[0]
702
795
  entry.object.should == 'jQuery'
703
796
  entry.function.name.should == 'prepend'
704
- entry.function.arguments.should == ["Stuff #{@javascript.taint}"]
705
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
706
- entry.taint.should == @javascript.taint
797
+ entry.function.arguments.should == ["Stuff #{taint}"]
798
+ entry.tainted_value.should == "Stuff #{taint}"
799
+ entry.taint.should == taint
707
800
 
708
801
  trace = entry.trace[0]
709
802
  @browser.source.split("\n")[trace.line].should include 'prepend('
@@ -715,15 +808,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
715
808
  it 'logs it' do
716
809
  load_with_taint 'data_trace/jQuery.before'
717
810
 
718
- sink = subject.data_flow_sinks
811
+ sink = subject.data_flow_sinks[taint]
719
812
  sink.size.should == 2
720
813
 
721
814
  entry = sink[0]
722
815
  entry.object.should == 'jQuery'
723
816
  entry.function.name.should == 'before'
724
- entry.function.arguments.should == ["Stuff #{@javascript.taint}"]
725
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
726
- entry.taint.should == @javascript.taint
817
+ entry.function.arguments.should == ["Stuff #{taint}"]
818
+ entry.tainted_value.should == "Stuff #{taint}"
819
+ entry.taint.should == taint
727
820
 
728
821
  trace = entry.trace[0]
729
822
  @browser.source.split("\n")[trace.line].should include 'before('
@@ -735,15 +828,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
735
828
  it 'logs it' do
736
829
  load_with_taint 'data_trace/jQuery.prop'
737
830
 
738
- sink = subject.data_flow_sinks
831
+ sink = subject.data_flow_sinks[taint]
739
832
  sink.size.should == 1
740
833
 
741
834
  entry = sink[0]
742
835
  entry.object.should == 'jQuery'
743
836
  entry.function.name.should == 'prop'
744
- entry.function.arguments.should == [ 'stuff', "Stuff #{@javascript.taint}"]
745
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
746
- entry.taint.should == @javascript.taint
837
+ entry.function.arguments.should == [ 'stuff', "Stuff #{taint}"]
838
+ entry.tainted_value.should == "Stuff #{taint}"
839
+ entry.taint.should == taint
747
840
 
748
841
  trace = entry.trace[0]
749
842
  @browser.source.split("\n")[trace.line].should include 'prop('
@@ -755,15 +848,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
755
848
  it 'logs it' do
756
849
  load_with_taint 'data_trace/jQuery.replaceWith'
757
850
 
758
- sink = subject.data_flow_sinks
851
+ sink = subject.data_flow_sinks[taint]
759
852
  sink.size.should == 2
760
853
 
761
854
  entry = sink[0]
762
855
  entry.object.should == 'jQuery'
763
856
  entry.function.name.should == 'replaceWith'
764
- entry.function.arguments.should == [ "Stuff #{@javascript.taint}"]
765
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
766
- entry.taint.should == @javascript.taint
857
+ entry.function.arguments.should == [ "Stuff #{taint}"]
858
+ entry.tainted_value.should == "Stuff #{taint}"
859
+ entry.taint.should == taint
767
860
 
768
861
  trace = entry.trace[0]
769
862
  @browser.source.split("\n")[trace.line-1].should include 'replaceWith('
@@ -775,15 +868,15 @@ describe Arachni::Browser::Javascript::TaintTracer do
775
868
  it 'logs it' do
776
869
  load_with_taint 'data_trace/jQuery.val'
777
870
 
778
- sink = subject.data_flow_sinks
871
+ sink = subject.data_flow_sinks[taint]
779
872
  sink.size.should == 1
780
873
 
781
874
  entry = sink[0]
782
875
  entry.object.should == 'jQuery'
783
876
  entry.function.name.should == 'val'
784
- entry.function.arguments.should == [ "Stuff #{@javascript.taint}"]
785
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
786
- entry.taint.should == @javascript.taint
877
+ entry.function.arguments.should == [ "Stuff #{taint}"]
878
+ entry.tainted_value.should == "Stuff #{taint}"
879
+ entry.taint.should == taint
787
880
 
788
881
  trace = entry.trace[0]
789
882
  @browser.source.split("\n")[trace.line].should include 'val('
@@ -797,7 +890,7 @@ describe Arachni::Browser::Javascript::TaintTracer do
797
890
  it 'logs it' do
798
891
  load_with_taint 'data_trace/String.replace'
799
892
 
800
- sink = subject.data_flow_sinks
893
+ sink = subject.data_flow_sinks[taint]
801
894
  sink.size.should == 1
802
895
 
803
896
  entry = sink[0]
@@ -805,10 +898,10 @@ describe Arachni::Browser::Javascript::TaintTracer do
805
898
  entry.function.name.should == 'replace'
806
899
  entry.function.source.should start_with 'function replace'
807
900
  entry.function.arguments.should == [
808
- 'my', @javascript.taint
901
+ 'my', taint
809
902
  ]
810
- entry.tainted_value.should == @javascript.taint
811
- entry.taint.should == @javascript.taint
903
+ entry.tainted_value.should == taint
904
+ entry.taint.should == taint
812
905
 
813
906
  trace = entry.trace[0]
814
907
  @browser.source.split("\n")[trace.line].should include 'replace('
@@ -820,22 +913,64 @@ describe Arachni::Browser::Javascript::TaintTracer do
820
913
  it 'logs it' do
821
914
  load_with_taint 'data_trace/String.concat'
822
915
 
823
- sink = subject.data_flow_sinks
916
+ sink = subject.data_flow_sinks[taint]
824
917
  sink.size.should == 1
825
918
 
826
919
  entry = sink[0]
827
920
  entry.object.should == 'String'
828
921
  entry.function.name.should == 'concat'
829
922
  entry.function.source.should start_with 'function concat'
830
- entry.function.arguments.should == [ "stuff #{@javascript.taint}" ]
831
- entry.tainted_value.should == "stuff #{@javascript.taint}"
832
- entry.taint.should == @javascript.taint
923
+ entry.function.arguments.should == [ "stuff #{taint}" ]
924
+ entry.tainted_value.should == "stuff #{taint}"
925
+ entry.taint.should == taint
833
926
 
834
927
  trace = entry.trace[0]
835
928
  @browser.source.split("\n")[trace.line].should include 'concat('
836
929
  trace.url.should == @browser.url
837
930
  end
838
931
  end
932
+
933
+ context '.indexOf' do
934
+ it 'logs it' do
935
+ load_with_taint 'data_trace/String.indexOf'
936
+
937
+ sink = subject.data_flow_sinks[taint]
938
+ sink.size.should == 1
939
+
940
+ entry = sink[0]
941
+ entry.object.should == 'String'
942
+ entry.function.name.should == 'indexOf'
943
+ entry.function.source.should start_with 'function indexOf'
944
+ entry.function.arguments.should == [ "stuff #{taint}" ]
945
+ entry.tainted_value.should == "stuff #{taint}"
946
+ entry.taint.should == taint
947
+
948
+ trace = entry.trace[0]
949
+ @browser.source.split("\n")[trace.line].should include 'indexOf('
950
+ trace.url.should == @browser.url
951
+ end
952
+ end
953
+
954
+ context '.lastIndexOf' do
955
+ it 'logs it' do
956
+ load_with_taint 'data_trace/String.lastIndexOf'
957
+
958
+ sink = subject.data_flow_sinks[taint]
959
+ sink.size.should == 1
960
+
961
+ entry = sink[0]
962
+ entry.object.should == 'String'
963
+ entry.function.name.should == 'lastIndexOf'
964
+ entry.function.source.should start_with 'function lastIndexOf'
965
+ entry.function.arguments.should == [ "stuff #{taint}" ]
966
+ entry.tainted_value.should == "stuff #{taint}"
967
+ entry.taint.should == taint
968
+
969
+ trace = entry.trace[0]
970
+ @browser.source.split("\n")[trace.line].should include 'lastIndexOf('
971
+ trace.url.should == @browser.url
972
+ end
973
+ end
839
974
  end
840
975
 
841
976
  context 'HTMLElement' do
@@ -843,7 +978,7 @@ describe Arachni::Browser::Javascript::TaintTracer do
843
978
  it 'logs it' do
844
979
  load_with_taint 'data_trace/HTMLElement.insertAdjacentHTML'
845
980
 
846
- sink = subject.data_flow_sinks
981
+ sink = subject.data_flow_sinks[taint]
847
982
  sink.size.should == 1
848
983
 
849
984
  entry = sink[0]
@@ -851,10 +986,10 @@ describe Arachni::Browser::Javascript::TaintTracer do
851
986
  entry.function.name.should == 'insertAdjacentHTML'
852
987
  entry.function.source.should start_with 'function insertAdjacentHTML'
853
988
  entry.function.arguments.should == [
854
- 'AfterBegin', "stuff #{@javascript.taint} more stuff"
989
+ 'AfterBegin', "stuff #{taint} more stuff"
855
990
  ]
856
- entry.tainted_value.should == "stuff #{@javascript.taint} more stuff"
857
- entry.taint.should == @javascript.taint
991
+ entry.tainted_value.should == "stuff #{taint} more stuff"
992
+ entry.taint.should == taint
858
993
 
859
994
  trace = entry.trace[0]
860
995
  @browser.source.split("\n")[trace.line].should include 'insertAdjacentHTML('
@@ -868,7 +1003,7 @@ describe Arachni::Browser::Javascript::TaintTracer do
868
1003
  it 'logs it' do
869
1004
  load_with_taint 'data_trace/Element.setAttribute'
870
1005
 
871
- sink = subject.data_flow_sinks
1006
+ sink = subject.data_flow_sinks[taint]
872
1007
  sink.size.should == 1
873
1008
 
874
1009
  entry = sink[0]
@@ -876,10 +1011,10 @@ describe Arachni::Browser::Javascript::TaintTracer do
876
1011
  entry.function.name.should == 'setAttribute'
877
1012
  entry.function.source.should start_with 'function setAttribute'
878
1013
  entry.function.arguments.should == [
879
- 'my-attribute', "stuff #{@javascript.taint} more stuff"
1014
+ 'my-attribute', "stuff #{taint} more stuff"
880
1015
  ]
881
- entry.tainted_value.should == "stuff #{@javascript.taint} more stuff"
882
- entry.taint.should == @javascript.taint
1016
+ entry.tainted_value.should == "stuff #{taint} more stuff"
1017
+ entry.taint.should == taint
883
1018
 
884
1019
  trace = entry.trace[0]
885
1020
  @browser.source.split("\n")[trace.line].should include 'setAttribute('
@@ -893,16 +1028,16 @@ describe Arachni::Browser::Javascript::TaintTracer do
893
1028
  it 'logs it' do
894
1029
  load_with_taint 'data_trace/Document.createTextNode'
895
1030
 
896
- sink = subject.data_flow_sinks
1031
+ sink = subject.data_flow_sinks[taint]
897
1032
  sink.size.should == 1
898
1033
 
899
1034
  entry = sink[0]
900
1035
  entry.object.should == 'DocumentPrototype'
901
1036
  entry.function.name.should == 'createTextNode'
902
1037
  entry.function.source.should start_with 'function createTextNode'
903
- entry.function.arguments.should == [ "node #{@javascript.taint}" ]
904
- entry.tainted_value.should == "node #{@javascript.taint}"
905
- entry.taint.should == @javascript.taint
1038
+ entry.function.arguments.should == [ "node #{taint}" ]
1039
+ entry.tainted_value.should == "node #{taint}"
1040
+ entry.taint.should == taint
906
1041
 
907
1042
  trace = entry.trace[0]
908
1043
  @browser.source.split("\n")[trace.line].should include 'document.createTextNode('
@@ -916,16 +1051,16 @@ describe Arachni::Browser::Javascript::TaintTracer do
916
1051
  it 'logs it' do
917
1052
  load_with_taint 'data_trace/CharacterData.insertData'
918
1053
 
919
- sink = subject.data_flow_sinks
1054
+ sink = subject.data_flow_sinks[taint]
920
1055
  sink.size.should == 1
921
1056
 
922
1057
  entry = sink[0]
923
1058
  entry.object.should == 'CharacterDataPrototype'
924
1059
  entry.function.name.should == 'insertData'
925
1060
  entry.function.source.should start_with 'function insertData'
926
- entry.function.arguments.should == [ "Stuff #{@javascript.taint}" ]
927
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
928
- entry.taint.should == @javascript.taint
1061
+ entry.function.arguments.should == [ "Stuff #{taint}" ]
1062
+ entry.tainted_value.should == "Stuff #{taint}"
1063
+ entry.taint.should == taint
929
1064
 
930
1065
  trace = entry.trace[0]
931
1066
  @browser.source.split("\n")[trace.line].should include 'insertData('
@@ -937,16 +1072,16 @@ describe Arachni::Browser::Javascript::TaintTracer do
937
1072
  it 'logs it' do
938
1073
  load_with_taint 'data_trace/CharacterData.appendData'
939
1074
 
940
- sink = subject.data_flow_sinks
1075
+ sink = subject.data_flow_sinks[taint]
941
1076
  sink.size.should == 1
942
1077
 
943
1078
  entry = sink[0]
944
1079
  entry.object.should == 'CharacterDataPrototype'
945
1080
  entry.function.name.should == 'appendData'
946
1081
  entry.function.source.should start_with 'function appendData'
947
- entry.function.arguments.should == [ "Stuff #{@javascript.taint}" ]
948
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
949
- entry.taint.should == @javascript.taint
1082
+ entry.function.arguments.should == [ "Stuff #{taint}" ]
1083
+ entry.tainted_value.should == "Stuff #{taint}"
1084
+ entry.taint.should == taint
950
1085
 
951
1086
  trace = entry.trace[0]
952
1087
  @browser.source.split("\n")[trace.line].should include 'appendData('
@@ -958,16 +1093,16 @@ describe Arachni::Browser::Javascript::TaintTracer do
958
1093
  it 'logs it' do
959
1094
  load_with_taint 'data_trace/CharacterData.replaceData'
960
1095
 
961
- sink = subject.data_flow_sinks
1096
+ sink = subject.data_flow_sinks[taint]
962
1097
  sink.size.should == 1
963
1098
 
964
1099
  entry = sink[0]
965
1100
  entry.object.should == 'CharacterDataPrototype'
966
1101
  entry.function.name.should == 'replaceData'
967
1102
  entry.function.source.should start_with 'function replaceData'
968
- entry.function.arguments.should == [ 0, 0, "Stuff #{@javascript.taint}" ]
969
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
970
- entry.taint.should == @javascript.taint
1103
+ entry.function.arguments.should == [ 0, 0, "Stuff #{taint}" ]
1104
+ entry.tainted_value.should == "Stuff #{taint}"
1105
+ entry.taint.should == taint
971
1106
 
972
1107
  trace = entry.trace[0]
973
1108
  @browser.source.split("\n")[trace.line].should include 'replaceData('
@@ -981,16 +1116,16 @@ describe Arachni::Browser::Javascript::TaintTracer do
981
1116
  it 'logs it' do
982
1117
  load_with_taint 'data_trace/Text.replaceWholeText'
983
1118
 
984
- sink = subject.data_flow_sinks
1119
+ sink = subject.data_flow_sinks[taint]
985
1120
  sink.size.should == 1
986
1121
 
987
1122
  entry = sink[0]
988
1123
  entry.object.should == 'TextPrototype'
989
1124
  entry.function.name.should == 'replaceWholeText'
990
1125
  entry.function.source.should start_with 'function replaceWholeText'
991
- entry.function.arguments.should == [ "Stuff #{@javascript.taint}" ]
992
- entry.tainted_value.should == "Stuff #{@javascript.taint}"
993
- entry.taint.should == @javascript.taint
1126
+ entry.function.arguments.should == [ "Stuff #{taint}" ]
1127
+ entry.tainted_value.should == "Stuff #{taint}"
1128
+ entry.taint.should == taint
994
1129
 
995
1130
  trace = entry.trace[0]
996
1131
  @browser.source.split("\n")[trace.line].should include 'replaceWholeText('
@@ -1004,7 +1139,7 @@ describe Arachni::Browser::Javascript::TaintTracer do
1004
1139
  it 'logs it' do
1005
1140
  load_with_taint 'data_trace/HTMLDocument.write'
1006
1141
 
1007
- sink = subject.data_flow_sinks
1142
+ sink = subject.data_flow_sinks[taint]
1008
1143
  sink.size.should == 1
1009
1144
 
1010
1145
  entry = sink[0]
@@ -1012,11 +1147,11 @@ describe Arachni::Browser::Javascript::TaintTracer do
1012
1147
  entry.function.name.should == 'write'
1013
1148
  entry.function.source.should start_with 'function write'
1014
1149
  entry.function.arguments.should == [
1015
- "Stuff here blah #{@javascript.taint} more stuff nlahblah..."
1150
+ "Stuff here blah #{taint} more stuff nlahblah..."
1016
1151
  ]
1017
1152
  entry.tainted_value.should ==
1018
- "Stuff here blah #{@javascript.taint} more stuff nlahblah..."
1019
- entry.taint.should == @javascript.taint
1153
+ "Stuff here blah #{taint} more stuff nlahblah..."
1154
+ entry.taint.should == taint
1020
1155
 
1021
1156
  trace = entry.trace[0]
1022
1157
  @browser.source.split("\n")[trace.line].should include 'document.write('
@@ -1028,7 +1163,7 @@ describe Arachni::Browser::Javascript::TaintTracer do
1028
1163
  it 'logs it' do
1029
1164
  load_with_taint 'data_trace/HTMLDocument.writeln'
1030
1165
 
1031
- sink = subject.data_flow_sinks
1166
+ sink = subject.data_flow_sinks[taint]
1032
1167
  sink.size.should == 1
1033
1168
 
1034
1169
  entry = sink[0]
@@ -1036,11 +1171,11 @@ describe Arachni::Browser::Javascript::TaintTracer do
1036
1171
  entry.function.name.should == 'writeln'
1037
1172
  entry.function.source.should start_with 'function writeln'
1038
1173
  entry.function.arguments.should == [
1039
- "Stuff here blah #{@javascript.taint} more stuff nlahblah..."
1174
+ "Stuff here blah #{taint} more stuff nlahblah..."
1040
1175
  ]
1041
1176
  entry.tainted_value.should ==
1042
- "Stuff here blah #{@javascript.taint} more stuff nlahblah..."
1043
- entry.taint.should == @javascript.taint
1177
+ "Stuff here blah #{taint} more stuff nlahblah..."
1178
+ entry.taint.should == taint
1044
1179
 
1045
1180
  trace = entry.trace[0]
1046
1181
  @browser.source.split("\n")[trace.line].should include 'document.writeln('
@@ -1051,10 +1186,10 @@ describe Arachni::Browser::Javascript::TaintTracer do
1051
1186
  end
1052
1187
  end
1053
1188
 
1054
- describe '#taint' do
1189
+ describe '#taints' do
1055
1190
  context 'by default' do
1056
- it 'returns nil' do
1057
- subject.taint.should be_nil
1191
+ it 'returns []' do
1192
+ subject.taints.should == []
1058
1193
  end
1059
1194
  end
1060
1195
  end
@@ -1090,23 +1225,23 @@ describe Arachni::Browser::Javascript::TaintTracer do
1090
1225
 
1091
1226
  describe '#data_flow_sinks' do
1092
1227
  it 'returns sink data' do
1093
- load "debug?input=#{subject.stub.function(:log_data_flow_sink, { function: 'blah' })}"
1228
+ load "debug?input=#{subject.stub.function(:log_data_flow_sink, 'taint', { function: 'blah' })}"
1094
1229
  @browser.watir.form.submit
1095
- subject.data_flow_sinks.should be_any
1230
+ subject.data_flow_sinks['taint'].should be_any
1096
1231
  end
1097
1232
 
1098
1233
  context 'by default' do
1099
- it 'returns []' do
1100
- subject.data_flow_sinks.should == []
1234
+ it 'returns {}' do
1235
+ subject.data_flow_sinks.should == {}
1101
1236
  end
1102
1237
  end
1103
1238
  end
1104
1239
 
1105
1240
  describe '#flush_data_flow_sinks' do
1106
1241
  it 'returns sink data' do
1107
- load "debug?input=#{subject.stub.function(:log_data_flow_sink, { function: { name: 'blah' } })}"
1242
+ load "debug?input=#{subject.stub.function(:log_data_flow_sink, 'taint', { function: { name: 'blah' } })}"
1108
1243
  @browser.watir.form.submit
1109
- sink_data = subject.flush_data_flow_sinks
1244
+ sink_data = subject.flush_data_flow_sinks['taint']
1110
1245
 
1111
1246
  first_entry = sink_data.first
1112
1247
  sink_data.should == [first_entry]
@@ -1136,7 +1271,7 @@ describe Arachni::Browser::Javascript::TaintTracer do
1136
1271
  load "debug?input=#{subject.stub.function(:log_data_flow_sink, { function: { name: 'blah' } })}"
1137
1272
  @browser.watir.form.submit
1138
1273
  subject.flush_data_flow_sinks
1139
- @javascript.flush_data_flow_sinks.should be_empty
1274
+ subject.data_flow_sinks.should be_empty
1140
1275
  end
1141
1276
  end
1142
1277
 
@@ -1174,7 +1309,7 @@ describe Arachni::Browser::Javascript::TaintTracer do
1174
1309
  load "debug?input=#{subject.stub.function(:log_data_flow_sink)}"
1175
1310
  @browser.watir.form.submit
1176
1311
  subject.flush_execution_flow_sinks
1177
- @javascript.flush_execution_flow_sinks.should be_empty
1312
+ subject.execution_flow_sinks.should be_empty
1178
1313
  end
1179
1314
  end
1180
1315
 
@@ -1211,9 +1346,9 @@ describe Arachni::Browser::Javascript::TaintTracer do
1211
1346
 
1212
1347
  describe '#log_data_flow_sink' do
1213
1348
  it 'logs a sink' do
1214
- load "debug?input=#{subject.stub.function(:log_data_flow_sink, { function: { name: 'blah' } })}"
1349
+ load "debug?input=#{subject.stub.function(:log_data_flow_sink, 'taint', { function: { name: 'blah' } })}"
1215
1350
  @browser.watir.form.submit
1216
- sink_data = subject.data_flow_sinks
1351
+ sink_data = subject.data_flow_sinks['taint']
1217
1352
 
1218
1353
  first_entry = sink_data.first
1219
1354
  sink_data.should == [first_entry]