arachni 1.0.6 → 1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +193 -0
- data/Gemfile +0 -1
- data/LICENSE.md +1 -1
- data/README.md +23 -18
- data/Rakefile +5 -3
- data/arachni.gemspec +11 -8
- data/bin/arachni +1 -1
- data/bin/arachni_console +1 -1
- data/bin/arachni_multi +1 -1
- data/bin/arachni_reporter +1 -1
- data/bin/arachni_restore +1 -1
- data/bin/arachni_rpc +1 -1
- data/bin/arachni_rpcd +1 -1
- data/bin/arachni_rpcd_monitor +1 -1
- data/bin/arachni_script +1 -1
- data/components/checks/active/code_injection.rb +5 -7
- data/components/checks/active/code_injection_php_input_wrapper.rb +1 -1
- data/components/checks/active/code_injection_timing.rb +2 -3
- data/components/checks/active/csrf.rb +9 -5
- data/components/checks/active/file_inclusion.rb +4 -5
- data/components/checks/active/ldap_injection.rb +6 -8
- data/components/checks/active/no_sql_injection.rb +4 -6
- data/components/checks/active/no_sql_injection_differential.rb +1 -1
- data/components/checks/active/os_cmd_injection.rb +7 -9
- data/components/checks/active/os_cmd_injection_timing.rb +6 -8
- data/components/checks/active/path_traversal.rb +6 -7
- data/components/checks/active/response_splitting.rb +7 -15
- data/components/checks/active/rfi.rb +4 -8
- data/components/checks/active/session_fixation.rb +1 -1
- data/components/checks/active/source_code_disclosure.rb +9 -7
- data/components/checks/active/sql_injection.rb +6 -9
- data/components/checks/active/sql_injection_differential.rb +3 -3
- data/components/checks/active/sql_injection_timing.rb +6 -8
- data/components/checks/active/trainer.rb +4 -4
- data/components/checks/active/unvalidated_redirect.rb +7 -6
- data/components/checks/active/unvalidated_redirect_dom.rb +97 -0
- data/components/checks/active/xpath_injection.rb +7 -8
- data/components/checks/active/xss.rb +11 -10
- data/components/checks/active/xss_dom.rb +3 -4
- data/components/checks/active/xss_dom_inputs.rb +1 -1
- data/components/checks/active/xss_dom_script_context.rb +6 -7
- data/components/checks/active/xss_event.rb +4 -4
- data/components/checks/active/xss_path.rb +1 -1
- data/components/checks/active/xss_script_context.rb +11 -4
- data/components/checks/active/xss_tag.rb +6 -6
- data/components/checks/active/xxe.rb +110 -0
- data/components/checks/passive/allowed_methods.rb +1 -1
- data/components/checks/passive/backdoors.rb +1 -1
- data/components/checks/passive/backup_directories.rb +1 -1
- data/components/checks/passive/backup_files.rb +1 -1
- data/components/checks/passive/common_directories.rb +1 -1
- data/components/checks/passive/common_directories/directories.txt +2 -0
- data/components/checks/passive/common_files.rb +1 -1
- data/components/checks/passive/directory_listing.rb +1 -1
- data/components/checks/passive/grep/captcha.rb +2 -2
- data/components/checks/passive/grep/cookie_set_for_parent_domain.rb +1 -1
- data/components/checks/passive/grep/credit_card.rb +1 -1
- data/components/checks/passive/grep/cvs_svn_users.rb +1 -1
- data/components/checks/passive/grep/emails.rb +1 -1
- data/components/checks/passive/grep/form_upload.rb +2 -2
- data/components/checks/passive/grep/hsts.rb +2 -2
- data/components/checks/passive/grep/html_objects.rb +4 -4
- data/components/checks/passive/grep/http_only_cookies.rb +1 -1
- data/components/checks/passive/grep/insecure_cookies.rb +1 -1
- data/components/checks/passive/grep/insecure_cors_policy.rb +66 -0
- data/components/checks/passive/grep/mixed_resource.rb +1 -1
- data/components/checks/passive/grep/password_autocomplete.rb +2 -2
- data/components/checks/passive/grep/private_ip.rb +1 -1
- data/components/checks/passive/grep/ssn.rb +1 -1
- data/components/checks/passive/grep/unencrypted_password_forms.rb +2 -2
- data/components/checks/passive/grep/x_frame_options.rb +61 -0
- data/components/checks/passive/htaccess_limit.rb +1 -1
- data/components/checks/passive/http_put.rb +10 -3
- data/components/checks/passive/insecure_client_access_policy.rb +91 -0
- data/components/checks/passive/insecure_cross_domain_policy_access.rb +91 -0
- data/components/checks/passive/insecure_cross_domain_policy_headers.rb +91 -0
- data/components/checks/passive/interesting_responses.rb +1 -1
- data/components/checks/passive/localstart_asp.rb +1 -1
- data/components/checks/passive/origin_spoof_access_restriction_bypass.rb +1 -1
- data/components/checks/passive/webdav.rb +1 -1
- data/components/checks/passive/xst.rb +1 -1
- data/components/fingerprinters/frameworks/rack.rb +1 -1
- data/components/fingerprinters/languages/asp.rb +1 -1
- data/components/fingerprinters/languages/aspx.rb +1 -1
- data/components/fingerprinters/languages/jsp.rb +1 -1
- data/components/fingerprinters/languages/php.rb +1 -1
- data/components/fingerprinters/languages/python.rb +1 -1
- data/components/fingerprinters/languages/ruby.rb +1 -1
- data/components/fingerprinters/os/bsd.rb +1 -1
- data/components/fingerprinters/os/linux.rb +1 -1
- data/components/fingerprinters/os/solaris.rb +1 -1
- data/components/fingerprinters/os/unix.rb +1 -1
- data/components/fingerprinters/os/windows.rb +1 -1
- data/components/fingerprinters/servers/apache.rb +1 -1
- data/components/fingerprinters/servers/iis.rb +1 -1
- data/components/fingerprinters/servers/jetty.rb +1 -1
- data/components/fingerprinters/servers/nginx.rb +1 -1
- data/components/fingerprinters/servers/tomcat.rb +1 -1
- data/components/path_extractors/anchors.rb +1 -1
- data/components/path_extractors/areas.rb +1 -1
- data/components/path_extractors/comments.rb +5 -5
- data/components/path_extractors/forms.rb +1 -1
- data/components/path_extractors/frames.rb +1 -1
- data/components/path_extractors/generic.rb +1 -1
- data/components/path_extractors/links.rb +1 -1
- data/components/path_extractors/meta_refresh.rb +1 -1
- data/components/path_extractors/scripts.rb +1 -1
- data/components/plugins/autologin.rb +6 -6
- data/components/plugins/beep_notify.rb +1 -1
- data/components/plugins/content_types.rb +1 -1
- data/components/plugins/cookie_collector.rb +1 -1
- data/components/plugins/defaults/autothrottle.rb +1 -1
- data/components/plugins/defaults/healthmap.rb +1 -1
- data/components/plugins/defaults/meta/remedies/discovery.rb +2 -4
- data/components/plugins/defaults/meta/remedies/timing_attacks.rb +1 -1
- data/components/plugins/defaults/meta/uniformity.rb +1 -1
- data/components/plugins/email_notify.rb +24 -12
- data/components/plugins/exec.rb +153 -0
- data/components/plugins/form_dicattack.rb +4 -4
- data/components/plugins/headers_collector.rb +102 -0
- data/components/plugins/http_dicattack.rb +4 -4
- data/components/plugins/login_script.rb +4 -5
- data/components/plugins/proxy.rb +19 -7
- data/components/plugins/proxy/template_scope.rb +1 -1
- data/components/plugins/script.rb +1 -1
- data/components/plugins/uncommon_headers.rb +9 -2
- data/components/plugins/vector_collector.rb +73 -0
- data/components/plugins/vector_feed.rb +3 -5
- data/components/plugins/waf_detector.rb +3 -3
- data/components/reporters/ap.rb +1 -1
- data/components/reporters/html.rb +138 -14
- data/components/reporters/html/default.erb +1 -1
- data/components/reporters/html/default/configuration.erb +2 -2
- data/components/reporters/html/default/issue/page.erb +1 -1
- data/components/reporters/html/default/issue/vector.erb +2 -2
- data/components/reporters/html/default/js/charts.js.erb +7 -4
- data/components/reporters/html/default/js/helpers.js +2 -0
- data/components/reporters/html/default/summary.erb +7 -0
- data/components/reporters/html/default/summary/charts.erb +3 -3
- data/components/reporters/html/default/summary/issues.erb +1 -91
- data/components/reporters/html/default/summary/issues/by_name.erb +90 -0
- data/components/reporters/html/default/summary/owasp_top_10.erb +43 -0
- data/components/reporters/json.rb +1 -1
- data/components/reporters/marshal.rb +1 -1
- data/components/reporters/plugin_formatters/html/autologin.rb +1 -1
- data/components/reporters/plugin_formatters/html/content_types.rb +1 -1
- data/components/reporters/plugin_formatters/html/cookie_collector.rb +1 -1
- data/components/reporters/plugin_formatters/html/exec.rb +63 -0
- data/components/reporters/plugin_formatters/html/form_dicattack.rb +1 -1
- data/components/reporters/plugin_formatters/html/healthmap.rb +1 -1
- data/components/reporters/plugin_formatters/html/http_dicattack.rb +1 -1
- data/components/reporters/plugin_formatters/html/login_script.rb +1 -1
- data/components/reporters/plugin_formatters/html/uncommon_headers.rb +1 -1
- data/components/reporters/plugin_formatters/html/uniformity.rb +1 -1
- data/components/reporters/plugin_formatters/html/vector_collector.rb +59 -0
- data/components/reporters/plugin_formatters/html/waf_detector.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/autologin.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/content_types.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/cookie_collector.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/exec.rb +26 -0
- data/components/reporters/plugin_formatters/stdout/form_dicattack.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/healthmap.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/http_dicattack.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/login_script.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/uncommon_headers.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/uniformity.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/vector_collector.rb +40 -0
- data/components/reporters/plugin_formatters/stdout/waf_detector.rb +1 -1
- data/components/reporters/plugin_formatters/xml/autologin.rb +1 -1
- data/components/reporters/plugin_formatters/xml/content_types.rb +1 -1
- data/components/reporters/plugin_formatters/xml/cookie_collector.rb +1 -1
- data/components/reporters/plugin_formatters/xml/exec.rb +26 -0
- data/components/reporters/plugin_formatters/xml/form_dicattack.rb +1 -1
- data/components/reporters/plugin_formatters/xml/healthmap.rb +1 -1
- data/components/reporters/plugin_formatters/xml/http_dicattack.rb +1 -1
- data/components/reporters/plugin_formatters/xml/login_script.rb +1 -1
- data/components/reporters/plugin_formatters/xml/uncommon_headers.rb +1 -1
- data/components/reporters/plugin_formatters/xml/uniformity.rb +1 -1
- data/components/reporters/plugin_formatters/xml/vector_collector.rb +44 -0
- data/components/reporters/plugin_formatters/xml/waf_detector.rb +1 -1
- data/components/reporters/stdout.rb +1 -1
- data/components/reporters/txt.rb +1 -1
- data/components/reporters/xml.rb +18 -9
- data/components/reporters/xml/schema.xsd +73 -8
- data/components/reporters/yaml.rb +1 -1
- data/config/write_paths.yml +15 -0
- data/lib/arachni.rb +1 -1
- data/lib/arachni/banner.rb +1 -1
- data/lib/arachni/browser.rb +221 -77
- data/lib/arachni/browser/element_locator.rb +7 -2
- data/lib/arachni/browser/javascript.rb +40 -24
- data/lib/arachni/browser/javascript/dom_monitor.rb +1 -1
- data/lib/arachni/browser/javascript/proxy.rb +1 -1
- data/lib/arachni/browser/javascript/proxy/stub.rb +1 -1
- data/lib/arachni/browser/javascript/scripts/dom_monitor.js +8 -3
- data/lib/arachni/browser/javascript/scripts/taint_tracer.js +57 -39
- data/lib/arachni/browser/javascript/taint_tracer.rb +12 -8
- data/lib/arachni/browser/javascript/taint_tracer/frame.rb +1 -1
- data/lib/arachni/browser/javascript/taint_tracer/frame/called_function.rb +1 -1
- data/lib/arachni/browser/javascript/taint_tracer/sink/base.rb +1 -1
- data/lib/arachni/browser/javascript/taint_tracer/sink/data_flow.rb +1 -1
- data/lib/arachni/browser/javascript/taint_tracer/sink/execution_flow.rb +1 -1
- data/lib/arachni/browser_cluster.rb +5 -3
- data/lib/arachni/browser_cluster/job.rb +1 -1
- data/lib/arachni/browser_cluster/job/result.rb +1 -1
- data/lib/arachni/browser_cluster/jobs/browser_provider.rb +2 -1
- data/lib/arachni/browser_cluster/jobs/resource_exploration.rb +2 -1
- data/lib/arachni/browser_cluster/jobs/resource_exploration/event_trigger.rb +1 -1
- data/lib/arachni/browser_cluster/jobs/resource_exploration/event_trigger/result.rb +1 -1
- data/lib/arachni/browser_cluster/jobs/resource_exploration/result.rb +1 -1
- data/lib/arachni/browser_cluster/jobs/taint_trace.rb +2 -1
- data/lib/arachni/browser_cluster/jobs/taint_trace/event_trigger.rb +1 -1
- data/lib/arachni/browser_cluster/jobs/taint_trace/event_trigger/result.rb +1 -1
- data/lib/arachni/browser_cluster/jobs/taint_trace/result.rb +1 -1
- data/lib/arachni/browser_cluster/worker.rb +16 -16
- data/lib/arachni/check.rb +1 -1
- data/lib/arachni/check/auditor.rb +40 -17
- data/lib/arachni/check/base.rb +1 -1
- data/lib/arachni/check/manager.rb +1 -1
- data/lib/arachni/component.rb +1 -1
- data/lib/arachni/component/base.rb +1 -1
- data/lib/arachni/component/manager.rb +1 -1
- data/lib/arachni/component/options.rb +1 -1
- data/lib/arachni/component/options/address.rb +1 -1
- data/lib/arachni/component/options/base.rb +1 -1
- data/lib/arachni/component/options/bool.rb +1 -1
- data/lib/arachni/component/options/float.rb +1 -1
- data/lib/arachni/component/options/int.rb +1 -1
- data/lib/arachni/component/options/multiple_choice.rb +1 -1
- data/lib/arachni/component/options/object.rb +1 -1
- data/lib/arachni/component/options/path.rb +1 -1
- data/lib/arachni/component/options/port.rb +1 -1
- data/lib/arachni/component/options/string.rb +1 -1
- data/lib/arachni/component/options/url.rb +1 -1
- data/lib/arachni/component/output.rb +1 -1
- data/lib/arachni/component/utilities.rb +1 -1
- data/lib/arachni/data.rb +1 -1
- data/lib/arachni/data/framework.rb +1 -1
- data/lib/arachni/data/framework/rpc.rb +1 -1
- data/lib/arachni/data/issues.rb +1 -1
- data/lib/arachni/data/plugins.rb +1 -1
- data/lib/arachni/data/session.rb +1 -1
- data/lib/arachni/element/base.rb +10 -4
- data/lib/arachni/element/body.rb +1 -6
- data/lib/arachni/element/capabilities/analyzable.rb +1 -1
- data/lib/arachni/element/capabilities/analyzable/differential.rb +41 -6
- data/lib/arachni/element/capabilities/analyzable/taint.rb +10 -2
- data/lib/arachni/element/capabilities/analyzable/timeout.rb +61 -8
- data/lib/arachni/element/capabilities/auditable.rb +9 -2
- data/lib/arachni/element/capabilities/auditable/dom.rb +6 -7
- data/lib/arachni/element/capabilities/inputtable.rb +5 -3
- data/lib/arachni/element/capabilities/mutable.rb +182 -67
- data/lib/arachni/element/capabilities/refreshable.rb +1 -1
- data/lib/arachni/element/capabilities/submittable.rb +3 -3
- data/lib/arachni/element/capabilities/with_auditor.rb +1 -1
- data/lib/arachni/element/capabilities/with_auditor/output.rb +1 -1
- data/lib/arachni/element/capabilities/with_dom.rb +17 -5
- data/lib/arachni/element/capabilities/with_node.rb +6 -31
- data/lib/arachni/element/capabilities/with_scope.rb +1 -1
- data/lib/arachni/element/capabilities/with_scope/scope.rb +8 -2
- data/lib/arachni/element/capabilities/with_source.rb +55 -0
- data/lib/arachni/element/cookie.rb +39 -112
- data/lib/arachni/element/cookie/capabilities/inputtable.rb +53 -0
- data/lib/arachni/element/cookie/capabilities/mutable.rb +95 -0
- data/lib/arachni/element/cookie/capabilities/with_dom.rb +31 -0
- data/lib/arachni/element/cookie/dom.rb +2 -2
- data/lib/arachni/element/form.rb +65 -153
- data/lib/arachni/element/form/capabilities/auditable.rb +45 -0
- data/lib/arachni/element/form/capabilities/mutable.rb +126 -0
- data/lib/arachni/element/form/capabilities/submittable.rb +36 -0
- data/lib/arachni/element/form/capabilities/with_dom.rb +32 -0
- data/lib/arachni/element/form/dom.rb +13 -4
- data/lib/arachni/element/generic_dom.rb +5 -3
- data/lib/arachni/element/header.rb +16 -11
- data/lib/arachni/element/json.rb +145 -0
- data/lib/arachni/element/json/capabilities/inputtable.rb +139 -0
- data/lib/arachni/element/json/capabilities/mutable.rb +121 -0
- data/lib/arachni/element/link.rb +14 -40
- data/lib/arachni/element/link/capabilities/auditable.rb +27 -0
- data/lib/arachni/element/link/capabilities/submittable.rb +37 -0
- data/lib/arachni/element/link/capabilities/with_dom.rb +43 -0
- data/lib/arachni/element/link/dom.rb +9 -2
- data/lib/arachni/element/link_template.rb +23 -51
- data/lib/arachni/element/link_template/capabilities/auditable.rb +27 -0
- data/lib/arachni/element/link_template/capabilities/inputtable.rb +47 -0
- data/lib/arachni/element/link_template/capabilities/with_dom.rb +42 -0
- data/lib/arachni/element/link_template/dom.rb +3 -2
- data/lib/arachni/element/path.rb +1 -1
- data/lib/arachni/element/server.rb +99 -18
- data/lib/arachni/element/xml.rb +195 -0
- data/lib/arachni/element/xml/capabilities/inputtable.rb +34 -0
- data/lib/arachni/element/xml/capabilities/mutable.rb +39 -0
- data/lib/arachni/element_filter.rb +54 -3
- data/lib/arachni/error.rb +1 -1
- data/lib/arachni/ethon/easy.rb +1 -1
- data/lib/arachni/framework.rb +20 -1
- data/lib/arachni/framework/parts/audit.rb +29 -22
- data/lib/arachni/framework/parts/browser.rb +53 -5
- data/lib/arachni/framework/parts/check.rb +11 -2
- data/lib/arachni/framework/parts/data.rb +8 -6
- data/lib/arachni/framework/parts/platform.rb +1 -1
- data/lib/arachni/framework/parts/plugin.rb +1 -1
- data/lib/arachni/framework/parts/report.rb +1 -1
- data/lib/arachni/framework/parts/scope.rb +1 -1
- data/lib/arachni/framework/parts/state.rb +5 -4
- data/lib/arachni/http.rb +1 -1
- data/lib/arachni/http/client.rb +13 -242
- data/lib/arachni/http/client/dynamic_404_handler.rb +474 -0
- data/lib/arachni/http/cookie_jar.rb +1 -1
- data/lib/arachni/http/headers.rb +11 -2
- data/lib/arachni/http/message.rb +1 -1
- data/lib/arachni/http/message/scope.rb +1 -1
- data/lib/arachni/http/proxy_server.rb +7 -4
- data/lib/arachni/http/request.rb +39 -8
- data/lib/arachni/http/request/scope.rb +1 -1
- data/lib/arachni/http/response.rb +10 -4
- data/lib/arachni/http/response/scope.rb +1 -1
- data/lib/arachni/issue.rb +17 -7
- data/lib/arachni/issue/severity.rb +1 -1
- data/lib/arachni/issue/severity/base.rb +1 -1
- data/lib/arachni/option_group.rb +1 -1
- data/lib/arachni/option_groups.rb +1 -1
- data/lib/arachni/option_groups/audit.rb +74 -6
- data/lib/arachni/option_groups/browser_cluster.rb +2 -2
- data/lib/arachni/option_groups/datastore.rb +1 -1
- data/lib/arachni/option_groups/dispatcher.rb +1 -1
- data/lib/arachni/option_groups/http.rb +143 -7
- data/lib/arachni/option_groups/input.rb +1 -1
- data/lib/arachni/option_groups/output.rb +1 -1
- data/lib/arachni/option_groups/paths.rb +1 -1
- data/lib/arachni/option_groups/rpc.rb +1 -1
- data/lib/arachni/option_groups/scope.rb +9 -9
- data/lib/arachni/option_groups/session.rb +1 -1
- data/lib/arachni/option_groups/snapshot.rb +1 -1
- data/lib/arachni/options.rb +1 -1
- data/lib/arachni/page.rb +81 -45
- data/lib/arachni/page/dom.rb +13 -3
- data/lib/arachni/page/dom/transition.rb +1 -1
- data/lib/arachni/page/scope.rb +1 -1
- data/lib/arachni/parser.rb +11 -1
- data/lib/arachni/platform.rb +1 -1
- data/lib/arachni/platform/fingerprinter.rb +1 -1
- data/lib/arachni/platform/list.rb +1 -1
- data/lib/arachni/platform/manager.rb +1 -1
- data/lib/arachni/plugin.rb +1 -1
- data/lib/arachni/plugin/base.rb +11 -4
- data/lib/arachni/plugin/formatter.rb +1 -1
- data/lib/arachni/plugin/manager.rb +13 -5
- data/lib/arachni/processes.rb +1 -1
- data/lib/arachni/processes/dispatchers.rb +1 -1
- data/lib/arachni/processes/helpers.rb +1 -1
- data/lib/arachni/processes/helpers/dispatchers.rb +1 -1
- data/lib/arachni/processes/helpers/instances.rb +1 -1
- data/lib/arachni/processes/helpers/processes.rb +1 -1
- data/lib/arachni/processes/instances.rb +1 -1
- data/lib/arachni/processes/manager.rb +8 -3
- data/lib/arachni/report.rb +12 -2
- data/lib/arachni/reporter.rb +1 -1
- data/lib/arachni/reporter/base.rb +1 -1
- data/lib/arachni/reporter/formatter_manager.rb +1 -1
- data/lib/arachni/reporter/manager.rb +1 -1
- data/lib/arachni/reporter/options.rb +1 -1
- data/lib/arachni/rpc/client/base.rb +1 -1
- data/lib/arachni/rpc/client/dispatcher.rb +1 -1
- data/lib/arachni/rpc/client/instance.rb +1 -1
- data/lib/arachni/rpc/client/instance/framework.rb +1 -1
- data/lib/arachni/rpc/client/instance/service.rb +1 -1
- data/lib/arachni/rpc/serializer.rb +3 -1
- data/lib/arachni/rpc/server/active_options.rb +1 -25
- data/lib/arachni/rpc/server/base.rb +1 -1
- data/lib/arachni/rpc/server/check/manager.rb +1 -1
- data/lib/arachni/rpc/server/dispatcher.rb +1 -1
- data/lib/arachni/rpc/server/dispatcher/node.rb +1 -1
- data/lib/arachni/rpc/server/dispatcher/service.rb +1 -1
- data/lib/arachni/rpc/server/framework.rb +1 -1
- data/lib/arachni/rpc/server/framework/distributor.rb +2 -6
- data/lib/arachni/rpc/server/framework/master.rb +1 -1
- data/lib/arachni/rpc/server/framework/multi_instance.rb +1 -1
- data/lib/arachni/rpc/server/framework/slave.rb +1 -1
- data/lib/arachni/rpc/server/instance.rb +9 -1
- data/lib/arachni/rpc/server/output.rb +1 -1
- data/lib/arachni/rpc/server/plugin/manager.rb +1 -1
- data/lib/arachni/ruby.rb +1 -1
- data/lib/arachni/ruby/array.rb +1 -1
- data/lib/arachni/ruby/hash.rb +1 -1
- data/lib/arachni/ruby/io.rb +1 -1
- data/lib/arachni/ruby/object.rb +1 -1
- data/lib/arachni/ruby/set.rb +1 -1
- data/lib/arachni/ruby/string.rb +1 -1
- data/lib/arachni/ruby/webrick.rb +1 -1
- data/lib/arachni/ruby/webrick/cookie.rb +1 -1
- data/lib/arachni/ruby/webrick/httprequest.rb +1 -1
- data/lib/arachni/scope.rb +1 -1
- data/lib/arachni/selenium/webdriver/remote/http/typhoeus.rb +19 -2
- data/lib/arachni/session.rb +8 -3
- data/lib/arachni/snapshot.rb +1 -1
- data/lib/arachni/state.rb +1 -1
- data/lib/arachni/state/audit.rb +1 -1
- data/lib/arachni/state/element_filter.rb +12 -20
- data/lib/arachni/state/framework.rb +1 -1
- data/lib/arachni/state/framework/rpc.rb +1 -1
- data/lib/arachni/state/http.rb +1 -1
- data/lib/arachni/state/options.rb +1 -1
- data/lib/arachni/state/plugins.rb +1 -1
- data/lib/arachni/support.rb +1 -1
- data/lib/arachni/support/buffer.rb +1 -1
- data/lib/arachni/support/buffer/autoflush.rb +1 -1
- data/lib/arachni/support/buffer/base.rb +1 -1
- data/lib/arachni/support/cache.rb +1 -1
- data/lib/arachni/support/cache/base.rb +1 -1
- data/lib/arachni/support/cache/least_cost_replacement.rb +1 -1
- data/lib/arachni/support/cache/least_recently_used.rb +1 -1
- data/lib/arachni/support/cache/preference.rb +1 -1
- data/lib/arachni/support/cache/random_replacement.rb +1 -1
- data/lib/arachni/support/crypto.rb +1 -1
- data/lib/arachni/support/crypto/rsa_aes_cbc.rb +1 -1
- data/lib/arachni/support/database.rb +1 -1
- data/lib/arachni/support/database/base.rb +1 -1
- data/lib/arachni/support/database/hash.rb +1 -1
- data/lib/arachni/support/database/queue.rb +1 -1
- data/lib/arachni/support/lookup.rb +1 -1
- data/lib/arachni/support/lookup/base.rb +1 -1
- data/lib/arachni/support/lookup/hash_set.rb +1 -1
- data/lib/arachni/support/lookup/moolb.rb +1 -1
- data/lib/arachni/support/mixins.rb +1 -1
- data/lib/arachni/support/mixins/observable.rb +1 -1
- data/lib/arachni/support/mixins/terminal.rb +1 -1
- data/lib/arachni/support/profiler.rb +1 -1
- data/lib/arachni/support/signature.rb +1 -1
- data/lib/arachni/trainer.rb +8 -1
- data/lib/arachni/ui/foo/output.rb +1 -1
- data/lib/arachni/uri.rb +79 -57
- data/lib/arachni/uri/scope.rb +17 -6
- data/lib/arachni/utilities.rb +8 -3
- data/lib/arachni/version.rb +1 -1
- data/lib/arachni/watir/element.rb +22 -1
- data/lib/version +1 -1
- data/spec/arachni/browser/element_locator_spec.rb +38 -1
- data/spec/arachni/browser/javascript/dom_monitor_spec.rb +21 -6
- data/spec/arachni/browser/javascript/taint_tracer_spec.rb +351 -216
- data/spec/arachni/browser/javascript_spec.rb +26 -6
- data/spec/arachni/browser_spec.rb +205 -53
- data/spec/arachni/check/auditor_spec.rb +36 -12
- data/spec/arachni/element/capabilities/analyzable/differential_spec.rb +84 -42
- data/spec/arachni/element/capabilities/analyzable/taint_spec.rb +2 -0
- data/spec/arachni/element/capabilities/analyzable/timeout_spec.rb +87 -19
- data/spec/arachni/element/capabilities/with_scope/scope_spec.rb +9 -0
- data/spec/arachni/element/cookie/dom_spec.rb +2 -2
- data/spec/arachni/element/cookie_spec.rb +28 -7
- data/spec/arachni/element/form/dom_spec.rb +2 -2
- data/spec/arachni/element/form_spec.rb +39 -7
- data/spec/arachni/element/generic_dom_spec.rb +13 -6
- data/spec/arachni/element/header_spec.rb +2 -2
- data/spec/arachni/element/json_spec.rb +522 -0
- data/spec/arachni/element/link/dom_spec.rb +2 -2
- data/spec/arachni/element/link_spec.rb +12 -12
- data/spec/arachni/element/link_template/dom_spec.rb +1 -1
- data/spec/arachni/element/link_template_spec.rb +13 -13
- data/spec/arachni/element/server_spec.rb +50 -8
- data/spec/arachni/element/xml_spec.rb +247 -0
- data/spec/arachni/framework/parts/audit_spec.rb +13 -6
- data/spec/arachni/framework/parts/browser_spec.rb +276 -10
- data/spec/arachni/framework/parts/state_spec.rb +20 -2
- data/spec/arachni/http/client/dynamic_404_handlers_spec.rb +274 -0
- data/spec/arachni/http/client_spec.rb +4 -241
- data/spec/arachni/http/proxy_server_spec.rb +8 -0
- data/spec/arachni/http/request_spec.rb +129 -1
- data/spec/arachni/http/response_spec.rb +20 -0
- data/spec/arachni/issue_spec.rb +3 -3
- data/spec/arachni/option_groups/audit_spec.rb +32 -0
- data/spec/arachni/option_groups/http_spec.rb +70 -4
- data/spec/arachni/options_spec.rb +6 -6
- data/spec/arachni/page_spec.rb +89 -1
- data/spec/arachni/report_spec.rb +17 -0
- data/spec/arachni/session_spec.rb +3 -14
- data/spec/arachni/trainer_spec.rb +24 -5
- data/spec/arachni/uri/scope_spec.rb +97 -7
- data/spec/arachni/uri_spec.rb +41 -0
- data/spec/arachni/utilities_spec.rb +2 -1
- data/spec/components/checks/active/code_injection_spec.rb +47 -7
- data/spec/components/checks/active/code_injection_timing_spec.rb +4 -2
- data/spec/components/checks/active/file_inclusion_spec.rb +16 -6
- data/spec/components/checks/active/ldap_injection_spec.rb +13 -4
- data/spec/components/checks/active/no_sql_injection_spec.rb +4 -2
- data/spec/components/checks/active/os_cmd_injection_spec.rb +15 -11
- data/spec/components/checks/active/os_cmd_injection_timing_spec.rb +4 -2
- data/spec/components/checks/active/path_traversal_spec.rb +11 -5
- data/spec/components/checks/active/response_splitting_spec.rb +4 -2
- data/spec/components/checks/active/rfi_spec.rb +5 -2
- data/spec/components/checks/active/source_code_disclosure_spec.rb +6 -4
- data/spec/components/checks/active/sql_injection_spec.rb +52 -26
- data/spec/components/checks/active/sql_injection_timing_spec.rb +29 -5
- data/spec/components/checks/active/unvalidated_redirect_dom_spec.rb +19 -0
- data/spec/components/checks/active/unvalidated_redirect_spec.rb +5 -2
- data/spec/components/checks/active/xpath_injection_spec.rb +11 -3
- data/spec/components/checks/active/xss_dom_script_context_spec.rb +4 -4
- data/spec/components/checks/active/xss_script_context_spec.rb +5 -5
- data/spec/components/checks/active/xss_tag_spec.rb +1 -1
- data/spec/components/checks/active/xxe_spec.rb +19 -0
- data/spec/components/checks/passive/grep/hsts_spec.rb +10 -2
- data/spec/components/checks/passive/grep/insecure_cors_policy_spec.rb +25 -0
- data/spec/components/checks/passive/grep/x_frame_options_spec.rb +25 -0
- data/spec/components/checks/passive/insecure_client_access_policy_spec.rb +15 -0
- data/spec/components/checks/passive/insecure_cross_domain_policy_access_spec.rb +15 -0
- data/spec/components/checks/passive/insecure_cross_domain_policy_headers_spec.rb +15 -0
- data/spec/components/plugins/exec_spec.rb +56 -0
- data/spec/components/plugins/headers_collector_spec.rb +126 -0
- data/spec/components/plugins/vector_collector_spec.rb +55 -0
- data/spec/spec_helper.rb +2 -1
- data/spec/support/factories/element/form.rb +1 -1
- data/spec/support/factories/element/json.rb +5 -0
- data/spec/support/factories/element/link.rb +1 -1
- data/spec/support/factories/element/link_template.rb +1 -1
- data/spec/support/factories/element/xml.rb +5 -0
- data/spec/support/factories/page.rb +11 -2
- data/spec/support/fixtures/check_with_invalid_platforms/with_invalid_platforms.rb +1 -1
- data/spec/support/fixtures/checks/test.rb +1 -1
- data/spec/support/fixtures/checks/test2.rb +1 -1
- data/spec/support/fixtures/checks/test3.rb +1 -1
- data/spec/support/fixtures/fingerprinters/test.rb +1 -1
- data/spec/support/fixtures/plugins/bad.rb +1 -1
- data/spec/support/fixtures/plugins/defaults/default.rb +1 -1
- data/spec/support/fixtures/plugins/distributable.rb +1 -1
- data/spec/support/fixtures/plugins/loop.rb +1 -1
- data/spec/support/fixtures/plugins/suspendable.rb +1 -1
- data/spec/support/fixtures/plugins/wait.rb +1 -1
- data/spec/support/fixtures/plugins/with_options.rb +1 -1
- data/spec/support/fixtures/plugins_with_priorities/p0.rb +1 -1
- data/spec/support/fixtures/plugins_with_priorities/p00.rb +1 -1
- data/spec/support/fixtures/plugins_with_priorities/p1.rb +1 -1
- data/spec/support/fixtures/plugins_with_priorities/p2.rb +1 -1
- data/spec/support/fixtures/plugins_with_priorities/p22.rb +1 -1
- data/spec/support/fixtures/plugins_with_priorities/p222.rb +1 -1
- data/spec/support/fixtures/plugins_with_priorities/p_nil.rb +1 -1
- data/spec/support/fixtures/plugins_with_priorities/p_nil2.rb +1 -1
- data/spec/support/fixtures/report.afr +0 -0
- data/spec/support/fixtures/reporters/base_spec/plugin_formatters/with_formatters/foobar.rb +1 -1
- data/spec/support/fixtures/reporters/base_spec/with_formatters.rb +1 -1
- data/spec/support/fixtures/reporters/base_spec/with_outfile.rb +1 -1
- data/spec/support/fixtures/reporters/base_spec/without_outfile.rb +1 -1
- data/spec/support/fixtures/reporters/manager_spec/afr.rb +1 -1
- data/spec/support/fixtures/reporters/manager_spec/foo.rb +1 -1
- data/spec/support/fixtures/run_check/body.rb +1 -1
- data/spec/support/fixtures/run_check/cookies.rb +1 -1
- data/spec/support/fixtures/run_check/empty.rb +1 -1
- data/spec/support/fixtures/run_check/flch.rb +1 -1
- data/spec/support/fixtures/run_check/forms.rb +1 -1
- data/spec/support/fixtures/run_check/headers.rb +1 -1
- data/spec/support/fixtures/run_check/links.rb +1 -1
- data/spec/support/fixtures/run_check/nil.rb +1 -1
- data/spec/support/fixtures/run_check/path.rb +1 -1
- data/spec/support/fixtures/run_check/server.rb +1 -1
- data/spec/support/fixtures/taint_check/taint.rb +1 -1
- data/spec/support/fixtures/wait_check/wait.rb +1 -1
- data/spec/support/helpers/framework.rb +1 -1
- data/spec/support/helpers/misc.rb +1 -1
- data/spec/support/helpers/pages.rb +23 -14
- data/spec/support/helpers/paths.rb +1 -1
- data/spec/support/helpers/requires.rb +1 -1
- data/spec/support/helpers/resets.rb +1 -1
- data/spec/support/helpers/web_server.rb +1 -1
- data/spec/support/lib/factory.rb +1 -1
- data/spec/support/lib/web_server_client.rb +1 -1
- data/spec/support/lib/web_server_dispatcher.rb +1 -1
- data/spec/support/lib/web_server_manager.rb +1 -1
- data/spec/support/servers/arachni/browser.rb +77 -3
- data/spec/support/servers/arachni/browser/javascript/angular-1.2.8.js +1 -1
- data/spec/support/servers/arachni/browser/javascript/angular-route.js +1 -1
- data/spec/support/servers/arachni/browser/javascript/dom_monitor.rb +24 -1
- data/spec/support/servers/arachni/browser/javascript/jquery.cookie.js +117 -0
- data/spec/support/servers/arachni/browser/javascript/taint_tracer.rb +58 -1
- data/spec/support/servers/arachni/element/capabilities/analyzable/timeout.rb +6 -0
- data/spec/support/servers/arachni/element/json.rb +5 -0
- data/spec/support/servers/arachni/element/xml.rb +5 -0
- data/spec/support/servers/arachni/http/client.rb +0 -22
- data/spec/support/servers/arachni/http/client/dynamic_404_handler.rb +47 -0
- data/spec/support/servers/arachni/trainer.rb +10 -0
- data/spec/support/servers/checks/active/code_injection.rb +69 -42
- data/spec/support/servers/checks/active/code_injection_timing.rb +115 -0
- data/spec/support/servers/checks/active/file_inclusion.rb +117 -2
- data/spec/support/servers/checks/active/ldap_injection.rb +114 -0
- data/spec/support/servers/checks/active/no_sql_injection.rb +81 -0
- data/spec/support/servers/checks/active/os_cmd_injection.rb +116 -0
- data/spec/support/servers/checks/active/os_cmd_injection_timing.rb +77 -5
- data/spec/support/servers/checks/active/path_traversal.rb +154 -2
- data/spec/support/servers/checks/active/response_splitting.rb +117 -0
- data/spec/support/servers/checks/active/rfi.rb +117 -0
- data/spec/support/servers/checks/active/source_code_disclosure.rb +109 -0
- data/spec/support/servers/checks/active/sql_injection.rb +125 -0
- data/spec/support/servers/checks/active/sql_injection_timing.rb +114 -0
- data/spec/support/servers/checks/active/unvalidated_redirect.rb +117 -1
- data/spec/support/servers/checks/active/unvalidated_redirect_dom.rb +115 -0
- data/spec/support/servers/checks/active/xpath_injection.rb +117 -0
- data/spec/support/servers/checks/active/xss_script_context.rb +16 -32
- data/spec/support/servers/checks/active/xss_tag.rb +12 -12
- data/spec/support/servers/checks/active/xxe.rb +85 -0
- data/spec/support/servers/checks/passive/grep/insecure_cors_policy.rb +8 -0
- data/spec/support/servers/checks/passive/grep/x_frame_options.rb +9 -0
- data/spec/support/servers/checks/passive/insecure_client_access_policy.rb +9 -0
- data/spec/support/servers/checks/passive/insecure_cross_domain_policy_access.rb +13 -0
- data/spec/support/servers/checks/passive/insecure_cross_domain_policy_headers.rb +13 -0
- data/spec/support/servers/plugins/headers_collector.rb +16 -0
- data/spec/support/servers/plugins/vector_collector.rb +13 -0
- data/spec/support/shared/check.rb +6 -1
- data/spec/support/shared/element/base.rb +16 -9
- data/spec/support/shared/element/capabilities/auditable.rb +22 -15
- data/spec/support/shared/element/capabilities/auditable/dom.rb +7 -14
- data/spec/support/shared/element/capabilities/inputtable.rb +46 -61
- data/spec/support/shared/element/capabilities/mutable.rb +159 -64
- data/spec/support/shared/element/capabilities/with_dom.rb +52 -3
- data/spec/support/shared/element/capabilities/with_node.rb +2 -44
- data/spec/support/shared/element/capabilities/with_scope.rb +1 -1
- data/spec/support/shared/element/capabilities/with_source.rb +55 -0
- data/ui/cli/framework.rb +9 -9
- data/ui/cli/framework/option_parser.rb +75 -3
- data/ui/cli/option_parser.rb +1 -1
- data/ui/cli/output.rb +1 -1
- data/ui/cli/reporter.rb +1 -1
- data/ui/cli/reporter/option_parser.rb +1 -1
- data/ui/cli/restored_framework.rb +1 -1
- data/ui/cli/restored_framework/option_parser.rb +1 -1
- data/ui/cli/rpc/client/dispatcher_monitor.rb +1 -1
- data/ui/cli/rpc/client/dispatcher_monitor/option_parser.rb +1 -1
- data/ui/cli/rpc/client/instance.rb +5 -4
- data/ui/cli/rpc/client/local.rb +1 -1
- data/ui/cli/rpc/client/local/option_parser.rb +1 -1
- data/ui/cli/rpc/client/remote.rb +1 -1
- data/ui/cli/rpc/client/remote/option_parser.rb +1 -1
- data/ui/cli/rpc/server/dispatcher.rb +1 -1
- data/ui/cli/rpc/server/dispatcher/option_parser.rb +1 -1
- data/ui/cli/utilities.rb +4 -1
- metadata +129 -19
- data/lib/arachni/nokogiri/xml/node.rb +0 -42
@@ -1,5 +1,5 @@
|
|
1
1
|
=begin
|
2
|
-
Copyright 2010-
|
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
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Sets default locations for writing files.
|
2
|
+
#
|
3
|
+
# * '~' will be expanded to $HOME.
|
4
|
+
# * Directories will be created if they don't already exist.
|
5
|
+
|
6
|
+
cli:
|
7
|
+
# Default directory for AFR reports generated by CLI interfaces, either
|
8
|
+
# local or RPC clients.
|
9
|
+
report_path:
|
10
|
+
framework:
|
11
|
+
# Error and RPC logs.
|
12
|
+
logs:
|
13
|
+
# Default directory for scan snapshots generated either by the CLI
|
14
|
+
# or by RPC Instances.
|
15
|
+
snapshots:
|
data/lib/arachni.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
=begin
|
2
|
-
Copyright 2010-
|
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
|
data/lib/arachni/banner.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
=begin
|
2
|
-
Copyright 2010-
|
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
|
data/lib/arachni/browser.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
=begin
|
2
|
-
Copyright 2010-
|
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
|
@@ -190,6 +190,17 @@ class Browser
|
|
190
190
|
ensure_open_window
|
191
191
|
end
|
192
192
|
|
193
|
+
def clear_buffers
|
194
|
+
synchronize do
|
195
|
+
@preloads.clear
|
196
|
+
@cache.clear
|
197
|
+
@captured_pages.clear
|
198
|
+
@page_snapshots.clear
|
199
|
+
@page_snapshots_with_sinks.clear
|
200
|
+
@window_responses.clear
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
193
204
|
# @return [String]
|
194
205
|
# Prefixes each source line with a number.
|
195
206
|
def source_with_line_numbers
|
@@ -337,7 +348,12 @@ class Browser
|
|
337
348
|
end
|
338
349
|
|
339
350
|
def shutdown
|
340
|
-
|
351
|
+
begin
|
352
|
+
watir.close if browser_alive?
|
353
|
+
rescue Selenium::WebDriver::Error::WebDriverError,
|
354
|
+
Watir::Exception::Error
|
355
|
+
end
|
356
|
+
|
341
357
|
kill_process
|
342
358
|
@proxy.shutdown
|
343
359
|
end
|
@@ -397,7 +413,7 @@ class Browser
|
|
397
413
|
href = attributes['href'].to_s
|
398
414
|
|
399
415
|
if !href.empty?
|
400
|
-
if href.start_with?( 'javascript:' )
|
416
|
+
if href.downcase.start_with?( 'javascript:' )
|
401
417
|
events << [ :click, href ]
|
402
418
|
else
|
403
419
|
next if skip_path?( to_absolute( href, current_url ) )
|
@@ -413,7 +429,7 @@ class Browser
|
|
413
429
|
action = attributes['action'].to_s
|
414
430
|
|
415
431
|
if !action.empty?
|
416
|
-
if action.start_with?( 'javascript:' )
|
432
|
+
if action.downcase.start_with?( 'javascript:' )
|
417
433
|
events << [ :submit, action ]
|
418
434
|
else
|
419
435
|
next if skip_path?( to_absolute( action, current_url ) )
|
@@ -421,9 +437,13 @@ class Browser
|
|
421
437
|
end
|
422
438
|
end
|
423
439
|
|
424
|
-
|
425
|
-
|
426
|
-
|
440
|
+
next if events.empty?
|
441
|
+
|
442
|
+
if mark_state
|
443
|
+
state = "#{tag_name}#{attributes}#{events}"
|
444
|
+
next if skip_state?( state )
|
445
|
+
skip_state state
|
446
|
+
end
|
427
447
|
|
428
448
|
yield ElementLocator.new( tag_name: tag_name, attributes: attributes ),
|
429
449
|
events
|
@@ -445,33 +465,38 @@ class Browser
|
|
445
465
|
javascript.dom_elements_with_events.each do |element|
|
446
466
|
tag_name = element['tag_name']
|
447
467
|
attributes = element['attributes']
|
448
|
-
events = element['events']
|
468
|
+
events = element['events'] +
|
469
|
+
Javascript.select_event_attributes( attributes ).to_a
|
470
|
+
element_id = attributes['id'].to_s
|
449
471
|
|
450
472
|
case tag_name
|
451
473
|
when 'a'
|
452
|
-
href
|
474
|
+
href = attributes['href'].to_s
|
475
|
+
element_id << href
|
453
476
|
|
454
477
|
if !href.empty?
|
455
|
-
if href.start_with?( 'javascript:' )
|
478
|
+
if href.downcase.start_with?( 'javascript:' )
|
456
479
|
events << [ :click, href ]
|
457
480
|
else
|
458
481
|
absolute = to_absolute( href, current_url )
|
459
|
-
if
|
460
|
-
|
461
|
-
|
482
|
+
next if skip_path?( absolute )
|
483
|
+
|
484
|
+
events << [ :click, href ]
|
462
485
|
end
|
463
486
|
else
|
464
487
|
events << [ :click, current_url ]
|
465
488
|
end
|
466
489
|
|
467
490
|
when 'input', 'textarea', 'select'
|
468
|
-
events
|
491
|
+
events << [ tag_name.to_sym ]
|
492
|
+
element_id << attributes['name'].to_s
|
469
493
|
|
470
494
|
when 'form'
|
471
|
-
action
|
495
|
+
action = attributes['action'].to_s
|
496
|
+
element_id << "#{action}#{attributes['name']}"
|
472
497
|
|
473
498
|
if !action.empty?
|
474
|
-
if action.start_with?( 'javascript:' )
|
499
|
+
if action.downcase.start_with?( 'javascript:' )
|
475
500
|
events << [ :submit, action ]
|
476
501
|
else
|
477
502
|
absolute = to_absolute( action, current_url )
|
@@ -485,10 +510,11 @@ class Browser
|
|
485
510
|
end
|
486
511
|
|
487
512
|
next if events.empty?
|
488
|
-
|
513
|
+
|
514
|
+
id << "#{tag_name}:#{element_id}:#{events}"
|
489
515
|
end
|
490
516
|
|
491
|
-
id.sort.to_s
|
517
|
+
id.uniq.sort.to_s
|
492
518
|
end
|
493
519
|
|
494
520
|
# Triggers all events on all elements (**once**) and captures
|
@@ -571,10 +597,11 @@ class Browser
|
|
571
597
|
|
572
598
|
begin
|
573
599
|
element = element.locate( self )
|
574
|
-
rescue Selenium::WebDriver::Error::
|
575
|
-
Watir::Exception::
|
600
|
+
rescue Selenium::WebDriver::Error::WebDriverError,
|
601
|
+
Watir::Exception::Error => e
|
576
602
|
|
577
|
-
print_debug "Element '#{
|
603
|
+
print_debug "Element '#{element.inspect}' could not be " <<
|
604
|
+
"located for triggering '#{event}'."
|
578
605
|
print_debug
|
579
606
|
print_debug_exception e
|
580
607
|
return
|
@@ -588,12 +615,13 @@ class Browser
|
|
588
615
|
sleep 0.1 while !element.exists?
|
589
616
|
end
|
590
617
|
rescue Timeout::Error
|
591
|
-
print_debug_level_2 "#{
|
618
|
+
print_debug_level_2 "#{element.inspect} did not appear in " <<
|
619
|
+
"#{ELEMENT_APPEARANCE_TIMEOUT}."
|
592
620
|
return
|
593
621
|
end
|
594
622
|
|
595
623
|
if !element.visible?
|
596
|
-
print_debug_level_2 "#{
|
624
|
+
print_debug_level_2 "#{element.inspect} is not visible, skipping..."
|
597
625
|
return
|
598
626
|
end
|
599
627
|
|
@@ -606,7 +634,7 @@ class Browser
|
|
606
634
|
locator = ElementLocator.from_html( opening_tag )
|
607
635
|
end
|
608
636
|
|
609
|
-
print_debug_level_2 "#{__method__}: #{event} (#{options}) #{locator}"
|
637
|
+
print_debug_level_2 "#{__method__} [start]: #{event} (#{options}) #{locator}"
|
610
638
|
|
611
639
|
tag_name = tag_name.to_sym
|
612
640
|
|
@@ -621,15 +649,14 @@ class Browser
|
|
621
649
|
fill_in_form_inputs( element, options[:inputs] )
|
622
650
|
|
623
651
|
if event == :submit
|
652
|
+
element.to_subtype.submit
|
624
653
|
had_special_trigger = true
|
625
|
-
element.submit
|
626
654
|
end
|
627
|
-
|
628
655
|
elsif tag_name == :input && event == :click &&
|
629
656
|
element.attribute_value(:type) == 'image'
|
630
657
|
|
658
|
+
element.to_subtype.click
|
631
659
|
had_special_trigger = true
|
632
|
-
watir.button( type: 'image' ).click
|
633
660
|
|
634
661
|
elsif [:keyup, :keypress, :keydown, :change, :input, :focus, :blur, :select].include? event
|
635
662
|
|
@@ -640,11 +667,16 @@ class Browser
|
|
640
667
|
end
|
641
668
|
|
642
669
|
element.fire_event( event ) if !had_special_trigger
|
670
|
+
|
671
|
+
print_debug_level_2 "#{__method__} [waiting for requests]: #{event} (#{options}) #{locator}"
|
643
672
|
wait_for_pending_requests
|
673
|
+
print_debug_level_2 "#{__method__} [done waiting for requests]: #{event} (#{options}) #{locator}"
|
674
|
+
|
675
|
+
# puts source_with_line_numbers
|
676
|
+
print_debug_level_2 "#{__method__} [done]: #{event} (#{options}) #{locator}"
|
644
677
|
end
|
645
|
-
rescue Selenium::WebDriver::Error::
|
646
|
-
|
647
|
-
Watir::Exception::UnknownObjectException => e
|
678
|
+
rescue Selenium::WebDriver::Error::WebDriverError,
|
679
|
+
Watir::Exception::Error => e
|
648
680
|
|
649
681
|
sleep 0.1
|
650
682
|
|
@@ -714,11 +746,20 @@ class Browser
|
|
714
746
|
# @return [Page]
|
715
747
|
# Converts the current browser window to a {Page page}.
|
716
748
|
def to_page
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
749
|
+
if !(r = response)
|
750
|
+
return Page.from_data(
|
751
|
+
dom: {
|
752
|
+
url: watir.url
|
753
|
+
},
|
754
|
+
response: {
|
755
|
+
code: 0,
|
756
|
+
url: url
|
757
|
+
}
|
758
|
+
)
|
759
|
+
end
|
721
760
|
|
761
|
+
page = r.to_page
|
762
|
+
page.body = source
|
722
763
|
page.dom.url = watir.url
|
723
764
|
page.dom.digest = @javascript.dom_digest
|
724
765
|
page.dom.execution_flow_sinks = @javascript.execution_flow_sinks
|
@@ -726,6 +767,38 @@ class Browser
|
|
726
767
|
page.dom.transitions = @transitions.dup
|
727
768
|
page.dom.skip_states = skip_states.dup
|
728
769
|
|
770
|
+
# Go through auditable DOM forms and cookies and remove the DOM from
|
771
|
+
# them if no events are associated with it.
|
772
|
+
#
|
773
|
+
# This can save **A LOT** of time during the audit.
|
774
|
+
if Options.audit.form_doms? && @javascript.supported?
|
775
|
+
page.forms.each do |form|
|
776
|
+
next if !form.node || !form.dom
|
777
|
+
|
778
|
+
action = form.node['action'].to_s
|
779
|
+
form.dom.browser = self
|
780
|
+
|
781
|
+
next if action.downcase.start_with?( 'javascript:' ) ||
|
782
|
+
form.dom.locate.events.any?
|
783
|
+
|
784
|
+
form.skip_dom = true
|
785
|
+
end
|
786
|
+
|
787
|
+
page.update_metadata
|
788
|
+
end
|
789
|
+
|
790
|
+
if Options.audit.cookie_doms? && @javascript.supported?
|
791
|
+
sinks = @javascript.taint_tracer.data_flow_sinks
|
792
|
+
page.cookies.each do |cookie|
|
793
|
+
next if sinks.include?( cookie.name ) ||
|
794
|
+
sinks.include?( cookie.value )
|
795
|
+
|
796
|
+
cookie.skip_dom = true
|
797
|
+
end
|
798
|
+
|
799
|
+
page.update_metadata
|
800
|
+
end
|
801
|
+
|
729
802
|
page
|
730
803
|
end
|
731
804
|
|
@@ -750,7 +823,7 @@ class Browser
|
|
750
823
|
|
751
824
|
capture_snapshot_with_sink( page )
|
752
825
|
|
753
|
-
unique_id
|
826
|
+
unique_id = self.snapshot_id
|
754
827
|
next if skip_state? unique_id
|
755
828
|
skip_state unique_id
|
756
829
|
|
@@ -808,7 +881,7 @@ class Browser
|
|
808
881
|
# this out ourselves, by checking for JS visibility.
|
809
882
|
javascript.run( 'return document.cookie' )
|
810
883
|
# We may not have a page.
|
811
|
-
rescue Selenium::WebDriver::Error::
|
884
|
+
rescue Selenium::WebDriver::Error::WebDriverError
|
812
885
|
''
|
813
886
|
end
|
814
887
|
|
@@ -887,6 +960,14 @@ class Browser
|
|
887
960
|
)
|
888
961
|
end
|
889
962
|
|
963
|
+
def inspect
|
964
|
+
s = "#<#{self.class} "
|
965
|
+
s << "pid=#{@pid} "
|
966
|
+
s << "last-url=#{@last_url.inspect} "
|
967
|
+
s << "transitions=#{@transitions.size}"
|
968
|
+
s << '>'
|
969
|
+
end
|
970
|
+
|
890
971
|
private
|
891
972
|
|
892
973
|
def fill_in_form_inputs( form, inputs = nil )
|
@@ -895,11 +976,10 @@ class Browser
|
|
895
976
|
value = inputs ? inputs[name_or_id] : value_for( input )
|
896
977
|
|
897
978
|
begin
|
898
|
-
input.set( value.to_s )
|
979
|
+
input.set( value.to_s.recode )
|
899
980
|
# Disabled inputs and such...
|
900
|
-
rescue
|
901
|
-
Watir::Exception::
|
902
|
-
Selenium::WebDriver::Error::InvalidElementStateError => e
|
981
|
+
rescue Selenium::WebDriver::Error::WebDriverError,
|
982
|
+
Watir::Exception::Error => e
|
903
983
|
print_debug_level_2 "Could not fill in form input '#{name_or_id}'" <<
|
904
984
|
" because: #{e} [#{e.class}"
|
905
985
|
end
|
@@ -910,12 +990,10 @@ class Browser
|
|
910
990
|
value = inputs ? inputs[name_or_id] : value_for( input )
|
911
991
|
|
912
992
|
begin
|
913
|
-
input.select_value( value.to_s )
|
993
|
+
input.select_value( value.to_s.recode )
|
914
994
|
# Disabled inputs and such...
|
915
|
-
rescue
|
916
|
-
Watir::Exception::
|
917
|
-
Watir::Exception::NoValueFoundException,
|
918
|
-
Selenium::WebDriver::Error::InvalidElementStateError => e
|
995
|
+
rescue Selenium::WebDriver::Error::WebDriverError,
|
996
|
+
Watir::Exception::Error => e
|
919
997
|
print_debug_level_2 "Could not fill in form select '#{name_or_id}'" <<
|
920
998
|
" because: #{e} [#{e.class}"
|
921
999
|
end
|
@@ -995,8 +1073,10 @@ class Browser
|
|
995
1073
|
"--webdriver=#{port}",
|
996
1074
|
"--proxy=http://#{@proxy.address}/",
|
997
1075
|
'--ignore-ssl-errors=true',
|
1076
|
+
'--disk-cache=true',
|
998
1077
|
"--debug=#{!!debug?}"
|
999
1078
|
)
|
1079
|
+
# @process.leader = true
|
1000
1080
|
@process.detach = true
|
1001
1081
|
|
1002
1082
|
@process.io.stdout = Tempfile.new( 'phantomjs-out' )
|
@@ -1058,13 +1138,18 @@ class Browser
|
|
1058
1138
|
end
|
1059
1139
|
|
1060
1140
|
def kill_process
|
1061
|
-
|
1062
|
-
@process.
|
1063
|
-
|
1141
|
+
begin
|
1142
|
+
if @process && @process.alive?
|
1143
|
+
@process.stop
|
1144
|
+
@process.io.close rescue nil
|
1145
|
+
end
|
1146
|
+
rescue Errno::ECHILD
|
1147
|
+
false
|
1064
1148
|
end
|
1065
1149
|
|
1066
1150
|
@process = nil
|
1067
1151
|
@watir = nil
|
1152
|
+
@selenium = nil
|
1068
1153
|
@pid = nil
|
1069
1154
|
@browser_url = nil
|
1070
1155
|
end
|
@@ -1198,6 +1283,8 @@ class Browser
|
|
1198
1283
|
end
|
1199
1284
|
|
1200
1285
|
def request_handler( request, response )
|
1286
|
+
request.performer = self
|
1287
|
+
|
1201
1288
|
return if request.headers['X-Arachni-Browser-Auth'] != auth_token
|
1202
1289
|
request.headers.delete( 'X-Arachni-Browser-Auth' )
|
1203
1290
|
|
@@ -1215,10 +1302,16 @@ class Browser
|
|
1215
1302
|
# preloaded or cached response for it.
|
1216
1303
|
return if from_preloads( request, response ) || from_cache( request, response )
|
1217
1304
|
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1305
|
+
begin
|
1306
|
+
# Capture the request as elements of pages -- let's us grab AJAX and
|
1307
|
+
# other browser requests and convert them into elements we can analyze
|
1308
|
+
# and audit.
|
1309
|
+
capture( request )
|
1310
|
+
rescue => e
|
1311
|
+
print_debug "Could not capture: #{request.url}"
|
1312
|
+
print_debug request.body.to_s
|
1313
|
+
print_debug_exception e
|
1314
|
+
end
|
1222
1315
|
|
1223
1316
|
request.headers['user-agent'] = Options.http.user_agent
|
1224
1317
|
|
@@ -1234,10 +1327,15 @@ class Browser
|
|
1234
1327
|
transition.complete
|
1235
1328
|
end
|
1236
1329
|
|
1330
|
+
# No-matter the scope, don't store resources for external domains.
|
1331
|
+
return if !response.scope.in_domain?
|
1332
|
+
|
1237
1333
|
return if enforce_scope? && response.scope.out?
|
1238
1334
|
|
1239
1335
|
intercept response
|
1240
1336
|
save_response response
|
1337
|
+
|
1338
|
+
nil
|
1241
1339
|
end
|
1242
1340
|
|
1243
1341
|
def intercept( response )
|
@@ -1247,12 +1345,37 @@ class Browser
|
|
1247
1345
|
|
1248
1346
|
def intercept?( response )
|
1249
1347
|
return false if response.body.empty?
|
1250
|
-
return false if !response.headers.content_type.to_s.start_with?( 'text/html' )
|
1251
1348
|
|
1349
|
+
# We only care about HTML.
|
1350
|
+
return false if !response.headers.content_type.to_s.downcase.start_with?( 'text/html' )
|
1351
|
+
|
1352
|
+
# Let's check that the response at least looks like it contains HTML
|
1353
|
+
# code of interest.
|
1252
1354
|
body = response.body.downcase
|
1253
|
-
HTML_IDENTIFIERS.
|
1355
|
+
return false if !HTML_IDENTIFIERS.find { |tag| body.include? tag.downcase }
|
1254
1356
|
|
1255
|
-
|
1357
|
+
# The last check isn't fool-proof, so don't do it when loading the page
|
1358
|
+
# for the first time, but only when the page loads stuff via AJAX and whatnot.
|
1359
|
+
#
|
1360
|
+
# Well, we can be pretty sure that the root page will be HTML anyways.
|
1361
|
+
return true if @last_url == response.url
|
1362
|
+
|
1363
|
+
# Finally, verify that we're really working with markup (hopefully HTML)
|
1364
|
+
# and that the previous checks weren't just flukes matching some other
|
1365
|
+
# kind of document.
|
1366
|
+
#
|
1367
|
+
# For example, it may have been JSON with the wrong content-type that
|
1368
|
+
# includes HTML -- it happens.
|
1369
|
+
begin
|
1370
|
+
return false if Nokogiri::XML( response.body ).children.empty?
|
1371
|
+
rescue => e
|
1372
|
+
print_debug "Javascript injection failed for: #{response.url}"
|
1373
|
+
print_debug "\n#{response.body}"
|
1374
|
+
print_debug_exception e
|
1375
|
+
return false
|
1376
|
+
end
|
1377
|
+
|
1378
|
+
true
|
1256
1379
|
end
|
1257
1380
|
|
1258
1381
|
def ignore_request?( request )
|
@@ -1260,19 +1383,36 @@ class Browser
|
|
1260
1383
|
|
1261
1384
|
# Only allow CSS and JS resources to be loaded from out-of-scope domains.
|
1262
1385
|
!['css', 'js'].include?( request.parsed_url.resource_extension ) &&
|
1263
|
-
request.scope.out? || request.scope.redundant?
|
1386
|
+
(request.scope.out? || request.scope.redundant?)
|
1264
1387
|
end
|
1265
1388
|
|
1266
1389
|
def capture( request )
|
1267
1390
|
return if !@last_url || !capture?
|
1268
1391
|
|
1392
|
+
elements = {
|
1393
|
+
forms: [],
|
1394
|
+
jsons: [],
|
1395
|
+
xmls: []
|
1396
|
+
}
|
1397
|
+
|
1398
|
+
found_element = false
|
1399
|
+
|
1400
|
+
if (json = JSON.from_request( @last_url, request ))
|
1401
|
+
elements[:jsons] << json
|
1402
|
+
found_element = true
|
1403
|
+
end
|
1404
|
+
|
1405
|
+
if !found_element && (xml = XML.from_request( @last_url, request ))
|
1406
|
+
elements[:xmls] << xml
|
1407
|
+
found_element = true
|
1408
|
+
end
|
1409
|
+
|
1269
1410
|
case request.method
|
1270
1411
|
when :get
|
1271
|
-
inputs =
|
1412
|
+
inputs = request.parsed_url.query_parameters
|
1272
1413
|
return if inputs.empty?
|
1273
1414
|
|
1274
|
-
|
1275
|
-
form = Form.new(
|
1415
|
+
elements[:forms] << Form.new(
|
1276
1416
|
url: @last_url,
|
1277
1417
|
action: request.url,
|
1278
1418
|
method: request.method,
|
@@ -1280,32 +1420,33 @@ class Browser
|
|
1280
1420
|
)
|
1281
1421
|
|
1282
1422
|
when :post
|
1283
|
-
inputs = request.body_parameters
|
1284
|
-
|
1285
|
-
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1290
|
-
|
1291
|
-
)
|
1423
|
+
if !found_element && (inputs = request.body_parameters).any?
|
1424
|
+
elements[:forms] << Form.new(
|
1425
|
+
url: @last_url,
|
1426
|
+
action: request.url,
|
1427
|
+
method: request.method,
|
1428
|
+
inputs: inputs
|
1429
|
+
)
|
1430
|
+
end
|
1292
1431
|
|
1293
1432
|
else
|
1294
1433
|
return
|
1295
1434
|
end
|
1296
1435
|
|
1297
|
-
|
1298
|
-
|
1436
|
+
el = elements.values.flatten
|
1437
|
+
|
1438
|
+
# Don't bother if the system in general has already seen the vectors.
|
1439
|
+
return if el.empty? || !el.find { |e| !ElementFilter.include?( e ) }
|
1299
1440
|
|
1300
1441
|
begin
|
1301
|
-
return if skip_state?(
|
1302
|
-
skip_state
|
1442
|
+
return if !el.find { |e| !skip_state?( e ) }
|
1443
|
+
el.each { |e| skip_state e.id }
|
1303
1444
|
# This could be an orphaned HTTP request, without a job, if running in
|
1304
1445
|
# BrowserCluster::Worker.
|
1305
1446
|
rescue NoMethodError
|
1306
1447
|
end
|
1307
1448
|
|
1308
|
-
page = Page.from_data( url: request.url
|
1449
|
+
page = Page.from_data( elements.merge( url: request.url ) )
|
1309
1450
|
page.response.request = request
|
1310
1451
|
page.dom.push_transition Page::DOM::Transition.new( request.url, :request )
|
1311
1452
|
|
@@ -1342,10 +1483,12 @@ class Browser
|
|
1342
1483
|
end
|
1343
1484
|
|
1344
1485
|
def save_response( response )
|
1345
|
-
|
1346
|
-
|
1486
|
+
synchronize do
|
1487
|
+
notify_on_response response
|
1488
|
+
return response if !response.text?
|
1347
1489
|
|
1348
|
-
|
1490
|
+
@window_responses[response.url] = response
|
1491
|
+
end
|
1349
1492
|
end
|
1350
1493
|
|
1351
1494
|
def get_response( url )
|
@@ -1354,7 +1497,8 @@ class Browser
|
|
1354
1497
|
# everything after ';' by treating it as a path parameter.
|
1355
1498
|
# Rightly so...but we need to bypass it when auditing LinkTemplate
|
1356
1499
|
# elements.
|
1357
|
-
@window_responses[
|
1500
|
+
@window_responses[url] ||
|
1501
|
+
@window_responses[normalize_watir_url( url )] ||
|
1358
1502
|
@window_responses[normalize_url( url )]
|
1359
1503
|
end
|
1360
1504
|
end
|