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
@@ -147,6 +147,22 @@ class Audit < Arachni::OptionGroup
|
|
147
147
|
# Audit XML request inputs.
|
148
148
|
attr_accessor :xmls
|
149
149
|
|
150
|
+
# @note Default is `false`.
|
151
|
+
#
|
152
|
+
# @return [Bool]
|
153
|
+
# Audit DOM inputs.
|
154
|
+
attr_accessor :ui_inputs
|
155
|
+
alias :ui_input_doms :ui_inputs
|
156
|
+
alias :ui_input_doms= :ui_inputs=
|
157
|
+
|
158
|
+
# @note Default is `false`.
|
159
|
+
#
|
160
|
+
# @return [Bool]
|
161
|
+
# Audit DOM UI forms -- i.e. combination or orphan inputs and buttons.
|
162
|
+
attr_accessor :ui_forms
|
163
|
+
alias :ui_form_doms :ui_forms
|
164
|
+
alias :ui_form_doms= :ui_forms=
|
165
|
+
|
150
166
|
set_defaults(
|
151
167
|
parameter_values: true,
|
152
168
|
exclude_vector_patterns: [],
|
@@ -235,6 +251,10 @@ class Audit < Arachni::OptionGroup
|
|
235
251
|
# * `:forms`
|
236
252
|
# * `:cookies`
|
237
253
|
# * `:headers`
|
254
|
+
# * `:ui_inputs`
|
255
|
+
# * `:ui_forms`
|
256
|
+
# * `:xmls`
|
257
|
+
# * `:jsons`
|
238
258
|
#
|
239
259
|
# @return [Bool]
|
240
260
|
#
|
@@ -250,8 +270,8 @@ class Audit < Arachni::OptionGroup
|
|
250
270
|
|
251
271
|
[:links, :forms, :cookies, :headers, :cookies_extensively,
|
252
272
|
:with_both_http_methods, :link_doms, :form_doms, :cookie_doms,
|
253
|
-
:jsons, :xmls, :
|
254
|
-
|
273
|
+
:jsons, :xmls, :ui_inputs, :ui_input_doms, :ui_forms, :ui_form_doms,
|
274
|
+
:parameter_values, :parameter_names, :with_extra_parameter].each do |attribute|
|
255
275
|
define_method "#{attribute}?" do
|
256
276
|
!!send( attribute )
|
257
277
|
end
|
@@ -13,6 +13,10 @@ module Arachni::OptionGroups
|
|
13
13
|
# @author Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>
|
14
14
|
class BrowserCluster < Arachni::OptionGroup
|
15
15
|
|
16
|
+
# @return [Hash]
|
17
|
+
# Data to be set in the browser's `localStorage`.
|
18
|
+
attr_accessor :local_storage
|
19
|
+
|
16
20
|
# @return [Hash<Regexp,String>]
|
17
21
|
# When the page URL matched the key `Regexp`, wait until the `String` CSS
|
18
22
|
# selector in the value matches an element.
|
@@ -43,6 +47,7 @@ class BrowserCluster < Arachni::OptionGroup
|
|
43
47
|
attr_accessor :screen_height
|
44
48
|
|
45
49
|
set_defaults(
|
50
|
+
local_storage: {},
|
46
51
|
wait_for_elements: {},
|
47
52
|
pool_size: 6,
|
48
53
|
job_timeout: 25,
|
@@ -52,6 +57,16 @@ class BrowserCluster < Arachni::OptionGroup
|
|
52
57
|
screen_height: 1200
|
53
58
|
)
|
54
59
|
|
60
|
+
def local_storage=( data )
|
61
|
+
data ||= {}
|
62
|
+
|
63
|
+
if !data.is_a?( Hash )
|
64
|
+
fail ArgumentError, "Expected data to be Hash, got #{data.class} instead."
|
65
|
+
end
|
66
|
+
|
67
|
+
@local_storage = data
|
68
|
+
end
|
69
|
+
|
55
70
|
def css_to_wait_for( url )
|
56
71
|
wait_for_elements.map do |pattern, css|
|
57
72
|
next if !(url =~ pattern)
|
data/lib/arachni/page.rb
CHANGED
@@ -101,7 +101,8 @@ class Page
|
|
101
101
|
end
|
102
102
|
|
103
103
|
ELEMENTS = [
|
104
|
-
:links, :forms, :cookies, :headers, :link_templates, :jsons, :xmls
|
104
|
+
:links, :forms, :cookies, :headers, :link_templates, :jsons, :xmls,
|
105
|
+
:ui_inputs, :ui_forms
|
105
106
|
]
|
106
107
|
|
107
108
|
METADATA = [ :nonce_name, :skip_dom ]
|
@@ -274,7 +275,7 @@ class Page
|
|
274
275
|
@has_javascript = nil
|
275
276
|
clear_cache
|
276
277
|
|
277
|
-
@body = string.to_s.dup.freeze
|
278
|
+
@body = string.to_s.dup.recode.freeze
|
278
279
|
end
|
279
280
|
|
280
281
|
ELEMENTS.each do |type|
|
data/lib/arachni/parser.rb
CHANGED
@@ -244,6 +244,16 @@ class Parser
|
|
244
244
|
@link_vars ||= parsed.rewrite.query_parameters.freeze
|
245
245
|
end
|
246
246
|
|
247
|
+
# Dummy method, only the {Browser#to_page browser} can fill this in.
|
248
|
+
def ui_inputs
|
249
|
+
[]
|
250
|
+
end
|
251
|
+
|
252
|
+
# Dummy method, only the {Browser#to_page browser} can fill this in.
|
253
|
+
def ui_forms
|
254
|
+
[]
|
255
|
+
end
|
256
|
+
|
247
257
|
# @return [Array<Element::Cookie>]
|
248
258
|
# Cookies from HTTP headers and response body.
|
249
259
|
def cookies
|
@@ -320,16 +330,25 @@ class Parser
|
|
320
330
|
# Paths.
|
321
331
|
def run_extractors
|
322
332
|
begin
|
323
|
-
|
333
|
+
unsanitized_paths = Set.new
|
334
|
+
self.class.extractors.available.each do |name|
|
324
335
|
exception_jail false do
|
325
|
-
self.class.extractors[name].new(
|
336
|
+
unsanitized_paths.merge self.class.extractors[name].new(
|
326
337
|
document: document,
|
327
338
|
html: body
|
328
339
|
).run
|
329
340
|
end
|
330
|
-
end
|
331
|
-
|
332
|
-
|
341
|
+
end
|
342
|
+
|
343
|
+
sanitized_paths = Set.new
|
344
|
+
unsanitized_paths.map do |path|
|
345
|
+
abs = to_absolute( path )
|
346
|
+
next if !abs || skip?( abs )
|
347
|
+
|
348
|
+
sanitized_paths << abs
|
349
|
+
end
|
350
|
+
|
351
|
+
sanitized_paths.to_a
|
333
352
|
rescue => e
|
334
353
|
print_exception e
|
335
354
|
[]
|
@@ -167,7 +167,7 @@ class Manager
|
|
167
167
|
rack: 'Rack',
|
168
168
|
django: 'Django',
|
169
169
|
cakephp: 'CakePHP',
|
170
|
-
nette:
|
170
|
+
nette: 'Nette',
|
171
171
|
symfony: 'Symfony',
|
172
172
|
rails: 'Ruby on Rails',
|
173
173
|
aspx_mvc: 'ASP.NET MVC',
|
@@ -175,7 +175,6 @@ class Manager
|
|
175
175
|
cherrypy: 'CherryPy'
|
176
176
|
}
|
177
177
|
|
178
|
-
# Amount of
|
179
178
|
PLATFORM_CACHE_SIZE = 1000
|
180
179
|
|
181
180
|
def self.synchronize( &block )
|
@@ -206,12 +206,11 @@ class Framework < ::Arachni::Framework
|
|
206
206
|
end
|
207
207
|
|
208
208
|
# @return [Array<Hash>]
|
209
|
-
#
|
210
|
-
# from the parent as {Arachni::Issue#to_rpc_data RPC data}.
|
209
|
+
# Issues as {Arachni::Issue#to_rpc_data RPC data}.
|
211
210
|
#
|
212
211
|
# @private
|
213
212
|
def issues
|
214
|
-
Data.issues.map
|
213
|
+
Data.issues.sort.map(&:to_rpc_data)
|
215
214
|
end
|
216
215
|
|
217
216
|
# @return [Array<Hash>]
|
@@ -219,7 +218,7 @@ class Framework < ::Arachni::Framework
|
|
219
218
|
#
|
220
219
|
# @see #issues
|
221
220
|
def issues_as_hash
|
222
|
-
Data.issues.map
|
221
|
+
Data.issues.sort.map(&:to_h)
|
223
222
|
end
|
224
223
|
|
225
224
|
# @return [String]
|
data/lib/arachni/session.rb
CHANGED
@@ -278,7 +278,7 @@ class Session
|
|
278
278
|
http.get( Options.session.check_url, http_options ) do |response|
|
279
279
|
bool = !!response.body.match( Options.session.check_pattern )
|
280
280
|
|
281
|
-
print_debug "Login check done: #{bool}"
|
281
|
+
print_debug "Login check done: #{bool}\n#{response}"
|
282
282
|
block.call( bool ) if block
|
283
283
|
end
|
284
284
|
|
data/lib/arachni/trainer.rb
CHANGED
@@ -127,18 +127,15 @@ class Trainer
|
|
127
127
|
|
128
128
|
[ :forms, :links ].each { |type| has_new_elements ||= has_new?( incoming_page, type ) }
|
129
129
|
|
130
|
+
incoming_page.paths.each do |path|
|
131
|
+
@framework.push_to_url_queue( path )
|
132
|
+
end
|
133
|
+
|
130
134
|
if has_new_elements
|
131
135
|
@trainings_per_url[incoming_page.url] += 1
|
132
136
|
|
133
137
|
notify_on_new_page incoming_page
|
134
138
|
@framework.push_to_page_queue( incoming_page )
|
135
|
-
|
136
|
-
# If the page is pushed, paths will be extracted eventually, if not, we
|
137
|
-
# need to do it now.
|
138
|
-
else
|
139
|
-
incoming_page.paths.each do |path|
|
140
|
-
@framework.push_to_url_queue( path )
|
141
|
-
end
|
142
139
|
end
|
143
140
|
|
144
141
|
incoming_page.clear_cache
|
@@ -10,7 +10,18 @@ module Watir
|
|
10
10
|
class Element
|
11
11
|
|
12
12
|
def opening_tag
|
13
|
-
|
13
|
+
browser.execute_script(
|
14
|
+
%Q[
|
15
|
+
var s = '<' + arguments[0].tagName.toLowerCase();
|
16
|
+
var attrs = arguments[0].attributes;
|
17
|
+
for( var l = 0; l < attrs.length; ++l ) {
|
18
|
+
s += ' ' + attrs[l].name + '="' + attrs[l].value.replace( '"', '\"' ) + '"';
|
19
|
+
}
|
20
|
+
s += '>'
|
21
|
+
return s;
|
22
|
+
],
|
23
|
+
self
|
24
|
+
)
|
14
25
|
end
|
15
26
|
|
16
27
|
def events
|
data/lib/version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.3
|
@@ -25,7 +25,7 @@ describe Arachni::Browser::ElementLocator do
|
|
25
25
|
subject { described_class.new options }
|
26
26
|
|
27
27
|
it "supports #{Arachni::RPC::Serializer}" do
|
28
|
-
subject.
|
28
|
+
expect(subject).to eq(Arachni::RPC::Serializer.deep_clone( subject ))
|
29
29
|
end
|
30
30
|
|
31
31
|
describe '#to_rpc_data' do
|
@@ -33,7 +33,7 @@ describe Arachni::Browser::ElementLocator do
|
|
33
33
|
|
34
34
|
%w(tag_name attributes).each do |attribute|
|
35
35
|
it "includes '#{attribute}'" do
|
36
|
-
data[attribute].
|
36
|
+
expect(data[attribute]).to eq(subject.send( attribute ))
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
@@ -44,7 +44,7 @@ describe Arachni::Browser::ElementLocator do
|
|
44
44
|
|
45
45
|
%w(tag_name attributes).each do |attribute|
|
46
46
|
it "restores '#{attribute}'" do
|
47
|
-
restored.send( attribute ).
|
47
|
+
expect(restored.send( attribute )).to eq(subject.send( attribute ))
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
@@ -52,10 +52,10 @@ describe Arachni::Browser::ElementLocator do
|
|
52
52
|
describe '.from_html' do
|
53
53
|
it 'fills in locator data from HTML code' do
|
54
54
|
l = described_class.from_html( '<a href="/test/">Click me</a>' )
|
55
|
-
l.tag_name.
|
56
|
-
l.attributes.
|
55
|
+
expect(l.tag_name).to eq(:a)
|
56
|
+
expect(l.attributes).to eq({
|
57
57
|
'href' => '/test/'
|
58
|
-
}
|
58
|
+
})
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -64,27 +64,27 @@ describe Arachni::Browser::ElementLocator do
|
|
64
64
|
l = described_class.from_node(
|
65
65
|
Nokogiri::HTML.fragment( '<a href="/test/">Click me</a>' ).children.first
|
66
66
|
)
|
67
|
-
l.tag_name.
|
68
|
-
l.attributes.
|
67
|
+
expect(l.tag_name).to eq(:a)
|
68
|
+
expect(l.attributes).to eq({
|
69
69
|
'href' => '/test/'
|
70
|
-
}
|
70
|
+
})
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
74
|
describe '#initialize' do
|
75
75
|
describe :tag_name do
|
76
76
|
it 'sets #tag_name' do
|
77
|
-
described_class.new( tag_name: :a ).tag_name.
|
77
|
+
expect(described_class.new( tag_name: :a ).tag_name).to eq(:a)
|
78
78
|
end
|
79
79
|
|
80
80
|
it 'converts it to a Sybmol' do
|
81
|
-
described_class.new( tag_name: 'a' ).tag_name.
|
81
|
+
expect(described_class.new( tag_name: 'a' ).tag_name).to eq(:a)
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
85
|
describe :attributes do
|
86
86
|
it 'sets #attributes' do
|
87
|
-
described_class.new( attributes: attributes ).attributes.
|
87
|
+
expect(described_class.new( attributes: attributes ).attributes).to eq(attributes)
|
88
88
|
end
|
89
89
|
end
|
90
90
|
end
|
@@ -95,14 +95,14 @@ 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.
|
99
|
-
element.exists
|
98
|
+
expect(element).to be_kind_of Watir::HTMLElement
|
99
|
+
expect(element.exists?).to be_truthy
|
100
100
|
end
|
101
101
|
|
102
102
|
context 'when the element cannot be located' do
|
103
103
|
it "returns a #{Watir} locator" do
|
104
104
|
browser.load "#{url}/digest"
|
105
|
-
subject.locate( browser ).exists
|
105
|
+
expect(subject.locate( browser ).exists?).to be_falsey
|
106
106
|
end
|
107
107
|
end
|
108
108
|
end
|
@@ -110,30 +110,30 @@ describe Arachni::Browser::ElementLocator do
|
|
110
110
|
describe '#css' do
|
111
111
|
context 'when there are no attributes' do
|
112
112
|
it 'returns a CSS locator with just the tag name' do
|
113
|
-
described_class.new( tag_name: :a ).css.
|
113
|
+
expect(described_class.new( tag_name: :a ).css).to eq('a')
|
114
114
|
end
|
115
115
|
end
|
116
116
|
|
117
117
|
context 'when there is an attribute' do
|
118
118
|
it 'returns a CSS locator with the attribute' do
|
119
|
-
described_class.new(
|
119
|
+
expect(described_class.new(
|
120
120
|
tag_name: :a,
|
121
121
|
attributes: {
|
122
122
|
stuff: 'blah'
|
123
123
|
}
|
124
|
-
).css.
|
124
|
+
).css).to eq('a[stuff="blah"]')
|
125
125
|
end
|
126
126
|
end
|
127
127
|
|
128
128
|
context 'when there are multiple attributes' do
|
129
129
|
it 'returns a CSS locator with the attributes' do
|
130
|
-
described_class.new(
|
130
|
+
expect(described_class.new(
|
131
131
|
tag_name: :a,
|
132
132
|
attributes: {
|
133
133
|
stuff: 'blah',
|
134
134
|
stuff2: 'blah2'
|
135
135
|
}
|
136
|
-
).css.
|
136
|
+
).css).to eq('a[stuff="blah"][stuff2="blah2"]')
|
137
137
|
end
|
138
138
|
end
|
139
139
|
end
|
@@ -142,13 +142,13 @@ describe Arachni::Browser::ElementLocator do
|
|
142
142
|
it 'sets #tag_name' do
|
143
143
|
l = described_class.new
|
144
144
|
l.tag_name = tag_name
|
145
|
-
l.tag_name.
|
145
|
+
expect(l.tag_name).to eq(tag_name)
|
146
146
|
end
|
147
147
|
|
148
148
|
it 'converts the arguments to a Symbol' do
|
149
149
|
l = described_class.new
|
150
150
|
l.tag_name = tag_name.to_s
|
151
|
-
l.tag_name.
|
151
|
+
expect(l.tag_name).to eq(tag_name.to_sym)
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
@@ -156,71 +156,71 @@ describe Arachni::Browser::ElementLocator do
|
|
156
156
|
it 'sets #attributes' do
|
157
157
|
l = described_class.new
|
158
158
|
l.attributes = attributes
|
159
|
-
l.attributes.
|
159
|
+
expect(l.attributes).to eq(attributes)
|
160
160
|
end
|
161
161
|
|
162
162
|
it 'converts the keys and values to strings' do
|
163
163
|
l = described_class.new
|
164
164
|
l.attributes = attributes.
|
165
165
|
inject({}) { |h, (k,v)| h[k.to_sym] = v.to_sym; h }
|
166
|
-
l.attributes.
|
166
|
+
expect(l.attributes).to eq(attributes)
|
167
167
|
end
|
168
168
|
|
169
169
|
it 'freezes the keys and values' do
|
170
170
|
l = described_class.new
|
171
171
|
l.attributes = attributes
|
172
172
|
l.attributes.each do |k, v|
|
173
|
-
k.
|
174
|
-
v.
|
173
|
+
expect(k).to be_frozen
|
174
|
+
expect(v).to be_frozen
|
175
175
|
end
|
176
176
|
end
|
177
177
|
|
178
178
|
it 'freezes the hash' do
|
179
179
|
l = described_class.new
|
180
180
|
l.attributes = attributes
|
181
|
-
l.attributes.
|
181
|
+
expect(l.attributes).to be_frozen
|
182
182
|
end
|
183
183
|
end
|
184
184
|
|
185
185
|
describe '#locatable_attributes' do
|
186
186
|
it 'returns attributes that can be used to locate the element' do
|
187
|
-
described_class.new(
|
187
|
+
expect(described_class.new(
|
188
188
|
tag_name: :a,
|
189
189
|
attributes: attributes.merge(
|
190
190
|
'custom-attr' => 'blah',
|
191
191
|
'data-id' => 'blah'
|
192
192
|
)
|
193
|
-
).locatable_attributes.
|
193
|
+
).locatable_attributes).to eq({ id: 'my-id', data_id: 'blah' })
|
194
194
|
end
|
195
195
|
end
|
196
196
|
|
197
197
|
describe '#to_s' do
|
198
198
|
it 'converts it to an HTML opening tag' do
|
199
|
-
subject.to_s.
|
200
|
-
described_class.new( tag_name: tag_name ).to_s.
|
199
|
+
expect(subject.to_s).to eq('<a id="my-id" class="my-class">')
|
200
|
+
expect(described_class.new( tag_name: tag_name ).to_s).to eq('<a>')
|
201
201
|
end
|
202
202
|
end
|
203
203
|
|
204
204
|
describe '#inspect' do
|
205
205
|
it 'is aliased to #to_s' do
|
206
|
-
subject.to_s.
|
206
|
+
expect(subject.to_s).to eq(subject.inspect)
|
207
207
|
end
|
208
208
|
end
|
209
209
|
|
210
210
|
describe '#to_hash' do
|
211
211
|
it 'converts it to a Hash' do
|
212
|
-
subject.to_hash.
|
212
|
+
expect(subject.to_hash).to eq(options)
|
213
213
|
end
|
214
214
|
|
215
215
|
it 'is aliased to #to_h' do
|
216
|
-
subject.to_h.
|
216
|
+
expect(subject.to_h).to eq(subject.to_hash)
|
217
217
|
end
|
218
218
|
end
|
219
219
|
|
220
220
|
describe '#dup' do
|
221
221
|
it 'duplicates self' do
|
222
|
-
subject.dup.
|
223
|
-
subject.dup.object_id.
|
222
|
+
expect(subject.dup).to eq(subject)
|
223
|
+
expect(subject.dup.object_id).not_to eq(subject.object_id)
|
224
224
|
end
|
225
225
|
end
|
226
226
|
|
@@ -228,20 +228,20 @@ describe Arachni::Browser::ElementLocator do
|
|
228
228
|
context 'when the #tag_name changes' do
|
229
229
|
it 'changes' do
|
230
230
|
hash = subject.hash
|
231
|
-
hash.
|
231
|
+
expect(hash).to eq(subject.hash)
|
232
232
|
|
233
233
|
subject.tag_name = 'stuff'
|
234
|
-
hash.
|
234
|
+
expect(hash).not_to eq(subject.hash)
|
235
235
|
end
|
236
236
|
end
|
237
237
|
|
238
238
|
context 'when the #attributes change' do
|
239
239
|
it 'changes' do
|
240
240
|
hash = subject.hash
|
241
|
-
hash.
|
241
|
+
expect(hash).to eq(subject.hash)
|
242
242
|
|
243
243
|
subject.attributes = { 1 => 2 }
|
244
|
-
hash.
|
244
|
+
expect(hash).not_to eq(subject.hash)
|
245
245
|
end
|
246
246
|
end
|
247
247
|
end
|
@@ -249,8 +249,8 @@ describe Arachni::Browser::ElementLocator do
|
|
249
249
|
describe '#==' do
|
250
250
|
context 'when the objects are equal' do
|
251
251
|
it 'returns true' do
|
252
|
-
subject.
|
253
|
-
subject.dup.
|
252
|
+
expect(subject).to eq(subject)
|
253
|
+
expect(subject.dup).to eq(subject)
|
254
254
|
end
|
255
255
|
end
|
256
256
|
|
@@ -258,7 +258,7 @@ describe Arachni::Browser::ElementLocator do
|
|
258
258
|
it 'returns false' do
|
259
259
|
dup = subject.dup
|
260
260
|
dup.tag_name = 'stuff'
|
261
|
-
dup.
|
261
|
+
expect(dup).not_to eq(subject)
|
262
262
|
end
|
263
263
|
end
|
264
264
|
end
|