arachni 1.2.1 → 1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +66 -0
- data/Gemfile +1 -1
- data/README.md +16 -5
- data/components/checks/active/ldap_injection/errors.txt +1 -0
- data/components/checks/active/source_code_disclosure.rb +1 -1
- data/components/checks/active/unvalidated_redirect.rb +6 -6
- data/components/checks/active/unvalidated_redirect_dom.rb +10 -7
- data/components/checks/passive/grep/captcha.rb +14 -5
- data/components/checks/passive/grep/form_upload.rb +7 -3
- data/components/checks/passive/grep/hsts.rb +3 -3
- data/components/checks/passive/grep/html_objects.rb +2 -3
- data/components/checks/passive/grep/http_only_cookies.rb +2 -3
- data/components/checks/passive/grep/insecure_cookies.rb +1 -1
- data/components/checks/passive/grep/password_autocomplete.rb +2 -2
- data/components/checks/passive/grep/unencrypted_password_forms.rb +7 -7
- data/components/checks/passive/grep/x_frame_options.rb +2 -2
- data/components/checks/passive/http_put.rb +2 -3
- data/components/path_extractors/comments.rb +3 -3
- data/components/path_extractors/scripts.rb +10 -1
- data/components/plugins/defaults/autothrottle.rb +27 -18
- data/components/plugins/defaults/meta/remedies/discovery.rb +30 -33
- data/components/plugins/defaults/meta/remedies/timing_attacks.rb +7 -11
- data/components/plugins/login_script.rb +9 -3
- data/components/plugins/proxy.rb +4 -3
- data/components/reporters/html.rb +11 -14
- data/components/reporters/html/default/issue.erb +13 -38
- data/components/reporters/html/default/issue/info.erb +1 -1
- data/components/reporters/html/default/summary/issues/by_name.erb +3 -3
- data/components/reporters/stdout.rb +62 -71
- data/components/reporters/xml.rb +26 -40
- data/components/reporters/xml/schema.xsd +43 -89
- data/lib/arachni/browser.rb +52 -3
- data/lib/arachni/browser/javascript.rb +3 -3
- data/lib/arachni/browser/javascript/scripts/taint_tracer.js +46 -25
- data/lib/arachni/browser_cluster.rb +61 -0
- data/lib/arachni/browser_cluster/job.rb +21 -1
- data/lib/arachni/browser_cluster/jobs/browser_provider.rb +3 -1
- data/lib/arachni/browser_cluster/jobs/resource_exploration.rb +2 -1
- data/lib/arachni/browser_cluster/jobs/resource_exploration/event_trigger.rb +2 -1
- data/lib/arachni/browser_cluster/jobs/taint_trace.rb +3 -2
- data/lib/arachni/browser_cluster/jobs/taint_trace/event_trigger.rb +1 -1
- data/lib/arachni/browser_cluster/worker.rb +5 -0
- data/lib/arachni/check/auditor.rb +22 -12
- data/lib/arachni/data/framework.rb +13 -1
- data/lib/arachni/data/issues.rb +9 -25
- data/lib/arachni/element/base.rb +9 -3
- data/lib/arachni/element/capabilities/analyzable.rb +2 -6
- data/lib/arachni/element/capabilities/analyzable/differential.rb +24 -7
- data/lib/arachni/element/capabilities/analyzable/{taint.rb → signature.rb} +23 -23
- data/lib/arachni/element/capabilities/auditable.rb +0 -6
- data/lib/arachni/element/capabilities/dom_only.rb +61 -0
- data/lib/arachni/element/capabilities/with_dom.rb +3 -1
- data/lib/arachni/element/cookie.rb +35 -5
- data/lib/arachni/element/cookie/dom.rb +13 -4
- data/lib/arachni/element/{capabilities/auditable/dom.rb → dom.rb} +20 -68
- data/lib/arachni/element/dom/capabilities/auditable.rb +29 -0
- data/lib/arachni/element/dom/capabilities/inputtable.rb +27 -0
- data/lib/arachni/element/dom/capabilities/mutable.rb +21 -0
- data/lib/arachni/element/dom/capabilities/submittable.rb +52 -0
- data/lib/arachni/element/form.rb +12 -1
- data/lib/arachni/element/form/capabilities/mutable.rb +2 -1
- data/lib/arachni/element/form/capabilities/with_dom.rb +0 -1
- data/lib/arachni/element/form/dom.rb +9 -3
- data/lib/arachni/element/header.rb +14 -33
- data/lib/arachni/element/header/capabilities/inputtable.rb +29 -0
- data/lib/arachni/element/header/capabilities/mutable.rb +51 -0
- data/lib/arachni/element/input/dom.rb +71 -0
- data/lib/arachni/element/json.rb +2 -0
- data/lib/arachni/element/link.rb +3 -0
- data/lib/arachni/element/link/capabilities/with_dom.rb +0 -1
- data/lib/arachni/element/link/dom.rb +16 -3
- data/lib/arachni/element/link/dom/capabilities/submittable.rb +29 -0
- data/lib/arachni/element/link_template.rb +3 -5
- data/lib/arachni/element/link_template/capabilities/inputtable.rb +5 -0
- data/lib/arachni/element/link_template/capabilities/with_dom.rb +0 -1
- data/lib/arachni/element/link_template/dom.rb +16 -3
- data/lib/arachni/element/link_template/dom/capabilities/submittable.rb +29 -0
- data/lib/arachni/element/server.rb +3 -5
- data/lib/arachni/element/ui_form.rb +106 -0
- data/lib/arachni/element/ui_form/dom.rb +107 -0
- data/lib/arachni/element/ui_input.rb +62 -0
- data/lib/arachni/element/xml.rb +2 -1
- data/lib/arachni/framework.rb +7 -5
- data/lib/arachni/framework/parts/audit.rb +0 -1
- data/lib/arachni/framework/parts/check.rb +1 -0
- data/lib/arachni/framework/parts/data.rb +4 -0
- data/lib/arachni/framework/parts/state.rb +0 -2
- data/lib/arachni/http/client.rb +17 -6
- data/lib/arachni/http/proxy_server.rb +52 -5
- data/lib/arachni/http/request.rb +1 -1
- data/lib/arachni/issue.rb +34 -179
- data/lib/arachni/issue/severity.rb +2 -0
- data/lib/arachni/option_groups/audit.rb +22 -2
- data/lib/arachni/option_groups/browser_cluster.rb +15 -0
- data/lib/arachni/page.rb +3 -2
- data/lib/arachni/parser.rb +24 -5
- data/lib/arachni/platform/manager.rb +1 -2
- data/lib/arachni/rpc/server/framework.rb +3 -4
- data/lib/arachni/rpc/server/framework/multi_instance.rb +2 -1
- data/lib/arachni/session.rb +1 -1
- data/lib/arachni/trainer.rb +4 -7
- data/lib/arachni/watir/element.rb +12 -1
- data/lib/version +1 -1
- data/spec/arachni/browser/element_locator_spec.rb +43 -43
- data/spec/arachni/browser/javascript/dom_monitor_spec.rb +44 -44
- data/spec/arachni/browser/javascript/proxy/stub_spec.rb +17 -14
- data/spec/arachni/browser/javascript/proxy_spec.rb +24 -24
- data/spec/arachni/browser/javascript/taint_tracer/frame/called_function_spec.rb +11 -11
- data/spec/arachni/browser/javascript/taint_tracer/frame_spec.rb +7 -7
- data/spec/arachni/browser/javascript/taint_tracer/sink/data_flow_spec.rb +13 -13
- data/spec/arachni/browser/javascript/taint_tracer/sink/execution_flow_spec.rb +7 -7
- data/spec/arachni/browser/javascript/taint_tracer_spec.rb +568 -558
- data/spec/arachni/browser/javascript_spec.rb +73 -63
- data/spec/arachni/browser_cluster/job/result_spec.rb +3 -3
- data/spec/arachni/browser_cluster/job_spec.rb +68 -48
- data/spec/arachni/browser_cluster/jobs/resource_exploration/event_trigger/result_spec.rb +2 -2
- data/spec/arachni/browser_cluster/jobs/resource_exploration/event_trigger_spec.rb +5 -4
- data/spec/arachni/browser_cluster/jobs/resource_exploration/result_spec.rb +2 -2
- data/spec/arachni/browser_cluster/jobs/resource_exploration_spec.rb +5 -5
- data/spec/arachni/browser_cluster/worker_spec.rb +87 -70
- data/spec/arachni/browser_cluster_spec.rb +64 -39
- data/spec/arachni/browser_spec.rb +692 -527
- data/spec/arachni/check/auditor_spec.rb +177 -147
- data/spec/arachni/check/base_spec.rb +33 -33
- data/spec/arachni/check/manager_spec.rb +15 -15
- data/spec/arachni/component/base_spec.rb +8 -8
- data/spec/arachni/component/manager_spec.rb +100 -99
- data/spec/arachni/component/options/address_spec.rb +3 -3
- data/spec/arachni/component/options/base_spec.rb +7 -7
- data/spec/arachni/component/options/bool_spec.rb +9 -9
- data/spec/arachni/component/options/float_spec.rb +6 -6
- data/spec/arachni/component/options/int_spec.rb +5 -5
- data/spec/arachni/component/options/multiple_choice_spec.rb +12 -12
- data/spec/arachni/component/options/object_spec.rb +2 -2
- data/spec/arachni/component/options/path_spec.rb +3 -3
- data/spec/arachni/component/options/port_spec.rb +5 -5
- data/spec/arachni/component/options/string_spec.rb +3 -3
- data/spec/arachni/component/options/url_spec.rb +4 -4
- data/spec/arachni/component/utilities_spec.rb +2 -2
- data/spec/arachni/data/framework/rpc_spec.rb +10 -9
- data/spec/arachni/data/framework_spec.rb +65 -46
- data/spec/arachni/data/issues_spec.rb +39 -77
- data/spec/arachni/data/plugins_spec.rb +11 -11
- data/spec/arachni/data/session_spec.rb +6 -6
- data/spec/arachni/data_spec.rb +8 -8
- data/spec/arachni/element/body_spec.rb +10 -10
- data/spec/arachni/element/capabilities/analyzable/differential_spec.rb +39 -21
- data/spec/arachni/element/capabilities/analyzable/{taint_spec.rb → signature_spec.rb} +63 -63
- data/spec/arachni/element/capabilities/analyzable/timeout_spec.rb +51 -51
- data/spec/arachni/element/capabilities/with_scope/scope_spec.rb +5 -5
- data/spec/arachni/element/cookie/dom_spec.rb +37 -18
- data/spec/arachni/element/cookie_spec.rb +206 -139
- data/spec/arachni/element/form/dom_spec.rb +36 -19
- data/spec/arachni/element/form_spec.rb +210 -187
- data/spec/arachni/element/generic_dom_spec.rb +14 -14
- data/spec/arachni/element/header_spec.rb +35 -17
- data/spec/arachni/element/json_spec.rb +53 -31
- data/spec/arachni/element/link/dom_spec.rb +46 -28
- data/spec/arachni/element/link_spec.rb +58 -40
- data/spec/arachni/element/link_template/dom_spec.rb +47 -29
- data/spec/arachni/element/link_template_spec.rb +79 -61
- data/spec/arachni/element/path_spec.rb +1 -1
- data/spec/arachni/element/server_spec.rb +33 -32
- data/spec/arachni/element/ui_form/ui_form_dom_spec.rb +164 -0
- data/spec/arachni/element/ui_form_spec.rb +242 -0
- data/spec/arachni/element/ui_input/dom_spec.rb +157 -0
- data/spec/arachni/element/ui_input_spec.rb +136 -0
- data/spec/arachni/element/xml_spec.rb +42 -24
- data/spec/arachni/element_filter_spec.rb +49 -48
- data/spec/arachni/error_spec.rb +3 -3
- data/spec/arachni/framework/parts/audit_spec.rb +64 -63
- data/spec/arachni/framework/parts/browser_spec.rb +16 -16
- data/spec/arachni/framework/parts/check_spec.rb +3 -3
- data/spec/arachni/framework/parts/data_spec.rb +48 -48
- data/spec/arachni/framework/parts/platform_spec.rb +3 -3
- data/spec/arachni/framework/parts/plugin_spec.rb +7 -6
- data/spec/arachni/framework/parts/report_spec.rb +7 -7
- data/spec/arachni/framework/parts/scope_spec.rb +16 -16
- data/spec/arachni/framework/parts/state_spec.rb +68 -69
- data/spec/arachni/framework_spec.rb +39 -31
- data/spec/arachni/http/client/dynamic_404_handlers_spec.rb +32 -32
- data/spec/arachni/http/client_spec.rb +219 -208
- data/spec/arachni/http/cookie_jar_spec.rb +72 -72
- data/spec/arachni/http/headers_spec.rb +14 -14
- data/spec/arachni/http/proxy_server_spec.rb +43 -42
- data/spec/arachni/http/request_spec.rb +105 -103
- data/spec/arachni/http/response/scope_spec.rb +24 -24
- data/spec/arachni/http/response_spec.rb +50 -49
- data/spec/arachni/issue/severity_spec.rb +10 -9
- data/spec/arachni/issue_spec.rb +71 -369
- data/spec/arachni/option_groups/audit_spec.rb +114 -114
- data/spec/arachni/option_groups/browser_cluster_spec.rb +20 -3
- data/spec/arachni/option_groups/datastore_spec.rb +6 -6
- data/spec/arachni/option_groups/dispatcher_spec.rb +19 -19
- data/spec/arachni/option_groups/http_spec.rb +11 -11
- data/spec/arachni/option_groups/input_spec.rb +31 -27
- data/spec/arachni/option_groups/output_spec.rb +2 -2
- data/spec/arachni/option_groups/paths_spec.rb +17 -17
- data/spec/arachni/option_groups/rpc_spec.rb +2 -2
- data/spec/arachni/option_groups/scope_spec.rb +40 -40
- data/spec/arachni/option_groups/session_spec.rb +6 -5
- data/spec/arachni/option_groups/snapshot_spec.rb +4 -4
- data/spec/arachni/options_spec.rb +46 -45
- data/spec/arachni/page/dom/transition_spec.rb +74 -72
- data/spec/arachni/page/dom_spec.rb +35 -35
- data/spec/arachni/page/scope_spec.rb +15 -15
- data/spec/arachni/page_spec.rb +217 -217
- data/spec/arachni/parser_spec.rb +106 -104
- data/spec/arachni/platform/fingerprinter_spec.rb +17 -14
- data/spec/arachni/platform/list_spec.rb +33 -33
- data/spec/arachni/platform/manager_spec.rb +67 -64
- data/spec/arachni/plugin/base_spec.rb +10 -10
- data/spec/arachni/plugin/manager_spec.rb +38 -37
- data/spec/arachni/report_spec.rb +43 -40
- data/spec/arachni/reporter/base_spec.rb +15 -15
- data/spec/arachni/reporter/manager_spec.rb +4 -4
- data/spec/arachni/reporter/options_spec.rb +6 -6
- data/spec/arachni/rpc/client/base_spec.rb +6 -6
- data/spec/arachni/rpc/client/dispatcher_spec.rb +2 -2
- data/spec/arachni/rpc/client/instance_spec.rb +6 -6
- data/spec/arachni/rpc/server/active_options_spec.rb +11 -8
- data/spec/arachni/rpc/server/base_spec.rb +5 -5
- data/spec/arachni/rpc/server/checks/manager_spec.rb +8 -8
- data/spec/arachni/rpc/server/dispatcher/node_spec.rb +37 -37
- data/spec/arachni/rpc/server/dispatcher/service_spec.rb +15 -14
- data/spec/arachni/rpc/server/dispatcher_spec.rb +36 -35
- data/spec/arachni/rpc/server/framework/distributor_spec.rb +36 -36
- data/spec/arachni/rpc/server/framework_multi_spec.rb +340 -336
- data/spec/arachni/rpc/server/framework_spec.rb +90 -85
- data/spec/arachni/rpc/server/instance_spec.rb +126 -107
- data/spec/arachni/rpc/server/output_spec.rb +1 -1
- data/spec/arachni/rpc/server/plugin/manager_spec.rb +6 -6
- data/spec/arachni/ruby/array_spec.rb +42 -42
- data/spec/arachni/ruby/hash_spec.rb +20 -18
- data/spec/arachni/ruby/io_spec.rb +2 -2
- data/spec/arachni/ruby/object_spec.rb +1 -1
- data/spec/arachni/ruby/set_spec.rb +3 -3
- data/spec/arachni/ruby/string_spec.rb +30 -30
- data/spec/arachni/ruby/webrick_spec.rb +2 -2
- data/spec/arachni/scope_spec.rb +1 -1
- data/spec/arachni/session_spec.rb +67 -64
- data/spec/arachni/snapshot_spec.rb +15 -15
- data/spec/arachni/state/audit_spec.rb +11 -11
- data/spec/arachni/state/element_filter_spec.rb +6 -6
- data/spec/arachni/state/framework/rpc_spec.rb +12 -12
- data/spec/arachni/state/framework_spec.rb +125 -121
- data/spec/arachni/state/http_spec.rb +7 -7
- data/spec/arachni/state/options_spec.rb +7 -7
- data/spec/arachni/state/plugins_spec.rb +8 -8
- data/spec/arachni/state_spec.rb +10 -10
- data/spec/arachni/support/buffer/autoflush_spec.rb +16 -16
- data/spec/arachni/support/buffer/base_spec.rb +39 -39
- data/spec/arachni/support/cache/least_cost_replacement_spec.rb +18 -18
- data/spec/arachni/support/cache/least_recently_pushed_spec.rb +24 -24
- data/spec/arachni/support/cache/least_recently_used_spec.rb +20 -20
- data/spec/arachni/support/cache/preference_spec.rb +4 -4
- data/spec/arachni/support/cache/random_replacement_spec.rb +8 -8
- data/spec/arachni/support/crypto/rsa_aes_cbc_spec.rb +1 -1
- data/spec/arachni/support/database/hash_spec.rb +44 -43
- data/spec/arachni/support/database/queue_spec.rb +27 -27
- data/spec/arachni/support/lookup/hash_set_spec.rb +8 -8
- data/spec/arachni/support/lookup/moolb_spec.rb +3 -3
- data/spec/arachni/support/mixins/observable_spec.rb +6 -6
- data/spec/arachni/support/signature_spec.rb +19 -19
- data/spec/arachni/trainer_spec.rb +39 -39
- data/spec/arachni/typhoeus/hydra_spec.rb +2 -2
- data/spec/arachni/uri/scope_spec.rb +66 -66
- data/spec/arachni/uri_spec.rb +107 -105
- data/spec/arachni/utilities_spec.rb +40 -40
- data/spec/components/checks/active/csrf_spec.rb +8 -8
- data/spec/components/checks/active/no_sql_injection_spec.rb +1 -1
- data/spec/components/checks/active/sql_injection_spec.rb +16 -16
- data/spec/components/checks/active/trainer_spec.rb +4 -4
- data/spec/components/checks/active/unvalidated_redirect_dom_spec.rb +4 -2
- data/spec/components/checks/active/xpath_injection_spec.rb +1 -1
- data/spec/components/checks/active/xss_dom_script_context_spec.rb +51 -21
- data/spec/components/checks/active/xss_dom_spec.rb +46 -24
- data/spec/components/checks/passive/allowed_methods_spec.rb +1 -1
- data/spec/components/checks/passive/grep/cookie_set_for_parent_domain_spec.rb +1 -1
- data/spec/components/checks/passive/grep/hsts_spec.rb +2 -2
- data/spec/components/checks/passive/grep/http_only_cookies_spec.rb +1 -1
- data/spec/components/checks/passive/grep/insecure_cookies_spec.rb +1 -1
- data/spec/components/checks/passive/grep/insecure_cors_policy_spec.rb +2 -2
- data/spec/components/checks/passive/grep/password_autocomplete_spec.rb +1 -1
- data/spec/components/checks/passive/grep/private_ip_spec.rb +3 -3
- data/spec/components/checks/passive/grep/unencrypted_password_forms_spec.rb +1 -1
- data/spec/components/checks/passive/grep/x_frame_options_spec.rb +2 -2
- data/spec/components/checks/passive/interesting_responses_spec.rb +2 -2
- data/spec/components/checks/passive/webdav_spec.rb +1 -1
- data/spec/components/checks/passive/xst_spec.rb +1 -1
- data/spec/components/fingerprinters/servers/apache_spec.rb +2 -2
- data/spec/components/path_extractors/comments_spec.rb +5 -1
- data/spec/components/path_extractors/scripts_spec.rb +5 -2
- data/spec/components/plugins/autologin_spec.rb +22 -22
- data/spec/components/plugins/autothrottle_spec.rb +6 -5
- data/spec/components/plugins/content_types_spec.rb +4 -4
- data/spec/components/plugins/cookie_collector_spec.rb +5 -5
- data/spec/components/plugins/exec_spec.rb +12 -12
- data/spec/components/plugins/form_dicattack_spec.rb +3 -3
- data/spec/components/plugins/headers_collector_spec.rb +8 -8
- data/spec/components/plugins/healthmap_spec.rb +3 -3
- data/spec/components/plugins/http_dicattack_spec.rb +3 -3
- data/spec/components/plugins/login_script_spec.rb +79 -22
- data/spec/components/plugins/meta/remedies/discovery_spec.rb +3 -2
- data/spec/components/plugins/meta/remedies/timing_attacks_spec.rb +3 -3
- data/spec/components/plugins/meta/uniformity_spec.rb +2 -2
- data/spec/components/plugins/restrict_to_dom_state_spec.rb +1 -1
- data/spec/components/plugins/script_spec.rb +1 -1
- data/spec/components/plugins/uncommon_headers_spec.rb +2 -2
- data/spec/components/plugins/vector_collector_spec.rb +2 -2
- data/spec/components/plugins/vector_feed_spec.rb +40 -40
- data/spec/components/plugins/waf_detector_spec.rb +6 -6
- data/spec/components/reporters/json_spec.rb +4 -4
- data/spec/components/reporters/marshal_spec.rb +2 -2
- data/spec/components/reporters/yaml_spec.rb +3 -2
- data/spec/external/wavsep/active/sqli_spec.rb +1 -3
- data/spec/spec_helper.rb +4 -0
- data/spec/support/factories/element/ui_form.rb +14 -0
- data/spec/support/factories/element/ui_input.rb +13 -0
- data/spec/support/factories/issue.rb +0 -13
- data/spec/support/fixtures/report.afr +0 -0
- data/spec/support/fixtures/{taint_check/taint.rb → signature_check/signature.rb} +2 -2
- data/spec/support/helpers/browser_cluster/jobs/taint_tracer.rb +11 -11
- data/spec/support/helpers/framework.rb +1 -1
- data/spec/support/helpers/pages.rb +2 -2
- data/spec/support/servers/arachni/browser.rb +139 -0
- data/spec/support/servers/arachni/browser/javascript/taint_tracer.rb +40 -0
- data/spec/support/servers/arachni/element/capabilities/analyzable/{taint.rb → signature.rb} +0 -0
- data/spec/support/servers/arachni/element/input/input_dom.rb +102 -0
- data/spec/support/servers/arachni/element/ui_form/ui_form_dom.rb +238 -0
- data/spec/support/servers/checks/active/trainer_check.rb +7 -7
- data/spec/support/servers/checks/active/unvalidated_redirect_dom.rb +22 -6
- data/spec/support/servers/checks/active/xss_dom.rb +50 -0
- data/spec/support/servers/checks/active/xss_dom_script_context.rb +53 -0
- data/spec/support/shared/browser/javascript/taint_tracer/sink/base.rb +6 -6
- data/spec/support/shared/check.rb +10 -12
- data/spec/support/shared/component/options/base.rb +24 -24
- data/spec/support/shared/element/base.rb +25 -25
- data/spec/support/shared/element/capabilities/auditable.rb +116 -140
- data/spec/support/shared/element/capabilities/dom_only.rb +65 -0
- data/spec/support/shared/element/capabilities/inputtable.rb +71 -86
- data/spec/support/shared/element/capabilities/mutable.rb +122 -111
- data/spec/support/shared/element/capabilities/refreshable.rb +10 -10
- data/spec/support/shared/element/capabilities/{submitable.rb → submittable.rb} +26 -26
- data/spec/support/shared/element/capabilities/with_auditor.rb +10 -10
- data/spec/support/shared/element/capabilities/with_dom.rb +8 -8
- data/spec/support/shared/element/capabilities/with_node.rb +4 -6
- data/spec/support/shared/element/capabilities/with_scope.rb +2 -2
- data/spec/support/shared/element/capabilities/with_source.rb +6 -8
- data/spec/support/shared/element/dom.rb +144 -0
- data/spec/support/shared/element/dom/auditable.rb +42 -0
- data/spec/support/shared/element/dom/inputtable.rb +5 -0
- data/spec/support/shared/element/dom/mutable.rb +3 -0
- data/spec/support/shared/element/dom/submittable.rb +119 -0
- data/spec/support/shared/external/wavsep.rb +3 -3
- data/spec/support/shared/fingerprinter.rb +2 -2
- data/spec/support/shared/framework.rb +1 -1
- data/spec/support/shared/http/message.rb +9 -9
- data/spec/support/shared/option_group.rb +17 -17
- data/spec/support/shared/path_extractor.rb +1 -1
- data/spec/support/shared/plugin.rb +2 -2
- data/spec/support/shared/support/cache.rb +57 -57
- data/spec/support/shared/support/lookup.rb +25 -25
- data/ui/cli/framework.rb +22 -11
- data/ui/cli/framework/option_parser.rb +15 -0
- data/ui/cli/option_parser.rb +8 -1
- data/ui/cli/output.rb +2 -1
- metadata +54 -20
- data/components/checks/active/xss_dom_inputs.rb +0 -236
- data/spec/components/checks/active/xss_dom_inputs_spec.rb +0 -30
- data/spec/support/servers/checks/active/xss_dom_inputs.rb +0 -59
- data/spec/support/shared/element/capabilities/auditable/dom.rb +0 -322
data/lib/arachni/browser.rb
CHANGED
@@ -350,11 +350,11 @@ class Browser
|
|
350
350
|
url: url,
|
351
351
|
cookies: extra_cookies
|
352
352
|
) do
|
353
|
+
print_debug_level_2 "Loading: #{url}"
|
353
354
|
watir.goto url
|
355
|
+
print_debug_level_2 'Done'
|
354
356
|
|
355
|
-
|
356
|
-
wait_for_pending_requests
|
357
|
-
wait_for_timers
|
357
|
+
wait_till_ready
|
358
358
|
|
359
359
|
url = watir.url
|
360
360
|
Options.browser_cluster.css_to_wait_for( url ).each do |css|
|
@@ -388,6 +388,20 @@ class Browser
|
|
388
388
|
transition
|
389
389
|
end
|
390
390
|
|
391
|
+
def wait_till_ready
|
392
|
+
print_debug_level_2 'Waiting for custom JS...'
|
393
|
+
@javascript.wait_till_ready
|
394
|
+
print_debug_level_2 'Done'
|
395
|
+
|
396
|
+
print_debug_level_2 "Waiting for #{@proxy.active_connections} connections to close.."
|
397
|
+
wait_for_pending_requests
|
398
|
+
print_debug_level_2 'Done'
|
399
|
+
|
400
|
+
print_debug_level_2 'Waiting for timers...'
|
401
|
+
wait_for_timers
|
402
|
+
print_debug_level_2 'Done'
|
403
|
+
end
|
404
|
+
|
391
405
|
def shutdown
|
392
406
|
begin
|
393
407
|
watir.close if browser_alive?
|
@@ -704,6 +718,13 @@ class Browser
|
|
704
718
|
# Some of these need an explicit event triggers.
|
705
719
|
had_special_trigger = true if ![:change, :blur, :focus, :select].include? event
|
706
720
|
|
721
|
+
# Send keys will append to the existing value, so we need to
|
722
|
+
# clear it first. The receiving input may support values
|
723
|
+
# though, so watch out.
|
724
|
+
if (subtype = element.to_subtype).respond_to?( :value= )
|
725
|
+
subtype.value = ''
|
726
|
+
end
|
727
|
+
|
707
728
|
element.send_keys( (options[:value] || value_for( element )).to_s )
|
708
729
|
end
|
709
730
|
|
@@ -808,6 +829,14 @@ class Browser
|
|
808
829
|
page.dom.transitions = @transitions.dup
|
809
830
|
page.dom.skip_states = skip_states.dup
|
810
831
|
|
832
|
+
if Options.audit.ui_inputs?
|
833
|
+
page.ui_inputs = Element::UIInput.from_browser( self, page )
|
834
|
+
end
|
835
|
+
|
836
|
+
if Options.audit.ui_forms?
|
837
|
+
page.ui_forms = Element::UIForm.from_browser( self, page )
|
838
|
+
end
|
839
|
+
|
811
840
|
# Go through auditable DOM forms and cookies and remove the DOM from
|
812
841
|
# them if no events are associated with it.
|
813
842
|
#
|
@@ -1012,6 +1041,11 @@ class Browser
|
|
1012
1041
|
s << '>'
|
1013
1042
|
end
|
1014
1043
|
|
1044
|
+
def filter_events( element, events )
|
1045
|
+
supported = Set.new( Arachni::Browser::Javascript.events_for( element ) )
|
1046
|
+
events.reject { |name, _| !supported.include? ('on' + name.to_s.gsub( /^on/, '' )).to_sym }
|
1047
|
+
end
|
1048
|
+
|
1015
1049
|
private
|
1016
1050
|
|
1017
1051
|
def fill_in_form_inputs( form, inputs = nil )
|
@@ -1273,8 +1307,23 @@ class Browser
|
|
1273
1307
|
end
|
1274
1308
|
|
1275
1309
|
url = "#{url}/set-cookies-#{request_token}"
|
1310
|
+
|
1311
|
+
body = ''
|
1312
|
+
if Arachni::Options::browser_cluster.local_storage.any?
|
1313
|
+
body = <<EOJS
|
1314
|
+
<script>
|
1315
|
+
var data = #{Arachni::Options::browser_cluster.local_storage.to_json};
|
1316
|
+
|
1317
|
+
for( prop in data ) {
|
1318
|
+
localStorage.setItem( prop, data[prop] );
|
1319
|
+
}
|
1320
|
+
</script>
|
1321
|
+
EOJS
|
1322
|
+
end
|
1323
|
+
|
1276
1324
|
watir.goto preload( HTTP::Response.new(
|
1277
1325
|
url: url,
|
1326
|
+
body: body,
|
1278
1327
|
headers: {
|
1279
1328
|
'Set-Cookie' => set_cookies.values.map(&:to_set_cookie)
|
1280
1329
|
}
|
@@ -504,13 +504,13 @@ class Javascript
|
|
504
504
|
end
|
505
505
|
|
506
506
|
def wrapped_taint_tracer_initializer
|
507
|
-
"/* #{token}_initialize_start */" <<
|
508
|
-
"#{@taint_tracer.stub.function( :initialize, taints )}" <<
|
507
|
+
"/* #{token}_initialize_start */ " <<
|
508
|
+
"#{@taint_tracer.stub.function( :initialize, taints )} " <<
|
509
509
|
"/* #{token}_initialize_stop */"
|
510
510
|
end
|
511
511
|
|
512
512
|
def wrapped_custom_code
|
513
|
-
"/* #{token}_code_start
|
513
|
+
"/* #{token}_code_start */ #{custom_code} /* #{token}_code_stop */"
|
514
514
|
end
|
515
515
|
|
516
516
|
def js_initialization_signal
|
@@ -25,6 +25,10 @@ var _tokenTaintTracer = _tokenTaintTracer || {
|
|
25
25
|
|
26
26
|
max_sinks: 50,
|
27
27
|
|
28
|
+
// Limits the maximum depth when traversing object properties, looking for
|
29
|
+
// taints -- safeguard for circular references.
|
30
|
+
find_taint_recursively_max_depth: 3,
|
31
|
+
|
28
32
|
// Hold debugging information, usually pushed by the 'debug' function.
|
29
33
|
debugging_data: [],
|
30
34
|
|
@@ -41,8 +45,7 @@ var _tokenTaintTracer = _tokenTaintTracer || {
|
|
41
45
|
},
|
42
46
|
|
43
47
|
// Keeps track of which functions have had tracers installed.
|
44
|
-
traced: {
|
45
|
-
},
|
48
|
+
traced: {},
|
46
49
|
|
47
50
|
// Original functions, without tracers. We don't want to trigger traced
|
48
51
|
// functions to provide functionality to this object.
|
@@ -211,7 +214,7 @@ var _tokenTaintTracer = _tokenTaintTracer || {
|
|
211
214
|
if( _tokenTaintTracer.data_flow_sinks[taint].length > _tokenTaintTracer.max_sinks ) {
|
212
215
|
_tokenTaintTracer.data_flow_sinks[taint] =
|
213
216
|
_tokenTaintTracer.data_flow_sinks[taint].slice(
|
214
|
-
|
217
|
+
_tokenTaintTracer.data_flow_sinks[taint].length -
|
215
218
|
_tokenTaintTracer.max_sinks,
|
216
219
|
_tokenTaintTracer.data_flow_sinks[taint].length
|
217
220
|
)
|
@@ -329,34 +332,38 @@ var _tokenTaintTracer = _tokenTaintTracer || {
|
|
329
332
|
},
|
330
333
|
|
331
334
|
cleanup_event: function( e ) {
|
332
|
-
var
|
333
|
-
'toElement',
|
334
|
-
'
|
335
|
+
var keep = [
|
336
|
+
'toElement',
|
337
|
+
'target',
|
338
|
+
'srcElement',
|
339
|
+
'currentTarget',
|
340
|
+
'fromElement',
|
341
|
+
'eventPhase',
|
342
|
+
'type'
|
335
343
|
];
|
336
344
|
|
337
|
-
var
|
338
|
-
|
339
|
-
|
345
|
+
var prop;
|
346
|
+
var event_data = {};
|
347
|
+
for( var i = 0; i < keep.length; i++ ) {
|
348
|
+
prop = keep[i];
|
340
349
|
|
341
|
-
|
342
|
-
if( e[prop].outerHTML ) {
|
343
|
-
arg[prop] = e[prop].outerHTML;
|
350
|
+
if( !e[prop] ) continue;
|
344
351
|
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
arg[prop] = e[prop].documentElement.outerHTML;
|
352
|
+
// Quick and easy, get the element as HTML.
|
353
|
+
if( e[prop].outerHTML ) {
|
354
|
+
event_data[prop] = e[prop].outerHTML;
|
349
355
|
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
356
|
+
// Dealing with a HTMLDocument, needs some special treatment to get the HTML.
|
357
|
+
} else if( e[prop].documentElement ) {
|
358
|
+
event_data[prop] = e[prop].documentElement.outerHTML;
|
359
|
+
|
360
|
+
// You never know...
|
354
361
|
} else {
|
355
|
-
|
362
|
+
event_data[prop] = e[prop].toString();
|
356
363
|
}
|
357
364
|
}
|
358
365
|
|
359
|
-
return
|
366
|
+
return event_data;
|
360
367
|
},
|
361
368
|
|
362
369
|
has_function: function( func ) {
|
@@ -414,8 +421,12 @@ var _tokenTaintTracer = _tokenTaintTracer || {
|
|
414
421
|
return null;
|
415
422
|
},
|
416
423
|
|
417
|
-
find_taint_recursively: function( taint, object ) {
|
424
|
+
find_taint_recursively: function( taint, object, depth ) {
|
418
425
|
var tainted;
|
426
|
+
depth = depth || 0;
|
427
|
+
|
428
|
+
if( depth > _tokenTaintTracer.find_taint_recursively_max_depth ) return;
|
429
|
+
depth++;
|
419
430
|
|
420
431
|
switch( Object.prototype.toString.call( object ) ) {
|
421
432
|
case '[object String]':
|
@@ -424,7 +435,12 @@ var _tokenTaintTracer = _tokenTaintTracer || {
|
|
424
435
|
|
425
436
|
case '[object Array]':
|
426
437
|
for( var i = 0; i < object.length; i++ ) {
|
427
|
-
tainted = _tokenTaintTracer.find_taint_recursively(
|
438
|
+
tainted = _tokenTaintTracer.find_taint_recursively(
|
439
|
+
taint,
|
440
|
+
object[i],
|
441
|
+
depth
|
442
|
+
);
|
443
|
+
|
428
444
|
if ( tainted ) return tainted;
|
429
445
|
}
|
430
446
|
break;
|
@@ -435,7 +451,12 @@ var _tokenTaintTracer = _tokenTaintTracer || {
|
|
435
451
|
var property_value = object[property];
|
436
452
|
|
437
453
|
if( Object.prototype.toString.call( property_value ) !== '[object Function]' ){
|
438
|
-
tainted = _tokenTaintTracer.find_taint_recursively(
|
454
|
+
tainted = _tokenTaintTracer.find_taint_recursively(
|
455
|
+
taint,
|
456
|
+
property_value,
|
457
|
+
depth
|
458
|
+
);
|
459
|
+
|
439
460
|
if ( tainted ) return tainted;
|
440
461
|
}
|
441
462
|
}
|
@@ -71,6 +71,8 @@ class BrowserCluster
|
|
71
71
|
|
72
72
|
attr_reader :consumed_pids
|
73
73
|
|
74
|
+
attr_reader :job_counter
|
75
|
+
|
74
76
|
# @param [Hash] options
|
75
77
|
# @option options [Integer] :pool_size (5)
|
76
78
|
# Amount of {Worker browsers} to add to the pool.
|
@@ -153,6 +155,8 @@ class BrowserCluster
|
|
153
155
|
|
154
156
|
notify_on_queue job
|
155
157
|
|
158
|
+
self.class.increment_queued_job_count
|
159
|
+
|
156
160
|
@pending_job_counter += 1
|
157
161
|
@pending_jobs[job.id] += 1
|
158
162
|
@job_callbacks[job.id] = block if block
|
@@ -362,6 +366,9 @@ class BrowserCluster
|
|
362
366
|
# @private
|
363
367
|
def decrease_pending_job( job )
|
364
368
|
synchronize do
|
369
|
+
increment_completed_job_count
|
370
|
+
add_to_total_job_time( job.time )
|
371
|
+
|
365
372
|
@pending_job_counter -= 1
|
366
373
|
@pending_jobs[job.id] -= 1
|
367
374
|
job_done( job ) if @pending_jobs[job.id] <= 0
|
@@ -373,6 +380,60 @@ class BrowserCluster
|
|
373
380
|
@job_callbacks[job.id]
|
374
381
|
end
|
375
382
|
|
383
|
+
def increment_queued_job_count
|
384
|
+
synchronize do
|
385
|
+
self.class.increment_queued_job_count
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
def increment_completed_job_count( *args )
|
390
|
+
synchronize do
|
391
|
+
self.class.increment_completed_job_count( *args )
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
def add_to_total_job_time( time )
|
396
|
+
synchronize do
|
397
|
+
self.class.add_to_total_job_time( time )
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
def self.seconds_per_job
|
402
|
+
total_job_time / Float( completed_job_count )
|
403
|
+
end
|
404
|
+
|
405
|
+
def self.increment_queued_job_count
|
406
|
+
@queued_job_count ||= 0
|
407
|
+
@queued_job_count += 1
|
408
|
+
end
|
409
|
+
|
410
|
+
def self.increment_completed_job_count( increment = 1 )
|
411
|
+
@completed_job_count ||= 0
|
412
|
+
@completed_job_count += increment
|
413
|
+
end
|
414
|
+
|
415
|
+
def self.completed_job_count
|
416
|
+
@completed_job_count.to_i
|
417
|
+
end
|
418
|
+
|
419
|
+
def self.total_job_time
|
420
|
+
@total_job_time.to_i
|
421
|
+
end
|
422
|
+
|
423
|
+
def self.add_to_total_job_time( time )
|
424
|
+
@total_job_time ||= 0
|
425
|
+
@total_job_time += time.to_i
|
426
|
+
end
|
427
|
+
|
428
|
+
def self.statistics
|
429
|
+
{
|
430
|
+
seconds_per_job: seconds_per_job,
|
431
|
+
total_job_time: total_job_time,
|
432
|
+
queued_job_count: @queued_job_count || 0,
|
433
|
+
completed_job_count: @completed_job_count || 0
|
434
|
+
}
|
435
|
+
end
|
436
|
+
|
376
437
|
private
|
377
438
|
|
378
439
|
def notify_on_queue( job )
|
@@ -44,6 +44,10 @@ class Job
|
|
44
44
|
# @see #forward_as
|
45
45
|
attr_accessor :forwarder
|
46
46
|
|
47
|
+
# @return [Integer]
|
48
|
+
# Duration of the job, in seconds.
|
49
|
+
attr_accessor :time
|
50
|
+
|
47
51
|
# @param [Hash] options
|
48
52
|
def initialize( options = {} )
|
49
53
|
@options = options.dup
|
@@ -52,6 +56,19 @@ class Job
|
|
52
56
|
options.each { |k, v| options[k] = send( "#{k}=", v ) }
|
53
57
|
end
|
54
58
|
|
59
|
+
# @param [Integer] time
|
60
|
+
# Amount of {#time} elapsed until time-out.
|
61
|
+
def timed_out!( time )
|
62
|
+
@timed_out = true
|
63
|
+
@time = time
|
64
|
+
end
|
65
|
+
|
66
|
+
# @return [Bool]
|
67
|
+
# `true` if timed-ot, `false` otherwise.
|
68
|
+
def timed_out?
|
69
|
+
!!@timed_out
|
70
|
+
end
|
71
|
+
|
55
72
|
# @note The following resources will be available at the time of execution:
|
56
73
|
#
|
57
74
|
# * {#browser}
|
@@ -121,7 +138,10 @@ class Job
|
|
121
138
|
# @return [Job]
|
122
139
|
# Copy of `self`
|
123
140
|
def dup
|
124
|
-
self.class.new add_id( @options )
|
141
|
+
n = self.class.new( add_id( @options ) )
|
142
|
+
n.time = time
|
143
|
+
n.timed_out!( time ) if timed_out?
|
144
|
+
n
|
125
145
|
end
|
126
146
|
|
127
147
|
# @param [Hash] options
|
@@ -21,7 +21,9 @@ class BrowserProvider < Job
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def to_s
|
24
|
-
"#<#{self.class}:#{object_id}
|
24
|
+
"#<#{self.class}:#{object_id} " <<
|
25
|
+
"callback=#{browser.master.callback_for( self ) if browser && browser.master} " <<
|
26
|
+
"time=#{@time} timed_out=#{timed_out?}>"
|
25
27
|
end
|
26
28
|
alias :inspect :to_s
|
27
29
|
|
@@ -37,7 +37,8 @@ class EventTrigger < ResourceExploration
|
|
37
37
|
|
38
38
|
def to_s
|
39
39
|
"#<#{self.class}:#{object_id} @resource=#{@resource} " +
|
40
|
-
"@event=#{@event.inspect} @element=#{@element.inspect}
|
40
|
+
"@event=#{@event.inspect} @element=#{@element.inspect} " <<
|
41
|
+
"time=#{@time} timed_out=#{timed_out?}>"
|
41
42
|
end
|
42
43
|
|
43
44
|
end
|
@@ -42,8 +42,9 @@ class TaintTrace < ResourceExploration
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def to_s
|
45
|
-
"#<#{self.class}:#{object_id} @resource=#{@resource} "
|
46
|
-
"@taint=#{@taint.inspect} @injector=#{@injector.inspect}
|
45
|
+
"#<#{self.class}:#{object_id} @resource=#{@resource} " <<
|
46
|
+
"@taint=#{@taint.inspect} @injector=#{@injector.inspect} " <<
|
47
|
+
"time=#{@time} timed_out=#{timed_out?}>"
|
47
48
|
end
|
48
49
|
alias :inspect :to_s
|
49
50
|
|
@@ -28,7 +28,7 @@ class EventTrigger < ResourceExploration::EventTrigger
|
|
28
28
|
def to_s
|
29
29
|
"#<#{self.class}:#{object_id} @resource=#{@resource} " +
|
30
30
|
"@event=#{@event.inspect} @element=#{@element.inspect} " +
|
31
|
-
"@forwarder=#{@forwarder}>"
|
31
|
+
"@forwarder=#{@forwarder} time=#{@time} timed_out=#{timed_out?}>"
|
32
32
|
end
|
33
33
|
|
34
34
|
end
|
@@ -82,6 +82,7 @@ class Worker < Arachni::Browser
|
|
82
82
|
# If we can't respawn, then bail out.
|
83
83
|
return if browser_respawn_if_necessary.nil?
|
84
84
|
|
85
|
+
time = Time.now
|
85
86
|
begin
|
86
87
|
with_timeout @job_timeout do
|
87
88
|
exception_jail false do
|
@@ -98,7 +99,11 @@ class Worker < Arachni::Browser
|
|
98
99
|
end
|
99
100
|
end
|
100
101
|
end
|
102
|
+
|
103
|
+
job.time = Time.now - time
|
101
104
|
rescue TimeoutError => e
|
105
|
+
job.timed_out!( Time.now - time )
|
106
|
+
|
102
107
|
print_bad "Job timed-out after #{@job_timeout} seconds: #{@job}"
|
103
108
|
|
104
109
|
# Could have left us with a broken browser.
|