arachni 1.3.2 → 1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +108 -0
- data/Gemfile +2 -6
- data/LICENSE.md +1 -1
- data/README.md +34 -16
- data/Rakefile +1 -1
- data/arachni.gemspec +28 -20
- 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_rest_server +13 -0
- 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 +8 -10
- data/components/checks/active/code_injection_php_input_wrapper.rb +5 -6
- data/components/checks/active/code_injection_timing.rb +1 -1
- data/components/checks/active/csrf.rb +1 -1
- data/components/checks/active/file_inclusion.rb +20 -26
- data/components/checks/active/ldap_injection.rb +4 -5
- data/components/checks/active/no_sql_injection.rb +11 -20
- data/components/checks/active/no_sql_injection/substrings/mongodb +1 -0
- data/components/checks/active/no_sql_injection_differential.rb +3 -4
- data/components/checks/active/os_cmd_injection.rb +5 -9
- data/components/checks/active/os_cmd_injection_timing.rb +1 -1
- data/components/checks/active/path_traversal.rb +4 -17
- data/components/checks/active/response_splitting.rb +8 -2
- data/components/checks/active/rfi.rb +4 -5
- data/components/checks/active/session_fixation.rb +9 -3
- data/components/checks/active/source_code_disclosure.rb +5 -20
- data/components/checks/active/sql_injection.rb +30 -18
- data/components/checks/active/sql_injection/{regexp_ignore.txt → ignore_substrings} +0 -0
- data/components/checks/active/sql_injection/regexps/db2.yaml +2 -0
- data/components/checks/active/sql_injection/regexps/frontbase.yaml +1 -0
- data/components/checks/active/sql_injection/regexps/informix.yaml +1 -0
- data/components/checks/active/sql_injection/regexps/ingres.yaml +2 -0
- data/components/checks/active/sql_injection/regexps/maxdb.yaml +2 -0
- data/components/checks/active/sql_injection/regexps/mssql.yaml +8 -0
- data/components/checks/active/sql_injection/regexps/mysql.yaml +4 -0
- data/components/checks/active/sql_injection/regexps/oracle.yaml +4 -0
- data/components/checks/active/sql_injection/regexps/pgsql.yaml +3 -0
- data/components/checks/active/sql_injection/regexps/sqlite.yaml +2 -0
- data/components/checks/active/sql_injection/regexps/sybase.yaml +2 -0
- data/components/checks/active/sql_injection/substrings/access +3 -0
- data/components/checks/active/sql_injection/substrings/db2 +2 -0
- data/components/checks/active/sql_injection/{patterns → substrings}/emc +1 -1
- data/components/checks/active/sql_injection/{patterns → substrings}/firebird +0 -1
- data/components/checks/active/sql_injection/substrings/hsqldb +1 -0
- data/components/checks/active/sql_injection/{patterns → substrings}/informix +1 -2
- data/components/checks/active/sql_injection/substrings/ingres +1 -0
- data/components/checks/active/sql_injection/{patterns → substrings}/interbase +0 -0
- data/components/checks/active/sql_injection/substrings/mssql +17 -0
- data/components/checks/active/sql_injection/{patterns → substrings}/mysql +3 -6
- data/components/checks/active/sql_injection/substrings/oracle +2 -0
- data/components/checks/active/sql_injection/{patterns → substrings}/pgsql +3 -6
- data/components/checks/active/sql_injection/substrings/sqlite +3 -0
- data/components/checks/active/sql_injection/substrings/sybase +1 -0
- data/components/checks/active/sql_injection_differential.rb +5 -7
- data/components/checks/active/sql_injection_differential/payloads.txt +1 -1
- data/components/checks/active/sql_injection_timing.rb +1 -1
- data/components/checks/active/trainer.rb +5 -4
- data/components/checks/active/unvalidated_redirect.rb +1 -1
- data/components/checks/active/unvalidated_redirect_dom.rb +1 -1
- data/components/checks/active/xpath_injection.rb +3 -4
- data/components/checks/active/xss.rb +33 -12
- data/components/checks/active/xss_dom.rb +7 -4
- data/components/checks/active/xss_dom_script_context.rb +1 -1
- data/components/checks/active/xss_event.rb +43 -20
- data/components/checks/active/xss_path.rb +5 -4
- data/components/checks/active/xss_script_context.rb +41 -11
- data/components/checks/active/xss_tag.rb +14 -15
- data/components/checks/active/xxe.rb +5 -16
- data/components/checks/passive/allowed_methods.rb +1 -1
- data/components/checks/passive/backdoors.rb +4 -2
- data/components/checks/passive/backup_directories.rb +4 -2
- data/components/checks/passive/backup_files.rb +4 -2
- data/components/checks/passive/common_admin_interfaces.rb +4 -3
- data/components/checks/passive/common_directories.rb +3 -1
- data/components/checks/passive/common_files.rb +3 -1
- data/components/checks/passive/directory_listing.rb +4 -4
- data/components/checks/passive/grep/captcha.rb +1 -1
- data/components/checks/passive/grep/cookie_set_for_parent_domain.rb +1 -1
- data/components/checks/passive/grep/credit_card.rb +5 -7
- data/components/checks/passive/grep/cvs_svn_users.rb +1 -1
- data/components/checks/passive/grep/emails.rb +135 -8
- data/components/checks/passive/grep/form_upload.rb +1 -1
- data/components/checks/passive/grep/hsts.rb +4 -3
- data/components/checks/passive/grep/html_objects.rb +1 -1
- data/components/checks/passive/grep/http_only_cookies.rb +5 -3
- data/components/checks/passive/grep/insecure_cookies.rb +5 -3
- data/components/checks/passive/grep/insecure_cors_policy.rb +1 -1
- data/components/checks/passive/grep/mixed_resource.rb +1 -1
- data/components/checks/passive/grep/password_autocomplete.rb +1 -1
- data/components/checks/passive/grep/private_ip.rb +1 -1
- data/components/checks/passive/grep/ssn.rb +6 -3
- data/components/checks/passive/grep/unencrypted_password_forms.rb +1 -1
- data/components/checks/passive/grep/x_frame_options.rb +4 -3
- data/components/checks/passive/htaccess_limit.rb +1 -1
- data/components/checks/passive/http_put.rb +1 -1
- data/components/checks/passive/insecure_client_access_policy.rb +2 -2
- data/components/checks/passive/insecure_cross_domain_policy_access.rb +2 -2
- data/components/checks/passive/insecure_cross_domain_policy_headers.rb +2 -2
- 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/aspx_mvc.rb +1 -1
- data/components/fingerprinters/frameworks/cakephp.rb +1 -1
- data/components/fingerprinters/frameworks/cherrypy.rb +1 -1
- data/components/fingerprinters/frameworks/django.rb +1 -1
- data/components/fingerprinters/frameworks/jsf.rb +1 -1
- data/components/fingerprinters/frameworks/nette.rb +1 -1
- data/components/fingerprinters/frameworks/rack.rb +1 -1
- data/components/fingerprinters/frameworks/rails.rb +1 -1
- data/components/fingerprinters/frameworks/symfony.rb +1 -1
- data/components/fingerprinters/languages/asp.rb +1 -1
- data/components/fingerprinters/languages/aspx.rb +1 -1
- data/components/fingerprinters/languages/java.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/gunicorn.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 +1 -1
- data/components/path_extractors/data_url.rb +1 -1
- 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 +3 -3
- data/components/path_extractors/scripts.rb +1 -1
- data/components/plugins/autologin.rb +16 -24
- 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 +10 -9
- 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 +3 -5
- data/components/plugins/exec.rb +1 -1
- data/components/plugins/form_dicattack.rb +1 -1
- data/components/plugins/headers_collector.rb +1 -1
- data/components/plugins/http_dicattack.rb +1 -1
- data/components/plugins/login_script.rb +47 -22
- data/components/plugins/metrics.rb +1 -1
- data/components/plugins/proxy.rb +69 -44
- data/components/plugins/proxy/panel/help.html.erb +1 -18
- data/components/plugins/proxy/panel/inspect.html.erb +4 -3
- data/components/plugins/proxy/panel/page_accordion.html.erb +78 -43
- data/components/plugins/proxy/panel/panel.html.erb +2 -7
- data/components/plugins/proxy/template_scope.rb +1 -1
- data/components/plugins/restrict_to_dom_state.rb +3 -15
- data/components/plugins/script.rb +1 -1
- data/components/plugins/uncommon_headers.rb +1 -1
- data/components/plugins/vector_collector.rb +1 -1
- data/components/plugins/vector_feed.rb +3 -11
- data/components/plugins/waf_detector.rb +1 -1
- data/components/reporters/ap.rb +1 -1
- data/components/reporters/html.rb +2 -2
- 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 +1 -1
- 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/metrics.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 +1 -1
- 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 +1 -1
- 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/metrics.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 +1 -1
- 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 +1 -1
- 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/metrics.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 +1 -1
- 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 +29 -4
- data/components/reporters/yaml.rb +1 -1
- data/lib/arachni.rb +48 -3
- data/lib/arachni/banner.rb +1 -1
- data/lib/arachni/browser.rb +601 -358
- data/lib/arachni/browser/element_locator.rb +25 -6
- data/lib/arachni/browser/javascript.rb +103 -35
- data/lib/arachni/browser/javascript/dom_monitor.rb +1 -1
- data/lib/arachni/browser/javascript/proxy.rb +28 -16
- data/lib/arachni/browser/javascript/proxy/stub.rb +1 -1
- data/lib/arachni/browser/javascript/scripts/dom_monitor.js +138 -67
- data/lib/arachni/browser/javascript/scripts/polyfills.js +28 -0
- data/lib/arachni/browser/javascript/scripts/taint_tracer.js +27 -6
- data/lib/arachni/browser/javascript/taint_tracer.rb +1 -1
- 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 +10 -14
- 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 +1 -1
- data/lib/arachni/browser_cluster/jobs/{resource_exploration.rb → dom_exploration.rb} +5 -5
- data/lib/arachni/browser_cluster/jobs/{resource_exploration → dom_exploration}/event_trigger.rb +7 -4
- data/lib/arachni/browser_cluster/jobs/{resource_exploration → dom_exploration}/event_trigger/result.rb +3 -3
- data/lib/arachni/browser_cluster/jobs/{resource_exploration → dom_exploration}/result.rb +2 -2
- data/lib/arachni/browser_cluster/jobs/taint_trace.rb +3 -3
- data/lib/arachni/browser_cluster/jobs/taint_trace/event_trigger.rb +2 -2
- data/lib/arachni/browser_cluster/jobs/taint_trace/event_trigger/result.rb +2 -2
- data/lib/arachni/browser_cluster/jobs/taint_trace/result.rb +1 -1
- data/lib/arachni/browser_cluster/worker.rb +12 -40
- data/lib/arachni/check.rb +1 -1
- data/lib/arachni/check/auditor.rb +15 -1
- 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 +5 -5
- data/lib/arachni/component/manager.rb +39 -13
- 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 +19 -5
- data/lib/arachni/element/body.rb +1 -1
- data/lib/arachni/element/capabilities/analyzable.rb +1 -1
- data/lib/arachni/element/capabilities/analyzable/differential.rb +15 -5
- data/lib/arachni/element/capabilities/analyzable/signature.rb +147 -89
- data/lib/arachni/element/capabilities/analyzable/timeout.rb +43 -16
- data/lib/arachni/element/capabilities/auditable.rb +20 -15
- data/lib/arachni/element/capabilities/dom_only.rb +5 -4
- data/lib/arachni/element/capabilities/inputtable.rb +62 -12
- data/lib/arachni/element/capabilities/mutable.rb +74 -13
- data/lib/arachni/element/capabilities/refreshable.rb +1 -1
- data/lib/arachni/element/capabilities/submittable.rb +5 -2
- data/lib/arachni/element/capabilities/with_auditor.rb +1 -1
- data/lib/arachni/element/capabilities/with_auditor/output.rb +5 -5
- data/lib/arachni/element/capabilities/with_dom.rb +1 -1
- data/lib/arachni/element/capabilities/with_node.rb +2 -2
- data/lib/arachni/element/capabilities/with_scope.rb +1 -1
- data/lib/arachni/element/capabilities/with_scope/scope.rb +1 -1
- data/lib/arachni/element/capabilities/with_source.rb +4 -4
- data/lib/arachni/element/cookie.rb +57 -34
- data/lib/arachni/element/cookie/capabilities/inputtable.rb +1 -1
- data/lib/arachni/element/cookie/capabilities/mutable.rb +10 -1
- data/lib/arachni/element/cookie/capabilities/with_dom.rb +1 -1
- data/lib/arachni/element/cookie/dom.rb +1 -1
- data/lib/arachni/element/dom.rb +1 -15
- data/lib/arachni/element/dom/capabilities/auditable.rb +1 -1
- data/lib/arachni/element/dom/capabilities/inputtable.rb +1 -1
- data/lib/arachni/element/dom/capabilities/locatable.rb +29 -0
- data/lib/arachni/element/dom/capabilities/mutable.rb +11 -1
- data/lib/arachni/element/dom/capabilities/submittable.rb +2 -2
- data/lib/arachni/element/form.rb +33 -14
- data/lib/arachni/element/form/capabilities/auditable.rb +1 -1
- data/lib/arachni/element/form/capabilities/mutable.rb +18 -17
- data/lib/arachni/element/form/capabilities/submittable.rb +1 -1
- data/lib/arachni/element/form/capabilities/with_dom.rb +2 -1
- data/lib/arachni/element/form/dom.rb +3 -2
- data/lib/arachni/element/generic_dom.rb +1 -1
- data/lib/arachni/element/header.rb +16 -4
- data/lib/arachni/element/header/capabilities/inputtable.rb +1 -1
- data/lib/arachni/element/header/capabilities/mutable.rb +11 -1
- data/lib/arachni/element/json.rb +2 -2
- data/lib/arachni/element/json/capabilities/inputtable.rb +1 -1
- data/lib/arachni/element/json/capabilities/mutable.rb +8 -2
- data/lib/arachni/element/link.rb +14 -7
- data/lib/arachni/element/link/capabilities/auditable.rb +1 -1
- data/lib/arachni/element/link/capabilities/submittable.rb +1 -1
- data/lib/arachni/element/link/capabilities/with_dom.rb +8 -1
- data/lib/arachni/element/link/dom.rb +2 -1
- data/lib/arachni/element/link/dom/capabilities/submittable.rb +1 -1
- data/lib/arachni/element/link_template.rb +8 -3
- data/lib/arachni/element/link_template/capabilities/auditable.rb +1 -1
- data/lib/arachni/element/link_template/capabilities/inputtable.rb +1 -1
- data/lib/arachni/element/link_template/capabilities/with_dom.rb +1 -1
- data/lib/arachni/element/link_template/dom.rb +2 -1
- data/lib/arachni/element/link_template/dom/capabilities/submittable.rb +1 -1
- data/lib/arachni/element/path.rb +1 -1
- data/lib/arachni/element/server.rb +3 -3
- data/lib/arachni/element/ui_form.rb +24 -21
- data/lib/arachni/element/ui_form/dom.rb +12 -3
- data/lib/arachni/element/ui_input.rb +17 -11
- data/lib/arachni/element/{input → ui_input}/dom.rb +11 -2
- data/lib/arachni/element/xml.rb +3 -3
- data/lib/arachni/element/xml/capabilities/inputtable.rb +7 -1
- data/lib/arachni/element/xml/capabilities/mutable.rb +7 -13
- data/lib/arachni/element_filter.rb +1 -1
- data/lib/arachni/error.rb +1 -1
- data/lib/arachni/ethon/easy.rb +1 -1
- data/lib/arachni/framework.rb +2 -5
- data/lib/arachni/framework/parts/audit.rb +8 -2
- data/lib/arachni/framework/parts/browser.rb +8 -9
- data/lib/arachni/framework/parts/check.rb +2 -6
- data/lib/arachni/framework/parts/data.rb +23 -8
- data/lib/arachni/framework/parts/platform.rb +1 -1
- data/lib/arachni/framework/parts/plugin.rb +2 -8
- data/lib/arachni/framework/parts/report.rb +3 -9
- data/lib/arachni/framework/parts/scope.rb +1 -1
- data/lib/arachni/framework/parts/state.rb +8 -8
- data/lib/arachni/http.rb +1 -1
- data/lib/arachni/http/client.rb +72 -68
- data/lib/arachni/http/client/dynamic_404_handler.rb +85 -60
- data/lib/arachni/http/cookie_jar.rb +48 -27
- data/lib/arachni/http/headers.rb +4 -3
- data/lib/arachni/http/message.rb +17 -3
- data/lib/arachni/http/message/scope.rb +1 -1
- data/lib/arachni/http/proxy_server.rb +46 -344
- data/lib/arachni/http/proxy_server/connection.rb +316 -0
- data/lib/arachni/http/proxy_server/ssl_interceptor.rb +102 -0
- data/lib/arachni/http/proxy_server/tunnel.rb +54 -0
- data/lib/arachni/http/request.rb +126 -29
- data/lib/arachni/http/request/scope.rb +1 -1
- data/lib/arachni/http/response.rb +42 -12
- data/lib/arachni/http/response/scope.rb +1 -1
- data/lib/arachni/issue.rb +2 -2
- 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 +20 -4
- data/lib/arachni/option_groups/browser_cluster.rb +8 -4
- 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 +2 -2
- data/lib/arachni/option_groups/input.rb +6 -3
- data/lib/arachni/option_groups/output.rb +1 -1
- data/lib/arachni/option_groups/paths.rb +10 -3
- data/lib/arachni/option_groups/rpc.rb +1 -1
- data/lib/arachni/option_groups/scope.rb +35 -6
- 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 +26 -12
- data/lib/arachni/page/dom.rb +29 -22
- data/lib/arachni/page/dom/transition.rb +2 -2
- data/lib/arachni/page/scope.rb +1 -1
- data/lib/arachni/parser.rb +42 -5
- 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 +2 -2
- data/lib/arachni/plugin.rb +1 -1
- data/lib/arachni/plugin/base.rb +1 -1
- data/lib/arachni/plugin/formatter.rb +1 -1
- data/lib/arachni/plugin/manager.rb +7 -13
- data/lib/arachni/processes.rb +1 -1
- data/lib/arachni/processes/dispatchers.rb +2 -2
- data/lib/arachni/processes/executables/base.rb +45 -4
- data/lib/arachni/processes/executables/browser.rb +91 -0
- data/lib/arachni/processes/executables/rest_service.rb +14 -0
- 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 +5 -5
- data/lib/arachni/processes/manager.rb +68 -9
- data/lib/arachni/report.rb +1 -1
- data/lib/arachni/reporter.rb +1 -1
- data/lib/arachni/reporter/base.rb +1 -1
- data/lib/arachni/reporter/formatter_manager.rb +4 -2
- data/lib/arachni/reporter/manager.rb +3 -2
- data/lib/arachni/reporter/options.rb +1 -1
- data/lib/arachni/rest/server.rb +231 -0
- data/lib/arachni/rest/server/instance_helpers.rb +37 -0
- 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 +1 -1
- data/lib/arachni/rpc/server/active_options.rb +20 -3
- 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 +4 -4
- 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 +3 -1
- data/lib/arachni/rpc/server/framework/distributor.rb +1 -1
- 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 +1 -3
- 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 -2
- data/lib/arachni/ruby/array.rb +1 -1
- data/lib/arachni/ruby/hash.rb +1 -1
- data/lib/arachni/ruby/object.rb +15 -1
- data/lib/arachni/ruby/set.rb +1 -1
- data/lib/arachni/ruby/string.rb +23 -4
- 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/{watir → selenium/webdriver}/element.rb +12 -13
- data/lib/arachni/session.rb +19 -4
- data/lib/arachni/snapshot.rb +9 -5
- data/lib/arachni/state.rb +1 -1
- data/lib/arachni/state/audit.rb +1 -1
- data/lib/arachni/state/element_filter.rb +1 -1
- 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 +2 -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 +20 -8
- data/lib/arachni/support/cache/least_cost_replacement.rb +1 -1
- data/lib/arachni/support/cache/least_recently_pushed.rb +1 -1
- data/lib/arachni/support/cache/least_recently_used.rb +8 -9
- data/lib/arachni/support/cache/preference.rb +7 -20
- 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 +2 -2
- data/lib/arachni/support/database/hash.rb +1 -1
- data/lib/arachni/support/database/queue.rb +1 -1
- data/lib/arachni/support/glob.rb +35 -0
- 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 +12 -10
- data/lib/arachni/support/signature.rb +12 -5
- data/lib/arachni/trainer.rb +18 -4
- data/lib/arachni/ui/foo/output.rb +17 -1
- data/lib/arachni/uri.rb +285 -203
- data/lib/arachni/uri/scope.rb +13 -2
- data/lib/arachni/utilities.rb +22 -5
- data/lib/arachni/version.rb +1 -1
- data/lib/version +1 -1
- data/spec/arachni/browser/element_locator_spec.rb +42 -14
- data/spec/arachni/browser/javascript/dom_monitor_spec.rb +34 -304
- data/spec/arachni/browser/javascript/polyfills_spec.rb +35 -0
- data/spec/arachni/browser/javascript/taint_tracer_spec.rb +24 -4
- data/spec/arachni/browser/javascript_spec.rb +92 -65
- data/spec/arachni/browser_cluster/job_spec.rb +3 -3
- data/spec/arachni/browser_cluster/jobs/{resource_exploration → dom_exploration}/event_trigger/result_spec.rb +1 -1
- data/spec/arachni/browser_cluster/jobs/{resource_exploration → dom_exploration}/event_trigger_spec.rb +4 -4
- data/spec/arachni/browser_cluster/jobs/{resource_exploration → dom_exploration}/result_spec.rb +1 -1
- data/spec/arachni/browser_cluster/jobs/{resource_exploration_spec.rb → dom_exploration_spec.rb} +4 -4
- data/spec/arachni/browser_cluster/jobs/taint_tracer_spec.rb +9 -9
- data/spec/arachni/browser_cluster/worker_spec.rb +46 -67
- data/spec/arachni/browser_cluster_spec.rb +19 -17
- data/spec/arachni/browser_spec.rb +506 -183
- data/spec/arachni/check/auditor_spec.rb +70 -25
- data/spec/arachni/component/manager_spec.rb +19 -20
- data/spec/arachni/data/framework/rpc_spec.rb +1 -1
- data/spec/arachni/data/framework_spec.rb +1 -1
- data/spec/arachni/data/issues_spec.rb +3 -3
- data/spec/arachni/element/capabilities/analyzable/differential_spec.rb +44 -0
- data/spec/arachni/element/capabilities/analyzable/signature_spec.rb +33 -162
- data/spec/arachni/element/capabilities/analyzable/timeout_spec.rb +4 -4
- data/spec/arachni/element/cookie_spec.rb +98 -49
- data/spec/arachni/element/form/dom_spec.rb +1 -22
- data/spec/arachni/element/form_spec.rb +7 -7
- data/spec/arachni/element/header_spec.rb +2 -2
- data/spec/arachni/element/json_spec.rb +2 -2
- data/spec/arachni/element/link/dom_spec.rb +1 -22
- data/spec/arachni/element/link_spec.rb +17 -1
- data/spec/arachni/element/link_template/dom_spec.rb +1 -22
- data/spec/arachni/element/link_template_spec.rb +3 -3
- data/spec/arachni/element/ui_form/{ui_form_dom_spec.rb → dom_spec.rb} +72 -22
- data/spec/arachni/element/ui_form_spec.rb +1 -0
- data/spec/arachni/element/ui_input/dom_spec.rb +64 -22
- data/spec/arachni/element/ui_input_spec.rb +1 -0
- data/spec/arachni/element/xml_spec.rb +1 -0
- data/spec/arachni/framework/parts/audit_spec.rb +7 -5
- data/spec/arachni/framework/parts/browser_spec.rb +8 -8
- data/spec/arachni/framework/parts/check_spec.rb +1 -1
- data/spec/arachni/framework/parts/data_spec.rb +4 -4
- data/spec/arachni/framework/parts/scope_spec.rb +2 -2
- data/spec/arachni/framework_spec.rb +1 -1
- data/spec/arachni/http/client/dynamic_404_handlers_spec.rb +26 -13
- data/spec/arachni/http/client_spec.rb +80 -45
- data/spec/arachni/http/cookie_jar_spec.rb +6 -6
- data/spec/arachni/http/proxy_server_spec.rb +69 -66
- data/spec/arachni/http/request_spec.rb +147 -23
- data/spec/arachni/http/response/scope_spec.rb +12 -12
- data/spec/arachni/http/response_spec.rb +62 -4
- data/spec/arachni/issue_spec.rb +6 -6
- data/spec/arachni/option_groups/audit_spec.rb +25 -8
- data/spec/arachni/option_groups/browser_cluster_spec.rb +27 -1
- data/spec/arachni/option_groups/dispatcher_spec.rb +3 -3
- data/spec/arachni/option_groups/input_spec.rb +9 -9
- data/spec/arachni/option_groups/paths_spec.rb +2 -2
- data/spec/arachni/option_groups/scope_spec.rb +32 -16
- data/spec/arachni/options_spec.rb +4 -4
- data/spec/arachni/page/dom/transition_spec.rb +17 -10
- data/spec/arachni/page/dom_spec.rb +19 -0
- data/spec/arachni/page/scope_spec.rb +4 -4
- data/spec/arachni/page_spec.rb +15 -15
- data/spec/arachni/platform/manager_spec.rb +2 -2
- data/spec/arachni/plugin/base_spec.rb +1 -0
- data/spec/arachni/reporter/base_spec.rb +2 -2
- data/spec/arachni/reporter/manager_spec.rb +2 -2
- data/spec/arachni/rest/server_spec.rb +495 -0
- data/spec/arachni/rpc/server/active_options_spec.rb +63 -12
- data/spec/arachni/rpc/server/base_spec.rb +1 -1
- data/spec/arachni/rpc/server/framework/distributor_spec.rb +2 -2
- data/spec/arachni/rpc/server/framework_multi_spec.rb +6 -6
- data/spec/arachni/rpc/server/framework_spec.rb +4 -4
- data/spec/arachni/rpc/server/instance_spec.rb +24 -24
- data/spec/arachni/ruby/array_spec.rb +2 -2
- data/spec/arachni/ruby/string_spec.rb +52 -0
- data/spec/arachni/session_spec.rb +19 -2
- data/spec/arachni/snapshot_spec.rb +1 -1
- data/spec/arachni/state/audit_spec.rb +1 -1
- data/spec/arachni/state/framework_spec.rb +2 -2
- data/spec/arachni/support/cache/least_recently_used_spec.rb +0 -2
- data/spec/arachni/support/glob_spec.rb +75 -0
- data/spec/arachni/support/lookup/hash_set_spec.rb +1 -1
- data/spec/arachni/support/lookup/moolb_spec.rb +2 -2
- data/spec/arachni/support/signature_spec.rb +4 -4
- data/spec/arachni/trainer_spec.rb +48 -4
- data/spec/arachni/uri/scope_spec.rb +54 -10
- data/spec/arachni/uri_spec.rb +110 -89
- data/spec/arachni/utilities_spec.rb +8 -8
- data/spec/components/checks/active/code_injection_spec.rb +9 -9
- data/spec/components/checks/active/file_inclusion_spec.rb +20 -20
- data/spec/components/checks/active/ldap_injection_spec.rb +1 -1
- data/spec/components/checks/active/no_sql_injection_spec.rb +1 -1
- data/spec/components/checks/active/os_cmd_injection_spec.rb +3 -3
- data/spec/components/checks/active/path_traversal_spec.rb +11 -11
- data/spec/components/checks/active/response_splitting_spec.rb +2 -2
- data/spec/components/checks/active/rfi_spec.rb +3 -3
- data/spec/components/checks/active/session_fixation_spec.rb +1 -1
- data/spec/components/checks/active/source_code_disclosure_spec.rb +4 -4
- data/spec/components/checks/active/sql_injection_spec.rb +58 -59
- data/spec/components/checks/active/unvalidated_redirect_spec.rb +2 -2
- data/spec/components/checks/active/xpath_injection_spec.rb +3 -3
- data/spec/components/checks/active/xss_dom_script_context_spec.rb +1 -1
- data/spec/components/checks/active/xss_dom_spec.rb +1 -1
- data/spec/components/checks/active/xss_script_context_spec.rb +5 -5
- data/spec/components/checks/active/xss_spec.rb +5 -5
- data/spec/components/checks/passive/grep/credit_card_spec.rb +1 -1
- data/spec/components/checks/passive/grep/emails_spec.rb +12 -2
- data/spec/components/checks/passive/grep/ssn_spec.rb +1 -1
- data/spec/components/path_extractors/meta_refresh_spec.rb +3 -1
- data/spec/components/plugins/exec_spec.rb +2 -2
- data/spec/components/plugins/login_script_spec.rb +22 -2
- data/spec/components/plugins/vector_feed_spec.rb +3 -3
- data/spec/spec_helper.rb +10 -4
- data/spec/support/factories/browser_cluster/job.rb +1 -0
- 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/error.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/signature_check/signature.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/paths.rb +1 -1
- data/spec/support/helpers/request_helpers.rb +38 -0
- 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 +2 -2
- data/spec/support/servers/arachni/browser.rb +182 -15
- 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 +27 -4
- data/spec/support/servers/arachni/element/capabilities/analyzable/differential.rb +103 -0
- data/spec/support/servers/arachni/element/capabilities/analyzable/timeout.rb +5 -2
- data/spec/support/servers/arachni/element/header.rb +1 -1
- data/spec/support/servers/arachni/http/client.rb +46 -0
- data/spec/support/servers/arachni/http/client/dynamic_404_handler.rb +7 -1
- data/spec/support/servers/checks/active/code_injection.rb +5 -5
- data/spec/support/servers/checks/active/no_sql_injection.rb +0 -6
- data/spec/support/servers/checks/active/no_sql_injection_differential.rb +1 -1
- data/spec/support/servers/checks/active/sql_injection.rb +5 -2
- data/spec/support/servers/checks/active/sql_injection_differential.rb +1 -1
- data/spec/support/servers/checks/active/trainer_check.rb +6 -6
- data/spec/support/servers/checks/passive/backdoors.rb +1 -0
- data/spec/support/servers/checks/passive/backup_directories.rb +2 -0
- data/spec/support/servers/checks/passive/backup_files.rb +2 -0
- data/spec/support/servers/checks/passive/grep/emails.rb +6 -6
- data/spec/support/shared/check.rb +28 -0
- data/spec/support/shared/element/capabilities/auditable.rb +76 -13
- data/spec/support/shared/element/capabilities/dom_only.rb +5 -6
- data/spec/support/shared/element/capabilities/inputtable.rb +74 -4
- data/spec/support/shared/element/capabilities/mutable.rb +86 -14
- data/spec/support/shared/element/capabilities/submittable.rb +12 -0
- data/spec/support/shared/element/capabilities/with_dom.rb +13 -4
- data/spec/support/shared/element/capabilities/with_node.rb +1 -1
- data/spec/support/shared/element/capabilities/with_source.rb +1 -6
- data/spec/support/shared/element/dom/locatable.rb +20 -0
- data/spec/support/shared/element/dom/submittable.rb +4 -17
- data/spec/support/shared/http/message.rb +37 -5
- data/spec/support/shared/support/cache.rb +5 -4
- data/ui/cli/framework.rb +4 -3
- data/ui/cli/framework/option_parser.rb +20 -8
- data/ui/cli/option_parser.rb +1 -1
- data/ui/cli/output.rb +40 -4
- data/ui/cli/reporter.rb +1 -1
- data/ui/cli/reporter/option_parser.rb +4 -4
- data/ui/cli/rest/server.rb +43 -0
- data/ui/cli/rest/server/option_parser.rb +115 -0
- 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 +1 -1
- 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 +1 -1
- metadata +197 -84
- data/components/checks/active/no_sql_injection/patterns/mongodb +0 -1
- data/components/checks/active/no_sql_injection/regexp_ignore.txt +0 -0
- data/components/checks/active/sql_injection/patterns/access +0 -3
- data/components/checks/active/sql_injection/patterns/db2 +0 -5
- data/components/checks/active/sql_injection/patterns/frontbase +0 -1
- data/components/checks/active/sql_injection/patterns/hsqldb +0 -1
- data/components/checks/active/sql_injection/patterns/ingres +0 -3
- data/components/checks/active/sql_injection/patterns/maxdb +0 -2
- data/components/checks/active/sql_injection/patterns/mssql +0 -25
- data/components/checks/active/sql_injection/patterns/oracle +0 -6
- data/components/checks/active/sql_injection/patterns/sqlite +0 -5
- data/components/checks/active/sql_injection/patterns/sybase +0 -3
- data/lib/arachni/ruby/io.rb +0 -39
- data/lib/arachni/selenium/webdriver/remote/http/typhoeus.rb +0 -63
- data/spec/arachni/ruby/io_spec.rb +0 -26
@@ -47,7 +47,7 @@ describe Arachni::BrowserCluster::Jobs::TaintTrace do
|
|
47
47
|
end
|
48
48
|
|
49
49
|
context 'and the resource is a' do
|
50
|
-
context String do
|
50
|
+
context 'String' do
|
51
51
|
it 'loads the URL and traces the taint' do
|
52
52
|
test_data_flow described_class.new(
|
53
53
|
resource: url,
|
@@ -56,7 +56,7 @@ describe Arachni::BrowserCluster::Jobs::TaintTrace do
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
context Arachni::HTTP::Response do
|
59
|
+
context 'Arachni::HTTP::Response' do
|
60
60
|
it 'loads it and traces the taint' do
|
61
61
|
test_data_flow described_class.new(
|
62
62
|
resource: Arachni::HTTP::Client.get( url, mode: :sync ),
|
@@ -65,7 +65,7 @@ describe Arachni::BrowserCluster::Jobs::TaintTrace do
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
-
context Arachni::Page do
|
68
|
+
context 'Arachni::Page' do
|
69
69
|
it 'loads it and traces the taint' do
|
70
70
|
test_data_flow described_class.new(
|
71
71
|
resource: Arachni::Page.from_url( url ),
|
@@ -83,7 +83,7 @@ describe Arachni::BrowserCluster::Jobs::TaintTrace do
|
|
83
83
|
end
|
84
84
|
|
85
85
|
context 'and the resource is a' do
|
86
|
-
context String do
|
86
|
+
context 'String' do
|
87
87
|
it 'loads the URL and traces the taint' do
|
88
88
|
test_data_flow_with_injector described_class.new(
|
89
89
|
resource: url,
|
@@ -93,7 +93,7 @@ describe Arachni::BrowserCluster::Jobs::TaintTrace do
|
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
|
-
context Arachni::HTTP::Response do
|
96
|
+
context 'Arachni::HTTP::Response' do
|
97
97
|
it 'loads it and traces the taint' do
|
98
98
|
test_data_flow_with_injector described_class.new(
|
99
99
|
resource: Arachni::HTTP::Client.get( url, mode: :sync ),
|
@@ -103,7 +103,7 @@ describe Arachni::BrowserCluster::Jobs::TaintTrace do
|
|
103
103
|
end
|
104
104
|
end
|
105
105
|
|
106
|
-
context Arachni::Page do
|
106
|
+
context 'Arachni::Page' do
|
107
107
|
it 'loads it and traces the taint' do
|
108
108
|
test_data_flow_with_injector described_class.new(
|
109
109
|
resource: Arachni::Page.from_url( url ),
|
@@ -123,13 +123,13 @@ describe Arachni::BrowserCluster::Jobs::TaintTrace do
|
|
123
123
|
end
|
124
124
|
|
125
125
|
context 'and the resource is a' do
|
126
|
-
context String do
|
126
|
+
context 'String' do
|
127
127
|
it 'loads the URL and traces the taint' do
|
128
128
|
test_execution_flow described_class.new( resource: url )
|
129
129
|
end
|
130
130
|
end
|
131
131
|
|
132
|
-
context Arachni::HTTP::Response do
|
132
|
+
context 'Arachni::HTTP::Response' do
|
133
133
|
it 'loads it and traces the taint' do
|
134
134
|
test_execution_flow described_class.new(
|
135
135
|
resource: Arachni::HTTP::Client.get( url, mode: :sync )
|
@@ -137,7 +137,7 @@ describe Arachni::BrowserCluster::Jobs::TaintTrace do
|
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
140
|
-
context Arachni::Page do
|
140
|
+
context 'Arachni::Page' do
|
141
141
|
it 'loads it and traces the taint' do
|
142
142
|
test_execution_flow described_class.new(
|
143
143
|
resource: Arachni::Page.from_url( url )
|
@@ -17,7 +17,7 @@ describe Arachni::BrowserCluster::Worker do
|
|
17
17
|
|
18
18
|
let(:url) { Arachni::Utilities.normalize_url( web_server_url_for( :browser ) ) }
|
19
19
|
let(:job) do
|
20
|
-
Arachni::BrowserCluster::Jobs::
|
20
|
+
Arachni::BrowserCluster::Jobs::DOMExploration.new(
|
21
21
|
resource: Arachni::HTTP::Client.get( url + 'explore', mode: :sync )
|
22
22
|
)
|
23
23
|
end
|
@@ -26,7 +26,7 @@ describe Arachni::BrowserCluster::Worker do
|
|
26
26
|
let(:subject) { @cluster.workers.first }
|
27
27
|
|
28
28
|
describe '#initialize' do
|
29
|
-
describe :job_timeout do
|
29
|
+
describe ':job_timeout' do
|
30
30
|
it 'sets how much time to allow each job to run' do
|
31
31
|
@worker = described_class.new( job_timeout: 10 )
|
32
32
|
expect(@worker.job_timeout).to eq(10)
|
@@ -39,7 +39,7 @@ describe Arachni::BrowserCluster::Worker do
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
describe :max_time_to_live do
|
42
|
+
describe ':max_time_to_live' do
|
43
43
|
it 'sets how many jobs should be run before respawning' do
|
44
44
|
@worker = described_class.new( max_time_to_live: 10 )
|
45
45
|
expect(@worker.max_time_to_live).to eq(10)
|
@@ -70,16 +70,41 @@ describe Arachni::BrowserCluster::Worker do
|
|
70
70
|
end
|
71
71
|
|
72
72
|
context 'before running the job' do
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
dead_pid = subject.pid
|
73
|
+
context 'when PhantomJS is dead' do
|
74
|
+
it 'spawns a new one' do
|
75
|
+
Arachni::Processes::Manager.kill subject.browser_pid
|
77
76
|
|
78
|
-
|
79
|
-
|
77
|
+
dead_lifeline_pid = subject.lifeline_pid
|
78
|
+
dead_browser_pid = subject.browser_pid
|
79
|
+
|
80
|
+
@cluster.queue( custom_job ){}
|
81
|
+
@cluster.wait
|
82
|
+
|
83
|
+
expect(subject.browser_pid).not_to eq(dead_browser_pid)
|
84
|
+
expect(subject.lifeline_pid).not_to eq(dead_lifeline_pid)
|
85
|
+
|
86
|
+
expect(Arachni::Processes::Manager.alive?( subject.lifeline_pid )).to be_truthy
|
87
|
+
expect(Arachni::Processes::Manager.alive?( subject.browser_pid )).to be_truthy
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context 'when the lifeline is dead' do
|
92
|
+
it 'spawns a new one' do
|
93
|
+
Arachni::Processes::Manager << subject.browser_pid
|
94
|
+
Arachni::Processes::Manager.kill subject.lifeline_pid
|
95
|
+
|
96
|
+
dead_lifeline_pid = subject.lifeline_pid
|
97
|
+
dead_browser_pid = subject.browser_pid
|
80
98
|
|
81
|
-
|
82
|
-
|
99
|
+
@cluster.queue( custom_job ){}
|
100
|
+
@cluster.wait
|
101
|
+
|
102
|
+
expect(subject.browser_pid).not_to eq(dead_browser_pid)
|
103
|
+
expect(subject.lifeline_pid).not_to eq(dead_lifeline_pid)
|
104
|
+
|
105
|
+
expect(Arachni::Processes::Manager.alive?( subject.lifeline_pid )).to be_truthy
|
106
|
+
expect(Arachni::Processes::Manager.alive?( subject.browser_pid )).to be_truthy
|
107
|
+
end
|
83
108
|
end
|
84
109
|
end
|
85
110
|
|
@@ -89,23 +114,23 @@ describe Arachni::BrowserCluster::Worker do
|
|
89
114
|
expect(subject.run_job( custom_job )).to be_truthy
|
90
115
|
end
|
91
116
|
|
92
|
-
context Selenium::WebDriver::Error::WebDriverError do
|
117
|
+
context 'Selenium::WebDriver::Error::WebDriverError' do
|
93
118
|
it 'respawns' do
|
94
|
-
|
119
|
+
expect(custom_job).to receive(:configure_and_run) do
|
95
120
|
raise Selenium::WebDriver::Error::WebDriverError
|
96
121
|
end
|
97
122
|
|
98
|
-
|
123
|
+
expect(subject.watir).to receive(:close) do
|
99
124
|
raise Selenium::WebDriver::Error::WebDriverError
|
100
125
|
end
|
101
126
|
|
102
127
|
watir = subject.watir
|
103
|
-
pid = subject.
|
128
|
+
pid = subject.browser_pid
|
104
129
|
|
105
130
|
subject.run_job( custom_job )
|
106
131
|
|
107
132
|
expect(watir).not_to eq(subject.watir)
|
108
|
-
expect(pid).not_to eq(subject.
|
133
|
+
expect(pid).not_to eq(subject.browser_pid)
|
109
134
|
end
|
110
135
|
end
|
111
136
|
end
|
@@ -122,19 +147,6 @@ describe Arachni::BrowserCluster::Worker do
|
|
122
147
|
expect(subject.javascript.taint).to be_nil
|
123
148
|
end
|
124
149
|
|
125
|
-
it 'clears #cookies' do
|
126
|
-
subject.preload page
|
127
|
-
expect(subject.preloads).to be_any
|
128
|
-
|
129
|
-
@cluster.with_browser do |browser|
|
130
|
-
browser.load page
|
131
|
-
expect(subject.cookies).to be_any
|
132
|
-
end
|
133
|
-
@cluster.wait
|
134
|
-
|
135
|
-
expect(subject.cookies).to be_empty
|
136
|
-
end
|
137
|
-
|
138
150
|
it 'clears #preloads' do
|
139
151
|
subject.preload page
|
140
152
|
expect(subject.preloads).to be_any
|
@@ -236,39 +248,6 @@ describe Arachni::BrowserCluster::Worker do
|
|
236
248
|
expect(custom_job.time).to be > 0
|
237
249
|
end
|
238
250
|
|
239
|
-
context 'when there are 5 or more windows open' do
|
240
|
-
before(:each) do
|
241
|
-
5.times do
|
242
|
-
subject.javascript.run( 'window.open()' )
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
it 'respawns PhantomJS' do
|
247
|
-
watir = subject.watir
|
248
|
-
pid = subject.pid
|
249
|
-
|
250
|
-
expect(subject.watir.windows.size).to be > 5
|
251
|
-
@cluster.explore( page ) {}
|
252
|
-
@cluster.wait
|
253
|
-
|
254
|
-
expect(watir).not_to eq(subject.watir)
|
255
|
-
expect(pid).not_to eq(subject.pid)
|
256
|
-
expect(subject.watir.windows.size).to eq(2)
|
257
|
-
end
|
258
|
-
|
259
|
-
it 'clears the cached HTTP responses' do
|
260
|
-
subject.preload page
|
261
|
-
expect(subject.preloads).to be_any
|
262
|
-
subject.instance_variable_get(:@window_responses)
|
263
|
-
|
264
|
-
expect(subject.watir.windows.size).to be > 5
|
265
|
-
@cluster.queue( custom_job ) {}
|
266
|
-
@cluster.wait
|
267
|
-
|
268
|
-
expect(subject.instance_variable_get(:@window_responses)).to be_empty
|
269
|
-
end
|
270
|
-
end
|
271
|
-
|
272
251
|
context 'when #time_to_live reaches 0' do
|
273
252
|
it 'respawns the browser' do
|
274
253
|
@cluster.shutdown
|
@@ -279,30 +258,30 @@ describe Arachni::BrowserCluster::Worker do
|
|
279
258
|
subject.max_time_to_live = 1
|
280
259
|
|
281
260
|
watir = subject.watir
|
282
|
-
pid = subject.
|
261
|
+
pid = subject.browser_pid
|
283
262
|
|
284
263
|
@cluster.queue( custom_job ) {}
|
285
264
|
@cluster.wait
|
286
265
|
|
287
266
|
expect(watir).not_to eq(subject.watir)
|
288
|
-
expect(pid).not_to eq(subject.
|
267
|
+
expect(pid).not_to eq(subject.browser_pid)
|
289
268
|
end
|
290
269
|
end
|
291
270
|
|
292
271
|
context 'when cookie clearing raises' do
|
293
|
-
context Selenium::WebDriver::Error::NoSuchWindowError do
|
272
|
+
context 'Selenium::WebDriver::Error::NoSuchWindowError' do
|
294
273
|
it 'respawns' do
|
295
274
|
allow(subject.watir).to receive(:cookies) do
|
296
275
|
raise Selenium::WebDriver::Error::NoSuchWindowError
|
297
276
|
end
|
298
277
|
|
299
278
|
watir = subject.watir
|
300
|
-
pid = subject.
|
279
|
+
pid = subject.browser_pid
|
301
280
|
|
302
281
|
subject.run_job( custom_job )
|
303
282
|
|
304
283
|
expect(watir).not_to eq(subject.watir)
|
305
|
-
expect(pid).not_to eq(subject.
|
284
|
+
expect(pid).not_to eq(subject.browser_pid)
|
306
285
|
end
|
307
286
|
end
|
308
287
|
end
|
@@ -4,7 +4,7 @@ describe Arachni::BrowserCluster do
|
|
4
4
|
|
5
5
|
let(:url) { Arachni::Utilities.normalize_url( web_server_url_for( :browser ) ) }
|
6
6
|
let(:job) do
|
7
|
-
Arachni::BrowserCluster::Jobs::
|
7
|
+
Arachni::BrowserCluster::Jobs::DOMExploration.new(
|
8
8
|
resource: Arachni::HTTP::Client.get( url + 'explore', mode: :sync )
|
9
9
|
)
|
10
10
|
end
|
@@ -23,6 +23,7 @@ describe Arachni::BrowserCluster do
|
|
23
23
|
|
24
24
|
@cluster = described_class.new
|
25
25
|
@cluster.workers.each do |browser|
|
26
|
+
browser.load url
|
26
27
|
expect(browser.javascript.run('return window.innerWidth')).to eq(100)
|
27
28
|
end
|
28
29
|
end
|
@@ -32,11 +33,12 @@ describe Arachni::BrowserCluster do
|
|
32
33
|
|
33
34
|
@cluster = described_class.new
|
34
35
|
@cluster.workers.each do |browser|
|
36
|
+
browser.load url
|
35
37
|
expect(browser.javascript.run('return window.innerHeight')).to eq(200)
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
39
|
-
describe :pool_size do
|
41
|
+
describe ':pool_size' do
|
40
42
|
it 'sets the amount of browsers to instantiate' do
|
41
43
|
@cluster = described_class.new( pool_size: 3 )
|
42
44
|
expect(@cluster.workers.size).to eq(3)
|
@@ -49,7 +51,7 @@ describe Arachni::BrowserCluster do
|
|
49
51
|
end
|
50
52
|
end
|
51
53
|
|
52
|
-
describe :on_pop do
|
54
|
+
describe ':on_pop' do
|
53
55
|
it 'assigns blocks to be passed each poped job' do
|
54
56
|
cj = nil
|
55
57
|
@cluster = described_class.new(
|
@@ -65,7 +67,7 @@ describe Arachni::BrowserCluster do
|
|
65
67
|
end
|
66
68
|
end
|
67
69
|
|
68
|
-
describe :on_queue do
|
70
|
+
describe ':on_queue' do
|
69
71
|
it 'assigns blocks to be passed each queued job' do
|
70
72
|
cj = nil
|
71
73
|
@cluster = described_class.new(
|
@@ -81,7 +83,7 @@ describe Arachni::BrowserCluster do
|
|
81
83
|
end
|
82
84
|
end
|
83
85
|
|
84
|
-
describe :on_job_done do
|
86
|
+
describe ':on_job_done' do
|
85
87
|
it 'assigns blocks to be passed each finished job' do
|
86
88
|
cj = nil
|
87
89
|
@cluster = described_class.new(
|
@@ -261,7 +263,7 @@ describe Arachni::BrowserCluster do
|
|
261
263
|
end
|
262
264
|
|
263
265
|
context 'when the resource is a' do
|
264
|
-
context String do
|
266
|
+
context 'String' do
|
265
267
|
it 'loads the URL and explores the DOM' do
|
266
268
|
pages = []
|
267
269
|
|
@@ -274,7 +276,7 @@ describe Arachni::BrowserCluster do
|
|
274
276
|
end
|
275
277
|
end
|
276
278
|
|
277
|
-
context Arachni::HTTP::Response do
|
279
|
+
context 'Arachni::HTTP::Response' do
|
278
280
|
it 'loads it and explores the DOM' do
|
279
281
|
pages = []
|
280
282
|
|
@@ -287,7 +289,7 @@ describe Arachni::BrowserCluster do
|
|
287
289
|
end
|
288
290
|
end
|
289
291
|
|
290
|
-
context Arachni::Page do
|
292
|
+
context 'Arachni::Page' do
|
291
293
|
it 'loads it and explores the DOM' do
|
292
294
|
pages = []
|
293
295
|
|
@@ -313,7 +315,7 @@ describe Arachni::BrowserCluster do
|
|
313
315
|
end
|
314
316
|
|
315
317
|
context 'and the resource is a' do
|
316
|
-
context String do
|
318
|
+
context 'String' do
|
317
319
|
it 'loads the URL and traces the taint' do
|
318
320
|
pages = []
|
319
321
|
@cluster.trace_taint( url, taint: taint ) do |result|
|
@@ -325,7 +327,7 @@ describe Arachni::BrowserCluster do
|
|
325
327
|
end
|
326
328
|
end
|
327
329
|
|
328
|
-
context Arachni::HTTP::Response do
|
330
|
+
context 'Arachni::HTTP::Response' do
|
329
331
|
it 'loads it and traces the taint' do
|
330
332
|
pages = []
|
331
333
|
|
@@ -339,7 +341,7 @@ describe Arachni::BrowserCluster do
|
|
339
341
|
end
|
340
342
|
end
|
341
343
|
|
342
|
-
context Arachni::Page do
|
344
|
+
context 'Arachni::Page' do
|
343
345
|
it 'loads it and traces the taint' do
|
344
346
|
pages = []
|
345
347
|
|
@@ -362,7 +364,7 @@ describe Arachni::BrowserCluster do
|
|
362
364
|
end
|
363
365
|
|
364
366
|
context 'and the resource is a' do
|
365
|
-
context String do
|
367
|
+
context 'String' do
|
366
368
|
it 'loads the URL and traces the taint' do
|
367
369
|
pages = []
|
368
370
|
@cluster.trace_taint( url,
|
@@ -376,7 +378,7 @@ describe Arachni::BrowserCluster do
|
|
376
378
|
end
|
377
379
|
end
|
378
380
|
|
379
|
-
context Arachni::HTTP::Response do
|
381
|
+
context 'Arachni::HTTP::Response' do
|
380
382
|
it 'loads it and traces the taint' do
|
381
383
|
pages = []
|
382
384
|
@cluster.trace_taint( Arachni::HTTP::Client.get( url, mode: :sync ),
|
@@ -390,7 +392,7 @@ describe Arachni::BrowserCluster do
|
|
390
392
|
end
|
391
393
|
end
|
392
394
|
|
393
|
-
context Arachni::Page do
|
395
|
+
context 'Arachni::Page' do
|
394
396
|
it 'loads it and traces the taint' do
|
395
397
|
pages = []
|
396
398
|
@cluster.trace_taint( Arachni::Page.from_url( url ),
|
@@ -414,7 +416,7 @@ describe Arachni::BrowserCluster do
|
|
414
416
|
end
|
415
417
|
|
416
418
|
context 'and the resource is a' do
|
417
|
-
context String do
|
419
|
+
context 'String' do
|
418
420
|
it 'loads the URL and traces the taint' do
|
419
421
|
pages = []
|
420
422
|
@cluster.trace_taint( url ) do |result|
|
@@ -426,7 +428,7 @@ describe Arachni::BrowserCluster do
|
|
426
428
|
end
|
427
429
|
end
|
428
430
|
|
429
|
-
context Arachni::HTTP::Response do
|
431
|
+
context 'Arachni::HTTP::Response' do
|
430
432
|
it 'loads it and traces the taint' do
|
431
433
|
pages = []
|
432
434
|
@cluster.trace_taint( Arachni::HTTP::Client.get( url, mode: :sync ) ) do |result|
|
@@ -438,7 +440,7 @@ describe Arachni::BrowserCluster do
|
|
438
440
|
end
|
439
441
|
end
|
440
442
|
|
441
|
-
context Arachni::Page do
|
443
|
+
context 'Arachni::Page' do
|
442
444
|
it 'loads it and traces the taint' do
|
443
445
|
pages = []
|
444
446
|
@cluster.trace_taint( Arachni::Page.from_url( url ) ) do |result|
|
@@ -14,7 +14,8 @@ describe Arachni::Browser do
|
|
14
14
|
after( :each ) do
|
15
15
|
Arachni::Options.reset
|
16
16
|
Arachni::Framework.reset
|
17
|
-
@browser.shutdown
|
17
|
+
@browser.shutdown if @browser
|
18
|
+
described_class.asset_domains.clear
|
18
19
|
clear_hit_count
|
19
20
|
end
|
20
21
|
|
@@ -27,7 +28,7 @@ describe Arachni::Browser do
|
|
27
28
|
|
28
29
|
options = {}
|
29
30
|
if element == :page && event == :load
|
30
|
-
options.merge!( url: @browser.
|
31
|
+
options.merge!( url: @browser.dom_url, cookies: {} )
|
31
32
|
end
|
32
33
|
|
33
34
|
if element.is_a? Hash
|
@@ -60,6 +61,46 @@ describe Arachni::Browser do
|
|
60
61
|
pages_should_have_form_with_input( pages, 'by-ajax' )
|
61
62
|
end
|
62
63
|
|
64
|
+
context 'when the browser dies' do
|
65
|
+
it 'kills the lifeline too' do
|
66
|
+
Arachni::Processes::Manager.kill subject.browser_pid
|
67
|
+
expect(Arachni::Processes::Manager.alive?(subject.lifeline_pid)).to be_falsey
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when the lifeline dies' do
|
72
|
+
it 'kills the browser too' do
|
73
|
+
Arachni::Processes::Manager.kill subject.lifeline_pid
|
74
|
+
expect(Arachni::Processes::Manager.alive?(subject.browser_pid)).to be_falsey
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe '#alive?' do
|
79
|
+
context 'when the lifeline is alive' do
|
80
|
+
it 'returns true' do
|
81
|
+
expect(Arachni::Processes::Manager.alive?(subject.lifeline_pid)).to be_truthy
|
82
|
+
expect(subject).to be_alive
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'when the browser is dead' do
|
87
|
+
it 'returns false' do
|
88
|
+
Arachni::Processes::Manager.kill subject.browser_pid
|
89
|
+
|
90
|
+
expect(subject).to_not be_alive
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'when the lifeline is dead' do
|
95
|
+
it 'returns false' do
|
96
|
+
Arachni::Processes::Manager << subject.browser_pid
|
97
|
+
Arachni::Processes::Manager.kill subject.lifeline_pid
|
98
|
+
|
99
|
+
expect(subject).to_not be_alive
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
63
104
|
describe '.has_executable?' do
|
64
105
|
context 'when there is no executable browser' do
|
65
106
|
it 'returns false' do
|
@@ -85,12 +126,12 @@ describe Arachni::Browser do
|
|
85
126
|
end
|
86
127
|
|
87
128
|
describe '#initialize' do
|
88
|
-
describe :concurrency do
|
129
|
+
describe ':concurrency' do
|
89
130
|
it 'sets the HTTP request concurrency'
|
90
131
|
end
|
91
132
|
|
92
|
-
describe :ignore_scope do
|
93
|
-
context true do
|
133
|
+
describe ':ignore_scope' do
|
134
|
+
context 'true' do
|
94
135
|
it 'ignores scope restrictions' do
|
95
136
|
@browser.shutdown
|
96
137
|
|
@@ -103,7 +144,7 @@ describe Arachni::Browser do
|
|
103
144
|
end
|
104
145
|
end
|
105
146
|
|
106
|
-
context false do
|
147
|
+
context 'false' do
|
107
148
|
it 'enforces scope restrictions' do
|
108
149
|
@browser.shutdown
|
109
150
|
|
@@ -116,7 +157,7 @@ describe Arachni::Browser do
|
|
116
157
|
end
|
117
158
|
end
|
118
159
|
|
119
|
-
context :default do
|
160
|
+
context ':default' do
|
120
161
|
it 'enforces scope restrictions' do
|
121
162
|
@browser.shutdown
|
122
163
|
|
@@ -130,35 +171,45 @@ describe Arachni::Browser do
|
|
130
171
|
end
|
131
172
|
end
|
132
173
|
|
133
|
-
describe :width do
|
174
|
+
describe ':width' do
|
134
175
|
it 'sets the window width' do
|
135
176
|
@browser.shutdown
|
136
177
|
|
137
178
|
width = 100
|
138
179
|
@browser = described_class.new( width: width )
|
180
|
+
|
181
|
+
subject.load @url
|
182
|
+
|
139
183
|
expect(subject.javascript.run('return window.innerWidth')).to eq(width)
|
140
184
|
end
|
141
185
|
|
142
186
|
it 'defaults to 1600' do
|
187
|
+
subject.load @url
|
188
|
+
|
143
189
|
expect(subject.javascript.run('return window.innerWidth')).to eq(1600)
|
144
190
|
end
|
145
191
|
end
|
146
192
|
|
147
|
-
describe :height do
|
193
|
+
describe ':height' do
|
148
194
|
it 'sets the window height' do
|
149
195
|
@browser.shutdown
|
150
196
|
|
151
197
|
height = 100
|
152
198
|
@browser = described_class.new( height: height )
|
199
|
+
|
200
|
+
subject.load @url
|
201
|
+
|
153
202
|
expect(subject.javascript.run('return window.innerHeight')).to eq(height)
|
154
203
|
end
|
155
204
|
|
156
205
|
it 'defaults to 1200' do
|
206
|
+
subject.load @url
|
207
|
+
|
157
208
|
expect(subject.javascript.run('return window.innerHeight')).to eq(1200)
|
158
209
|
end
|
159
210
|
end
|
160
211
|
|
161
|
-
describe :store_pages do
|
212
|
+
describe ':store_pages' do
|
162
213
|
describe 'default' do
|
163
214
|
it 'stores snapshot pages' do
|
164
215
|
@browser.shutdown
|
@@ -174,7 +225,7 @@ describe Arachni::Browser do
|
|
174
225
|
end
|
175
226
|
end
|
176
227
|
|
177
|
-
describe true do
|
228
|
+
describe 'true' do
|
178
229
|
it 'stores snapshot pages' do
|
179
230
|
@browser.shutdown
|
180
231
|
@browser = described_class.new( store_pages: true )
|
@@ -189,7 +240,7 @@ describe Arachni::Browser do
|
|
189
240
|
end
|
190
241
|
end
|
191
242
|
|
192
|
-
describe false do
|
243
|
+
describe 'false' do
|
193
244
|
it 'stores snapshot pages' do
|
194
245
|
@browser.shutdown
|
195
246
|
@browser = described_class.new( store_pages: false )
|
@@ -292,7 +343,7 @@ describe Arachni::Browser do
|
|
292
343
|
end
|
293
344
|
|
294
345
|
context '#store_pages?' do
|
295
|
-
context true do
|
346
|
+
context 'true' do
|
296
347
|
subject { @browser.shutdown; @browser = described_class.new( store_pages: true )}
|
297
348
|
|
298
349
|
it 'stores it in #page_snapshots' do
|
@@ -307,7 +358,7 @@ describe Arachni::Browser do
|
|
307
358
|
end
|
308
359
|
end
|
309
360
|
|
310
|
-
context false do
|
361
|
+
context 'false' do
|
311
362
|
subject { @browser.shutdown; @browser = described_class.new( store_pages: false ) }
|
312
363
|
|
313
364
|
it 'does not store it' do
|
@@ -365,7 +416,7 @@ describe Arachni::Browser do
|
|
365
416
|
end
|
366
417
|
|
367
418
|
context '#store_pages?' do
|
368
|
-
context true do
|
419
|
+
context 'true' do
|
369
420
|
subject { @browser.shutdown; @browser = described_class.new( store_pages: true )}
|
370
421
|
|
371
422
|
it 'stores it in #page_snapshots_with_sinks' do
|
@@ -374,7 +425,7 @@ describe Arachni::Browser do
|
|
374
425
|
end
|
375
426
|
end
|
376
427
|
|
377
|
-
context false do
|
428
|
+
context 'false' do
|
378
429
|
subject { @browser.shutdown; @browser = described_class.new( store_pages: false )}
|
379
430
|
|
380
431
|
it 'does not store it in #page_snapshots_with_sinks' do
|
@@ -399,24 +450,21 @@ describe Arachni::Browser do
|
|
399
450
|
end
|
400
451
|
|
401
452
|
context 'when there are multiple windows open' do
|
402
|
-
before :each do
|
403
|
-
subject.load( ajax_url, take_snapshot: false )
|
404
|
-
end
|
405
453
|
|
406
454
|
it 'captures snapshots from all windows' do
|
407
|
-
|
408
|
-
|
409
|
-
subject.load
|
455
|
+
url = "#{@url}open-new-window"
|
456
|
+
|
457
|
+
subject.load url, take_snapshot: false
|
410
458
|
|
411
459
|
expect(subject.capture_snapshot.map(&:url).sort).to eq(
|
412
|
-
[
|
460
|
+
[url, "#{@url}with-ajax"].sort
|
413
461
|
)
|
414
462
|
end
|
415
463
|
end
|
416
464
|
|
417
465
|
context 'when an error occurs' do
|
418
466
|
it 'ignores it' do
|
419
|
-
allow(subject
|
467
|
+
allow(subject).to receive(:to_page) { raise }
|
420
468
|
expect(subject.capture_snapshot( blah: :stuff )).to be_empty
|
421
469
|
end
|
422
470
|
end
|
@@ -496,8 +544,8 @@ describe Arachni::Browser do
|
|
496
544
|
calls << [element.opening_tag, event]
|
497
545
|
end
|
498
546
|
|
499
|
-
@browser.fire_event @browser.
|
500
|
-
@browser.fire_event @browser.
|
547
|
+
@browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :click
|
548
|
+
@browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :mouseover
|
501
549
|
|
502
550
|
expect(calls).to eq([
|
503
551
|
[ "<div id=\"my-div\" onclick=\"addForm();\">", :click ],
|
@@ -590,7 +638,7 @@ describe Arachni::Browser do
|
|
590
638
|
tag_name: 'a',
|
591
639
|
attributes: {
|
592
640
|
'onmouseover' => 'writeButton();',
|
593
|
-
'href' => '
|
641
|
+
'href' => '#'
|
594
642
|
}
|
595
643
|
} => :mouseover
|
596
644
|
}
|
@@ -603,11 +651,11 @@ describe Arachni::Browser do
|
|
603
651
|
{
|
604
652
|
tag_name: 'a',
|
605
653
|
attributes: {
|
606
|
-
'onmouseover' => 'writeButton();',
|
607
654
|
'href' => 'javascript:level3();'
|
608
655
|
}
|
609
656
|
} => :click
|
610
657
|
},
|
658
|
+
{ "#{@url}level4" => :request },
|
611
659
|
{ "#{@url}level4" => :request }
|
612
660
|
],
|
613
661
|
[
|
@@ -619,7 +667,7 @@ describe Arachni::Browser do
|
|
619
667
|
tag_name: 'a',
|
620
668
|
attributes: {
|
621
669
|
'onmouseover' => 'writeButton();',
|
622
|
-
'href' => '
|
670
|
+
'href' => '#'
|
623
671
|
}
|
624
672
|
} => :mouseover
|
625
673
|
},
|
@@ -640,12 +688,12 @@ describe Arachni::Browser do
|
|
640
688
|
{
|
641
689
|
tag_name: 'a',
|
642
690
|
attributes: {
|
643
|
-
'onmouseover' => 'writeButton();',
|
644
691
|
'href' => 'javascript:level3();'
|
645
692
|
}
|
646
693
|
} => :click
|
647
694
|
},
|
648
695
|
{ "#{@url}level4" => :request },
|
696
|
+
{ "#{@url}level4" => :request },
|
649
697
|
{
|
650
698
|
{
|
651
699
|
tag_name: 'div',
|
@@ -680,7 +728,7 @@ describe Arachni::Browser do
|
|
680
728
|
tag_name: 'a',
|
681
729
|
attributes: {
|
682
730
|
'onmouseover' => 'writeButton();',
|
683
|
-
'href' => '
|
731
|
+
'href' => '#'
|
684
732
|
}
|
685
733
|
} => :mouseover
|
686
734
|
}
|
@@ -693,11 +741,11 @@ describe Arachni::Browser do
|
|
693
741
|
{
|
694
742
|
tag_name: 'a',
|
695
743
|
attributes: {
|
696
|
-
'onmouseover' => 'writeButton();',
|
697
744
|
'href' => 'javascript:level3();'
|
698
745
|
}
|
699
746
|
} => :click
|
700
747
|
},
|
748
|
+
{ "#{@url}level4" => :request },
|
701
749
|
{ "#{@url}level4" => :request }
|
702
750
|
]
|
703
751
|
].map { |transitions| transitions_from_array( transitions ) })
|
@@ -991,15 +1039,62 @@ describe Arachni::Browser do
|
|
991
1039
|
it 'returns nil'
|
992
1040
|
end
|
993
1041
|
|
994
|
-
context 'when the resource is out
|
1042
|
+
context 'when the resource is out of scope' do
|
995
1043
|
it 'returns nil' do
|
996
1044
|
Arachni::Options.url = @url
|
997
|
-
@browser.load
|
1045
|
+
@browser.load @url
|
1046
|
+
|
1047
|
+
subject.javascript.run( 'window.location = "http://google.com/";' )
|
1048
|
+
sleep 1
|
1049
|
+
|
998
1050
|
expect(@browser.response).to be_nil
|
999
1051
|
end
|
1000
1052
|
end
|
1001
1053
|
end
|
1002
1054
|
|
1055
|
+
describe '#state' do
|
1056
|
+
it 'returns a Page::DOM with enough info to reproduce the current state' do
|
1057
|
+
@browser.load "#{web_server_url_for( :taint_tracer )}/debug" <<
|
1058
|
+
"?input=#{@browser.javascript.log_execution_flow_sink_stub(1)}"
|
1059
|
+
|
1060
|
+
dom = subject.to_page.dom
|
1061
|
+
state = subject.state
|
1062
|
+
|
1063
|
+
expect(state.page).to be_nil
|
1064
|
+
expect(state.url).to eq dom.url
|
1065
|
+
expect(state.digest).to eq dom.digest
|
1066
|
+
expect(state.transitions).to eq dom.transitions
|
1067
|
+
expect(state.skip_states).to eq dom.skip_states
|
1068
|
+
expect(state.data_flow_sinks).to be_empty
|
1069
|
+
expect(state.execution_flow_sinks).to be_empty
|
1070
|
+
end
|
1071
|
+
|
1072
|
+
context 'when the URL is about:blank' do
|
1073
|
+
it 'returns nil' do
|
1074
|
+
Arachni::Options.url = @url
|
1075
|
+
subject.load @url
|
1076
|
+
|
1077
|
+
subject.javascript.run( 'window.location = "about:blank";' )
|
1078
|
+
sleep 1
|
1079
|
+
|
1080
|
+
expect(subject.state).to be_nil
|
1081
|
+
end
|
1082
|
+
end
|
1083
|
+
|
1084
|
+
context 'when the resource is out-of-scope' do
|
1085
|
+
it 'returns an empty page' do
|
1086
|
+
Arachni::Options.url = @url
|
1087
|
+
subject.load @url
|
1088
|
+
|
1089
|
+
subject.javascript.run( 'window.location = "http://google.com/";' )
|
1090
|
+
sleep 1
|
1091
|
+
|
1092
|
+
expect(subject.state).to be_nil
|
1093
|
+
end
|
1094
|
+
end
|
1095
|
+
|
1096
|
+
end
|
1097
|
+
|
1003
1098
|
describe '#to_page' do
|
1004
1099
|
it "converts the working window to an #{Arachni::Page}" do
|
1005
1100
|
ua = Arachni::Options.http.user_agent
|
@@ -1017,10 +1112,12 @@ describe Arachni::Browser do
|
|
1017
1112
|
it "assigns the proper #{Arachni::Page::DOM}#digest" do
|
1018
1113
|
@browser.load( @url )
|
1019
1114
|
expect(@browser.to_page.dom.instance_variable_get(:@digest)).to eq(
|
1020
|
-
'<HTML><HEAD><SCRIPT src=http://
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1115
|
+
'<HTML><HEAD><SCRIPT src=http://' <<
|
1116
|
+
'javascript.browser.arachni/polyfills.js><SCRIPT src=http://' <<
|
1117
|
+
'javascript.browser.arachni/' <<
|
1118
|
+
'taint_tracer.js><SCRIPT src=http://javascript.' <<
|
1119
|
+
'browser.arachni/dom_monitor.js><SCRIPT><TITLE><BODY><' <<
|
1120
|
+
'DIV><SCRIPT type=text/javascript><SCRIPT type=text/javascript>'
|
1024
1121
|
)
|
1025
1122
|
end
|
1026
1123
|
|
@@ -1078,7 +1175,7 @@ describe Arachni::Browser do
|
|
1078
1175
|
context 'when the page has' do
|
1079
1176
|
context "#{Arachni::Element::UIForm} elements" do
|
1080
1177
|
context "and #{Arachni::OptionGroups::Audit}#inputs is" do
|
1081
|
-
context true do
|
1178
|
+
context 'true' do
|
1082
1179
|
before do
|
1083
1180
|
Arachni::Options.audit.elements :ui_forms
|
1084
1181
|
end
|
@@ -1126,7 +1223,7 @@ describe Arachni::Browser do
|
|
1126
1223
|
end
|
1127
1224
|
end
|
1128
1225
|
|
1129
|
-
context false do
|
1226
|
+
context 'false' do
|
1130
1227
|
before do
|
1131
1228
|
Arachni::Options.audit.skip_elements :ui_forms
|
1132
1229
|
end
|
@@ -1141,7 +1238,7 @@ describe Arachni::Browser do
|
|
1141
1238
|
|
1142
1239
|
context "#{Arachni::Element::UIInput} elements" do
|
1143
1240
|
context "and #{Arachni::OptionGroups::Audit}#inputs is" do
|
1144
|
-
context true do
|
1241
|
+
context 'true' do
|
1145
1242
|
before do
|
1146
1243
|
Arachni::Options.audit.elements :ui_inputs
|
1147
1244
|
end
|
@@ -1189,7 +1286,7 @@ describe Arachni::Browser do
|
|
1189
1286
|
end
|
1190
1287
|
end
|
1191
1288
|
|
1192
|
-
context false do
|
1289
|
+
context 'false' do
|
1193
1290
|
before do
|
1194
1291
|
Arachni::Options.audit.skip_elements :ui_inputs
|
1195
1292
|
end
|
@@ -1204,7 +1301,7 @@ describe Arachni::Browser do
|
|
1204
1301
|
|
1205
1302
|
context "#{Arachni::Element::Form::DOM} elements" do
|
1206
1303
|
context "and #{Arachni::OptionGroups::Audit}#forms is" do
|
1207
|
-
context true do
|
1304
|
+
context 'true' do
|
1208
1305
|
before do
|
1209
1306
|
Arachni::Options.audit.elements :forms
|
1210
1307
|
end
|
@@ -1231,7 +1328,7 @@ describe Arachni::Browser do
|
|
1231
1328
|
end
|
1232
1329
|
end
|
1233
1330
|
|
1234
|
-
context false do
|
1331
|
+
context 'false' do
|
1235
1332
|
before do
|
1236
1333
|
Arachni::Options.audit.skip_elements :forms
|
1237
1334
|
end
|
@@ -1248,7 +1345,7 @@ describe Arachni::Browser do
|
|
1248
1345
|
let(:cookies) { @browser.to_page.cookies }
|
1249
1346
|
|
1250
1347
|
context "and #{Arachni::OptionGroups::Audit}#cookies is" do
|
1251
|
-
context true do
|
1348
|
+
context 'true' do
|
1252
1349
|
before do
|
1253
1350
|
Arachni::Options.audit.elements :cookies
|
1254
1351
|
|
@@ -1261,8 +1358,16 @@ describe Arachni::Browser do
|
|
1261
1358
|
let(:page) { 'dom-cookies-names' }
|
1262
1359
|
|
1263
1360
|
it 'does not set #skip_dom' do
|
1264
|
-
expect(cookies.find { |c| c.name == '
|
1265
|
-
expect(cookies.find { |c| c.name == '
|
1361
|
+
expect(cookies.find { |c| c.name == 'js_cookie1' }.skip_dom).to be_nil
|
1362
|
+
expect(cookies.find { |c| c.name == 'js_cookie2' }.skip_dom).to be_nil
|
1363
|
+
end
|
1364
|
+
|
1365
|
+
it 'does not track HTTP-only cookies' do
|
1366
|
+
expect(cookies.find { |c| c.name == 'http_only_cookie' }.skip_dom).to be true
|
1367
|
+
end
|
1368
|
+
|
1369
|
+
it 'does not track cookies for other paths' do
|
1370
|
+
expect(cookies.find { |c| c.name == 'other_path' }.skip_dom).to be true
|
1266
1371
|
end
|
1267
1372
|
end
|
1268
1373
|
|
@@ -1270,8 +1375,16 @@ describe Arachni::Browser do
|
|
1270
1375
|
let(:page) { 'dom-cookies-values' }
|
1271
1376
|
|
1272
1377
|
it 'does not set #skip_dom' do
|
1273
|
-
expect(cookies.find { |c| c.name == '
|
1274
|
-
expect(cookies.find { |c| c.name == '
|
1378
|
+
expect(cookies.find { |c| c.name == 'js_cookie1' }.skip_dom).to be_nil
|
1379
|
+
expect(cookies.find { |c| c.name == 'js_cookie2' }.skip_dom).to be_nil
|
1380
|
+
end
|
1381
|
+
|
1382
|
+
it 'does not track HTTP-only cookies' do
|
1383
|
+
expect(cookies.find { |c| c.name == 'http_only_cookie' }.skip_dom).to be true
|
1384
|
+
end
|
1385
|
+
|
1386
|
+
it 'does not track cookies for other paths' do
|
1387
|
+
expect(cookies.find { |c| c.name == 'other_path' }.skip_dom).to be true
|
1275
1388
|
end
|
1276
1389
|
end
|
1277
1390
|
end
|
@@ -1281,7 +1394,7 @@ describe Arachni::Browser do
|
|
1281
1394
|
let(:page) { 'dom-cookies-names' }
|
1282
1395
|
|
1283
1396
|
it 'does not set #skip_dom' do
|
1284
|
-
expect(cookies.find { |c| c.name == '
|
1397
|
+
expect(cookies.find { |c| c.name == 'js_cookie3' }.skip_dom).to be_truthy
|
1285
1398
|
end
|
1286
1399
|
end
|
1287
1400
|
|
@@ -1289,13 +1402,13 @@ describe Arachni::Browser do
|
|
1289
1402
|
let(:page) { 'dom-cookies-values' }
|
1290
1403
|
|
1291
1404
|
it 'does not set #skip_dom' do
|
1292
|
-
expect(cookies.find { |c| c.name == '
|
1405
|
+
expect(cookies.find { |c| c.name == 'js_cookie3' }.skip_dom).to be_truthy
|
1293
1406
|
end
|
1294
1407
|
end
|
1295
1408
|
end
|
1296
1409
|
end
|
1297
1410
|
|
1298
|
-
context false do
|
1411
|
+
context 'false' do
|
1299
1412
|
before do
|
1300
1413
|
Arachni::Options.audit.skip_elements :cookies
|
1301
1414
|
|
@@ -1319,13 +1432,17 @@ describe Arachni::Browser do
|
|
1319
1432
|
context 'when the resource is out-of-scope' do
|
1320
1433
|
it 'returns an empty page' do
|
1321
1434
|
Arachni::Options.url = @url
|
1322
|
-
subject.load
|
1435
|
+
subject.load @url
|
1436
|
+
|
1437
|
+
subject.javascript.run( 'window.location = "http://google.com/";' )
|
1438
|
+
sleep 1
|
1439
|
+
|
1323
1440
|
page = subject.to_page
|
1324
1441
|
|
1325
1442
|
expect(page.code).to eq(0)
|
1326
|
-
expect(page.url).to eq(
|
1443
|
+
expect(page.url).to eq('http://google.com/')
|
1327
1444
|
expect(page.body).to be_empty
|
1328
|
-
expect(page.dom.url).to eq(
|
1445
|
+
expect(page.dom.url).to eq('http://google.com/')
|
1329
1446
|
end
|
1330
1447
|
end
|
1331
1448
|
end
|
@@ -1337,22 +1454,22 @@ describe Arachni::Browser do
|
|
1337
1454
|
end
|
1338
1455
|
|
1339
1456
|
it 'fires the given event' do
|
1340
|
-
@browser.fire_event @browser.
|
1457
|
+
@browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :click
|
1341
1458
|
pages_should_have_form_with_input [@browser.to_page], 'by-ajax'
|
1342
1459
|
end
|
1343
1460
|
|
1344
1461
|
it 'accepts events without the "on" prefix' do
|
1345
1462
|
pages_should_not_have_form_with_input [@browser.to_page], 'by-ajax'
|
1346
1463
|
|
1347
|
-
@browser.fire_event @browser.
|
1464
|
+
@browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :onclick
|
1348
1465
|
pages_should_have_form_with_input [@browser.to_page], 'by-ajax'
|
1349
1466
|
|
1350
|
-
@browser.fire_event @browser.
|
1467
|
+
@browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :click
|
1351
1468
|
pages_should_have_form_with_input [@browser.to_page], 'by-ajax'
|
1352
1469
|
end
|
1353
1470
|
|
1354
1471
|
it 'returns a playable transition' do
|
1355
|
-
transition = @browser.fire_event @browser.
|
1472
|
+
transition = @browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :click
|
1356
1473
|
pages_should_have_form_with_input [@browser.to_page], 'by-ajax'
|
1357
1474
|
|
1358
1475
|
@browser.load( url ).start_capture
|
@@ -1362,12 +1479,51 @@ describe Arachni::Browser do
|
|
1362
1479
|
pages_should_have_form_with_input [@browser.to_page], 'by-ajax'
|
1363
1480
|
end
|
1364
1481
|
|
1365
|
-
context 'when
|
1366
|
-
|
1367
|
-
|
1482
|
+
context 'when new timers are introduced' do
|
1483
|
+
let(:url) { "#{@url}/trigger_events/with_new_timers/3000" }
|
1484
|
+
|
1485
|
+
it 'waits for them' do
|
1486
|
+
@browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :click
|
1487
|
+
pages_should_have_form_with_input [@browser.to_page], 'by-ajax'
|
1488
|
+
end
|
1489
|
+
|
1490
|
+
context 'when a new timer exceeds Options.http.request_timeout' do
|
1491
|
+
let(:url) { "#{@url}/trigger_events/with_new_timers/#{Arachni::Options.http.request_timeout + 5000}" }
|
1492
|
+
|
1493
|
+
it 'waits for Options.http.request_timeout' do
|
1494
|
+
t = Time.now
|
1495
|
+
|
1496
|
+
@browser.fire_event @browser.selenium.find_element( id: 'my-div' ), :click
|
1497
|
+
pages_should_not_have_form_with_input [@browser.to_page], 'by-ajax'
|
1498
|
+
|
1499
|
+
expect(Time.now - t).to be <= Arachni::Options.http.request_timeout
|
1500
|
+
end
|
1501
|
+
end
|
1502
|
+
end
|
1503
|
+
|
1504
|
+
context 'when cookies are set' do
|
1505
|
+
let(:url) { @url + '/each_element_with_events/set-cookie' }
|
1368
1506
|
|
1369
|
-
|
1507
|
+
it 'sets them globally' do
|
1508
|
+
expect(Arachni::HTTP::Client.cookies).to be_empty
|
1370
1509
|
|
1510
|
+
@browser.fire_event described_class::ElementLocator.new(
|
1511
|
+
tag_name: :button,
|
1512
|
+
attributes: {
|
1513
|
+
onclick: 'setCookie()'
|
1514
|
+
}
|
1515
|
+
), :click
|
1516
|
+
|
1517
|
+
cookie = Arachni::HTTP::Client.cookies.first
|
1518
|
+
expect(cookie.name).to eq 'cookie_name'
|
1519
|
+
expect(cookie.value).to eq 'cookie value'
|
1520
|
+
end
|
1521
|
+
end
|
1522
|
+
|
1523
|
+
context 'when the element is not visible' do
|
1524
|
+
it 'returns nil' do
|
1525
|
+
@browser.goto "#{url}/invisible-div"
|
1526
|
+
element = @browser.selenium.find_element( id: 'invisible-div' )
|
1371
1527
|
expect(@browser.fire_event( element, :click )).to be_nil
|
1372
1528
|
end
|
1373
1529
|
end
|
@@ -1382,57 +1538,45 @@ describe Arachni::Browser do
|
|
1382
1538
|
|
1383
1539
|
allow(element).to receive(:locate){ raise Selenium::WebDriver::Error::WebDriverError }
|
1384
1540
|
expect(@browser.fire_event( element, :click )).to be_nil
|
1385
|
-
|
1386
|
-
allow(element).to receive(:locate){ raise Watir::Exception::Error }
|
1387
|
-
expect(@browser.fire_event( element, :click )).to be_nil
|
1388
1541
|
end
|
1389
1542
|
end
|
1390
1543
|
end
|
1391
1544
|
|
1392
|
-
context 'when the element never appears' do
|
1393
|
-
it 'returns nil' do
|
1394
|
-
element = @browser.watir.div( id: 'my-div' )
|
1395
|
-
|
1396
|
-
allow(element).to receive(:exists?) { false }
|
1397
|
-
|
1398
|
-
expect(@browser.fire_event( element, :click )).to be_nil
|
1399
|
-
end
|
1400
|
-
end
|
1401
|
-
|
1402
1545
|
context 'when the trigger fails with' do
|
1403
|
-
let(:element) { @browser.
|
1546
|
+
let(:element) { @browser.selenium.find_element( id: 'my-div' ) }
|
1404
1547
|
|
1405
|
-
context Selenium::WebDriver::Error::WebDriverError do
|
1548
|
+
context 'Selenium::WebDriver::Error::WebDriverError' do
|
1406
1549
|
it 'returns nil' do
|
1407
|
-
allow(
|
1408
|
-
|
1409
|
-
|
1410
|
-
end
|
1550
|
+
allow(@browser).to receive(:wait_for_pending_requests) do
|
1551
|
+
raise Selenium::WebDriver::Error::WebDriverError
|
1552
|
+
end
|
1411
1553
|
|
1412
|
-
context Watir::Exception::Error do
|
1413
|
-
it 'returns nil' do
|
1414
|
-
allow(element).to receive(:fire_event){ raise Watir::Exception::Error }
|
1415
1554
|
expect(@browser.fire_event( element, :click )).to be_nil
|
1416
1555
|
end
|
1417
1556
|
end
|
1418
1557
|
end
|
1419
1558
|
|
1420
1559
|
context 'form' do
|
1421
|
-
context :submit do
|
1560
|
+
context ':submit' do
|
1422
1561
|
let(:url) { "#{@url}/fire_event/form/onsubmit" }
|
1423
1562
|
|
1424
1563
|
context 'when option' do
|
1425
|
-
describe :inputs do
|
1564
|
+
describe ':inputs' do
|
1565
|
+
|
1566
|
+
def element
|
1567
|
+
@browser.selenium.find_element(:tag_name, :form)
|
1568
|
+
end
|
1569
|
+
|
1426
1570
|
context 'is given' do
|
1427
1571
|
let(:inputs) do
|
1428
1572
|
{
|
1429
|
-
name:
|
1573
|
+
name: 'The Dude',
|
1430
1574
|
email: 'the.dude@abides.com'
|
1431
1575
|
}
|
1432
1576
|
end
|
1433
1577
|
|
1434
1578
|
before(:each) do
|
1435
|
-
@browser.fire_event
|
1579
|
+
@browser.fire_event element, :submit, inputs: inputs
|
1436
1580
|
end
|
1437
1581
|
|
1438
1582
|
it 'fills in its inputs with the given values' do
|
@@ -1447,7 +1591,7 @@ describe Arachni::Browser do
|
|
1447
1591
|
it 'returns a playable transition' do
|
1448
1592
|
@browser.load url
|
1449
1593
|
|
1450
|
-
transition = @browser.fire_event
|
1594
|
+
transition = @browser.fire_event element, :submit, inputs: inputs
|
1451
1595
|
|
1452
1596
|
@browser.load url
|
1453
1597
|
|
@@ -1513,7 +1657,7 @@ describe Arachni::Browser do
|
|
1513
1657
|
|
1514
1658
|
it 'returns a playable transition' do
|
1515
1659
|
@browser.load url
|
1516
|
-
transition = @browser.fire_event
|
1660
|
+
transition = @browser.fire_event element, :submit, inputs: inputs
|
1517
1661
|
|
1518
1662
|
@browser.load url
|
1519
1663
|
|
@@ -1541,7 +1685,7 @@ describe Arachni::Browser do
|
|
1541
1685
|
|
1542
1686
|
it 'returns a playable transition' do
|
1543
1687
|
@browser.load url
|
1544
|
-
transition = @browser.fire_event
|
1688
|
+
transition = @browser.fire_event element, :submit, inputs: inputs
|
1545
1689
|
|
1546
1690
|
@browser.load url
|
1547
1691
|
|
@@ -1570,7 +1714,7 @@ describe Arachni::Browser do
|
|
1570
1714
|
context 'is not given' do
|
1571
1715
|
it 'fills in its inputs with sample values' do
|
1572
1716
|
@browser.load url
|
1573
|
-
@browser.fire_event
|
1717
|
+
@browser.fire_event element, :submit
|
1574
1718
|
|
1575
1719
|
expect(@browser.watir.div( id: 'container-name' ).text).to eq(
|
1576
1720
|
Arachni::Options.input.value_for_name( 'name' )
|
@@ -1582,7 +1726,7 @@ describe Arachni::Browser do
|
|
1582
1726
|
|
1583
1727
|
it 'returns a playable transition' do
|
1584
1728
|
@browser.load url
|
1585
|
-
transition = @browser.fire_event
|
1729
|
+
transition = @browser.fire_event element, :submit
|
1586
1730
|
|
1587
1731
|
@browser.load url
|
1588
1732
|
|
@@ -1603,7 +1747,7 @@ describe Arachni::Browser do
|
|
1603
1747
|
let(:url) { "#{@url}/fire_event/form/disabled_inputs" }
|
1604
1748
|
|
1605
1749
|
it 'is skips those inputs' do
|
1606
|
-
@browser.fire_event
|
1750
|
+
@browser.fire_event element, :submit
|
1607
1751
|
|
1608
1752
|
expect(@browser.watir.div( id: 'container-name' ).text).to eq(
|
1609
1753
|
Arachni::Options.input.value_for_name( 'name' )
|
@@ -1617,13 +1761,17 @@ describe Arachni::Browser do
|
|
1617
1761
|
end
|
1618
1762
|
|
1619
1763
|
context 'image button' do
|
1620
|
-
context :click do
|
1764
|
+
context ':click' do
|
1621
1765
|
before( :each ) { @browser.start_capture }
|
1622
1766
|
let(:url) { "#{@url}fire_event/form/image-input" }
|
1623
1767
|
|
1768
|
+
def element
|
1769
|
+
@browser.selenium.find_element( :xpath, '//input[@type="image"]')
|
1770
|
+
end
|
1771
|
+
|
1624
1772
|
it 'submits the form with x, y coordinates' do
|
1625
1773
|
@browser.load( url )
|
1626
|
-
@browser.fire_event
|
1774
|
+
@browser.fire_event element, :click
|
1627
1775
|
|
1628
1776
|
pages_should_have_form_with_input @browser.captured_pages, 'myImageButton.x'
|
1629
1777
|
pages_should_have_form_with_input @browser.captured_pages, 'myImageButton.y'
|
@@ -1631,7 +1779,7 @@ describe Arachni::Browser do
|
|
1631
1779
|
|
1632
1780
|
it 'returns a playable transition' do
|
1633
1781
|
@browser.load( url )
|
1634
|
-
transition = @browser.fire_event
|
1782
|
+
transition = @browser.fire_event element, :click
|
1635
1783
|
|
1636
1784
|
captured_pages = @browser.flush_pages
|
1637
1785
|
pages_should_have_form_with_input captured_pages, 'myImageButton.x'
|
@@ -1658,18 +1806,22 @@ describe Arachni::Browser do
|
|
1658
1806
|
string[0...-1] : string
|
1659
1807
|
end
|
1660
1808
|
|
1661
|
-
context event do
|
1809
|
+
context event.to_s do
|
1662
1810
|
let( :url ) { "#{@url}/fire_event/input/#{event}" }
|
1663
1811
|
|
1664
1812
|
context 'when option' do
|
1665
|
-
describe :inputs do
|
1813
|
+
describe ':inputs' do
|
1814
|
+
def element
|
1815
|
+
@browser.selenium.find_element(:tag_name, :input)
|
1816
|
+
end
|
1817
|
+
|
1666
1818
|
context 'is given' do
|
1667
1819
|
let(:value) do
|
1668
1820
|
'The Dude'
|
1669
1821
|
end
|
1670
1822
|
|
1671
1823
|
before(:each) do
|
1672
|
-
@browser.fire_event
|
1824
|
+
@browser.fire_event element, event, value: value
|
1673
1825
|
end
|
1674
1826
|
|
1675
1827
|
it 'fills in its inputs with the given values' do
|
@@ -1680,7 +1832,7 @@ describe Arachni::Browser do
|
|
1680
1832
|
|
1681
1833
|
it 'returns a playable transition' do
|
1682
1834
|
@browser.load url
|
1683
|
-
transition = @browser.fire_event
|
1835
|
+
transition = @browser.fire_event element, event, value: value
|
1684
1836
|
|
1685
1837
|
@browser.load url
|
1686
1838
|
expect(@browser.watir.div( id: 'container' ).text).to be_empty
|
@@ -1702,7 +1854,7 @@ describe Arachni::Browser do
|
|
1702
1854
|
|
1703
1855
|
it 'returns a playable transition' do
|
1704
1856
|
@browser.load url
|
1705
|
-
transition = @browser.fire_event
|
1857
|
+
transition = @browser.fire_event element, event, value: value
|
1706
1858
|
|
1707
1859
|
@browser.load url
|
1708
1860
|
expect(@browser.watir.div( id: 'container' ).text).to be_empty
|
@@ -1715,7 +1867,7 @@ describe Arachni::Browser do
|
|
1715
1867
|
|
1716
1868
|
context 'is not given' do
|
1717
1869
|
it 'fills in a sample value' do
|
1718
|
-
@browser.fire_event
|
1870
|
+
@browser.fire_event element, event
|
1719
1871
|
|
1720
1872
|
expect(@browser.watir.div( id: 'container' ).text).to eq(
|
1721
1873
|
calculate_expectation.call( Arachni::Options.input.value_for_name( 'name' ) )
|
@@ -1724,7 +1876,7 @@ describe Arachni::Browser do
|
|
1724
1876
|
|
1725
1877
|
it 'returns a playable transition' do
|
1726
1878
|
@browser.load url
|
1727
|
-
transition = @browser.fire_event
|
1879
|
+
transition = @browser.fire_event element, event
|
1728
1880
|
|
1729
1881
|
@browser.load url
|
1730
1882
|
expect(@browser.watir.div( id: 'container' ).text).to be_empty
|
@@ -1742,6 +1894,44 @@ describe Arachni::Browser do
|
|
1742
1894
|
end
|
1743
1895
|
end
|
1744
1896
|
|
1897
|
+
describe '#elements_with_events' do
|
1898
|
+
before :each do
|
1899
|
+
@browser.load url
|
1900
|
+
end
|
1901
|
+
|
1902
|
+
let(:elements_with_events) do
|
1903
|
+
elements_with_events = {}
|
1904
|
+
@browser.each_element_with_events do |locator, events|
|
1905
|
+
elements_with_events[locator] = events
|
1906
|
+
end
|
1907
|
+
elements_with_events
|
1908
|
+
end
|
1909
|
+
|
1910
|
+
let(:url) { @url + '/trigger_events' }
|
1911
|
+
|
1912
|
+
it 'returns all elements with associated events' do
|
1913
|
+
expect(subject.elements_with_events.to_s).to eq elements_with_events.to_s
|
1914
|
+
end
|
1915
|
+
|
1916
|
+
it 'caches results' do
|
1917
|
+
expect(subject).to receive(:each_element_with_events)
|
1918
|
+
subject.elements_with_events
|
1919
|
+
|
1920
|
+
expect(subject).to_not receive(:each_element_with_events)
|
1921
|
+
subject.elements_with_events
|
1922
|
+
end
|
1923
|
+
|
1924
|
+
context 'when passed true' do
|
1925
|
+
it 'clears the cache' do
|
1926
|
+
expect(subject).to receive(:each_element_with_events)
|
1927
|
+
subject.elements_with_events
|
1928
|
+
|
1929
|
+
expect(subject).to receive(:each_element_with_events)
|
1930
|
+
subject.elements_with_events( true )
|
1931
|
+
end
|
1932
|
+
end
|
1933
|
+
end
|
1934
|
+
|
1745
1935
|
describe '#each_element_with_events' do
|
1746
1936
|
before :each do
|
1747
1937
|
@browser.load url
|
@@ -1762,19 +1952,19 @@ describe Arachni::Browser do
|
|
1762
1952
|
tag_name: 'body',
|
1763
1953
|
attributes: { 'onmouseover' => 'makePOST();' }
|
1764
1954
|
),
|
1765
|
-
|
1955
|
+
{ onmouseover: ['makePOST();'] }
|
1766
1956
|
],
|
1767
1957
|
[
|
1768
1958
|
described_class::ElementLocator.new(
|
1769
1959
|
tag_name: 'div',
|
1770
1960
|
attributes: { 'id' => 'my-div', 'onclick' => 'addForm();' }
|
1771
1961
|
),
|
1772
|
-
|
1962
|
+
{ onclick: ['addForm();']}
|
1773
1963
|
]
|
1774
1964
|
])
|
1775
1965
|
end
|
1776
1966
|
|
1777
|
-
context :a do
|
1967
|
+
context ':a' do
|
1778
1968
|
context 'and the href is not empty' do
|
1779
1969
|
context 'and it starts with javascript:' do
|
1780
1970
|
let(:url) { @url + '/each_element_with_events/a/href/javascript' }
|
@@ -1786,7 +1976,7 @@ describe Arachni::Browser do
|
|
1786
1976
|
tag_name: 'a',
|
1787
1977
|
attributes: { 'href' => 'javascript:doStuff()' }
|
1788
1978
|
),
|
1789
|
-
|
1979
|
+
{click: [ 'javascript:doStuff()']}
|
1790
1980
|
]
|
1791
1981
|
])
|
1792
1982
|
end
|
@@ -1810,8 +2000,8 @@ describe Arachni::Browser do
|
|
1810
2000
|
end
|
1811
2001
|
end
|
1812
2002
|
|
1813
|
-
context :form do
|
1814
|
-
context :input do
|
2003
|
+
context ':form' do
|
2004
|
+
context ':input' do
|
1815
2005
|
context 'of type "image"' do
|
1816
2006
|
let(:url) { @url + '/each_element_with_events/form/input/image' }
|
1817
2007
|
|
@@ -1826,7 +2016,7 @@ describe Arachni::Browser do
|
|
1826
2016
|
'src' => '/__sinatra__/404.png'
|
1827
2017
|
}
|
1828
2018
|
),
|
1829
|
-
|
2019
|
+
{click: ['image']}
|
1830
2020
|
]
|
1831
2021
|
])
|
1832
2022
|
end
|
@@ -1846,7 +2036,7 @@ describe Arachni::Browser do
|
|
1846
2036
|
'action' => 'javascript:doStuff()'
|
1847
2037
|
}
|
1848
2038
|
),
|
1849
|
-
|
2039
|
+
{submit: ['javascript:doStuff()']}
|
1850
2040
|
]
|
1851
2041
|
])
|
1852
2042
|
end
|
@@ -1855,7 +2045,7 @@ describe Arachni::Browser do
|
|
1855
2045
|
context 'and it does not start with javascript:' do
|
1856
2046
|
let(:url) { @url + '/each_element_with_events/form/action/regular' }
|
1857
2047
|
|
1858
|
-
it 'is ignored'do
|
2048
|
+
it 'is ignored' do
|
1859
2049
|
expect(elements_with_events).to be_empty
|
1860
2050
|
end
|
1861
2051
|
end
|
@@ -1863,7 +2053,7 @@ describe Arachni::Browser do
|
|
1863
2053
|
context 'and is out of scope' do
|
1864
2054
|
let(:url) { @url + '/each_element_with_events/form/action/out-of-scope' }
|
1865
2055
|
|
1866
|
-
it 'is ignored'do
|
2056
|
+
it 'is ignored' do
|
1867
2057
|
expect(elements_with_events).to be_empty
|
1868
2058
|
end
|
1869
2059
|
end
|
@@ -1876,7 +2066,7 @@ describe Arachni::Browser do
|
|
1876
2066
|
@browser.load( @url + '/trigger_events' ).start_capture
|
1877
2067
|
|
1878
2068
|
locators = []
|
1879
|
-
@browser.
|
2069
|
+
@browser.selenium.find_elements(:css, '*').each do |element|
|
1880
2070
|
begin
|
1881
2071
|
locators << described_class::ElementLocator.from_html( element.opening_tag )
|
1882
2072
|
rescue
|
@@ -1899,6 +2089,10 @@ describe Arachni::Browser do
|
|
1899
2089
|
end
|
1900
2090
|
|
1901
2091
|
describe '#trigger_events' do
|
2092
|
+
it 'returns self' do
|
2093
|
+
expect(@browser.load( @url + '/explore' ).trigger_events).to eq(@browser)
|
2094
|
+
end
|
2095
|
+
|
1902
2096
|
it 'waits for AJAX requests to complete' do
|
1903
2097
|
@browser.load( @url + '/trigger_events-wait-for-ajax' ).start_capture.trigger_events
|
1904
2098
|
|
@@ -1916,6 +2110,7 @@ describe Arachni::Browser do
|
|
1916
2110
|
|
1917
2111
|
it 'assigns the proper page transitions' do
|
1918
2112
|
pages = @browser.load( @url + '/explore' ).trigger_events.page_snapshots
|
2113
|
+
|
1919
2114
|
expect(pages.map(&:dom).map(&:transitions)).to eq([
|
1920
2115
|
[
|
1921
2116
|
{ :page => :load },
|
@@ -1933,7 +2128,8 @@ describe Arachni::Browser do
|
|
1933
2128
|
}
|
1934
2129
|
} => :click
|
1935
2130
|
},
|
1936
|
-
{ "#{@url}get-ajax?ajax-token=my-token" => :request }
|
2131
|
+
{ "#{@url}get-ajax?ajax-token=my-token" => :request },
|
2132
|
+
{ "#{@url}post-ajax" => :request }
|
1937
2133
|
],
|
1938
2134
|
[
|
1939
2135
|
{ :page => :load },
|
@@ -1947,6 +2143,8 @@ describe Arachni::Browser do
|
|
1947
2143
|
} => :click
|
1948
2144
|
},
|
1949
2145
|
{ "#{@url}href-ajax" => :request },
|
2146
|
+
{ "#{@url}post-ajax" => :request },
|
2147
|
+
{ "#{@url}href-ajax" => :request }
|
1950
2148
|
]
|
1951
2149
|
].map { |transitions| transitions_from_array( transitions ) })
|
1952
2150
|
end
|
@@ -1975,10 +2173,6 @@ describe Arachni::Browser do
|
|
1975
2173
|
pages_should_have_form_with_input @browser.captured_pages, 'myImageButton.y'
|
1976
2174
|
end
|
1977
2175
|
end
|
1978
|
-
|
1979
|
-
it 'returns self' do
|
1980
|
-
expect(@browser.load( @url + '/explore' ).trigger_events).to eq(@browser)
|
1981
|
-
end
|
1982
2176
|
end
|
1983
2177
|
|
1984
2178
|
describe '#source' do
|
@@ -2190,7 +2384,7 @@ describe Arachni::Browser do
|
|
2190
2384
|
end
|
2191
2385
|
|
2192
2386
|
it "waits a maximum of #{Arachni::OptionGroups::BrowserCluster}#job_timeout" do
|
2193
|
-
Arachni::Options.browser_cluster.job_timeout =
|
2387
|
+
Arachni::Options.browser_cluster.job_timeout = 2
|
2194
2388
|
|
2195
2389
|
t = Time.now
|
2196
2390
|
@browser.goto( @url + '/wait_for_elements#stuff/here' )
|
@@ -2216,7 +2410,7 @@ describe Arachni::Browser do
|
|
2216
2410
|
end
|
2217
2411
|
|
2218
2412
|
context "#{Arachni::OptionGroups::BrowserCluster}#ignore_images" do
|
2219
|
-
context true do
|
2413
|
+
context 'true' do
|
2220
2414
|
it 'does not load images' do
|
2221
2415
|
Arachni::Options.browser_cluster.ignore_images = true
|
2222
2416
|
@browser.shutdown
|
@@ -2228,7 +2422,7 @@ describe Arachni::Browser do
|
|
2228
2422
|
end
|
2229
2423
|
end
|
2230
2424
|
|
2231
|
-
context false do
|
2425
|
+
context 'false' do
|
2232
2426
|
it 'loads images' do
|
2233
2427
|
Arachni::Options.browser_cluster.ignore_images = false
|
2234
2428
|
@browser.shutdown
|
@@ -2266,16 +2460,19 @@ describe Arachni::Browser do
|
|
2266
2460
|
context "with #{Arachni::OptionGroups::Scope}#auto_redundant_paths has bee configured" do
|
2267
2461
|
it 'respects scope restrictions' do
|
2268
2462
|
Arachni::Options.scope.auto_redundant_paths = 0
|
2269
|
-
expect(@browser.load( @url + '/explore?test=1&test2=2' ).response
|
2463
|
+
expect(@browser.load( @url + '/explore?test=1&test2=2' ).response).to be_nil
|
2270
2464
|
end
|
2271
2465
|
end
|
2272
2466
|
|
2273
|
-
describe :cookies do
|
2467
|
+
describe ':cookies' do
|
2274
2468
|
it 'loads the given cookies' do
|
2275
2469
|
cookie = { 'myname' => 'myvalue' }
|
2276
2470
|
@browser.goto @url, cookies: cookie
|
2277
2471
|
|
2278
|
-
|
2472
|
+
cookie_data = @browser.cookies.
|
2473
|
+
find { |c| c.name == cookie.keys.first }.inputs
|
2474
|
+
|
2475
|
+
expect(cookie_data).to eq(cookie)
|
2279
2476
|
end
|
2280
2477
|
|
2281
2478
|
it 'includes them in the transition' do
|
@@ -2284,23 +2481,10 @@ describe Arachni::Browser do
|
|
2284
2481
|
|
2285
2482
|
expect(transition.options[:cookies]).to eq(cookie)
|
2286
2483
|
end
|
2287
|
-
|
2288
|
-
context 'when auditing existing cookies' do
|
2289
|
-
it 'preserves the HttpOnly attribute' do
|
2290
|
-
@browser.goto( @url )
|
2291
|
-
expect(@browser.cookies.size).to eq(1)
|
2292
|
-
|
2293
|
-
cookies = { @browser.cookies.first.name => 'updated' }
|
2294
|
-
@browser.goto( @url, cookies: cookies )
|
2295
|
-
|
2296
|
-
@browser.cookies.first.value == 'updated'
|
2297
|
-
expect(@browser.cookies.first).to be_http_only
|
2298
|
-
end
|
2299
|
-
end
|
2300
2484
|
end
|
2301
2485
|
|
2302
|
-
describe :take_snapshot do
|
2303
|
-
describe true do
|
2486
|
+
describe ':take_snapshot' do
|
2487
|
+
describe 'true' do
|
2304
2488
|
it 'captures a snapshot of the loaded page' do
|
2305
2489
|
@browser.goto @url, take_snapshot: true
|
2306
2490
|
pages = @browser.page_snapshots
|
@@ -2313,7 +2497,7 @@ describe Arachni::Browser do
|
|
2313
2497
|
end
|
2314
2498
|
end
|
2315
2499
|
|
2316
|
-
describe false do
|
2500
|
+
describe 'false' do
|
2317
2501
|
it 'does not capture a snapshot of the loaded page' do
|
2318
2502
|
@browser.goto @url, take_snapshot: false
|
2319
2503
|
expect(@browser.page_snapshots).to be_empty
|
@@ -2334,15 +2518,15 @@ describe Arachni::Browser do
|
|
2334
2518
|
end
|
2335
2519
|
end
|
2336
2520
|
|
2337
|
-
describe :update_transitions do
|
2338
|
-
describe true do
|
2521
|
+
describe ':update_transitions' do
|
2522
|
+
describe 'true' do
|
2339
2523
|
it 'pushes the page load to the transitions' do
|
2340
2524
|
t = @browser.goto( @url, update_transitions: true )
|
2341
2525
|
expect(@browser.to_page.dom.transitions).to include t
|
2342
2526
|
end
|
2343
2527
|
end
|
2344
2528
|
|
2345
|
-
describe false do
|
2529
|
+
describe 'false' do
|
2346
2530
|
it 'does not push the page load to the transitions' do
|
2347
2531
|
t = @browser.goto( @url, update_transitions: false )
|
2348
2532
|
expect(@browser.to_page.dom.transitions).to be_empty
|
@@ -2363,7 +2547,16 @@ describe Arachni::Browser do
|
|
2363
2547
|
expect(@browser.load( @url )).to eq(@browser)
|
2364
2548
|
end
|
2365
2549
|
|
2366
|
-
|
2550
|
+
it 'updates the global cookie-jar' do
|
2551
|
+
@browser.load @url
|
2552
|
+
|
2553
|
+
cookie = Arachni::HTTP::Client.cookies.find(&:http_only?)
|
2554
|
+
|
2555
|
+
expect(cookie.name).to eq('This name should be updated; and properly escaped')
|
2556
|
+
expect(cookie.value).to eq('This value should be updated; and properly escaped')
|
2557
|
+
end
|
2558
|
+
|
2559
|
+
describe ':cookies' do
|
2367
2560
|
it 'loads the given cookies' do
|
2368
2561
|
cookie = { 'myname' => 'myvalue' }
|
2369
2562
|
@browser.load @url, cookies: cookie
|
@@ -2372,8 +2565,8 @@ describe Arachni::Browser do
|
|
2372
2565
|
end
|
2373
2566
|
end
|
2374
2567
|
|
2375
|
-
describe :take_snapshot do
|
2376
|
-
describe true do
|
2568
|
+
describe ':take_snapshot' do
|
2569
|
+
describe 'true' do
|
2377
2570
|
it 'captures a snapshot of the loaded page' do
|
2378
2571
|
@browser.load @url, take_snapshot: true
|
2379
2572
|
pages = @browser.page_snapshots
|
@@ -2386,7 +2579,7 @@ describe Arachni::Browser do
|
|
2386
2579
|
end
|
2387
2580
|
end
|
2388
2581
|
|
2389
|
-
describe false do
|
2582
|
+
describe 'false' do
|
2390
2583
|
it 'does not capture a snapshot of the loaded page' do
|
2391
2584
|
@browser.load @url, take_snapshot: false
|
2392
2585
|
expect(@browser.page_snapshots).to be_empty
|
@@ -2408,7 +2601,7 @@ describe Arachni::Browser do
|
|
2408
2601
|
end
|
2409
2602
|
|
2410
2603
|
context 'when given a' do
|
2411
|
-
describe String do
|
2604
|
+
describe 'String' do
|
2412
2605
|
it 'treats it as a URL' do
|
2413
2606
|
expect(hit_count).to eq(0)
|
2414
2607
|
|
@@ -2420,7 +2613,7 @@ describe Arachni::Browser do
|
|
2420
2613
|
end
|
2421
2614
|
end
|
2422
2615
|
|
2423
|
-
describe Arachni::HTTP::Response do
|
2616
|
+
describe 'Arachni::HTTP::Response' do
|
2424
2617
|
it 'loads it' do
|
2425
2618
|
expect(hit_count).to eq(0)
|
2426
2619
|
|
@@ -2432,34 +2625,89 @@ describe Arachni::Browser do
|
|
2432
2625
|
end
|
2433
2626
|
end
|
2434
2627
|
|
2435
|
-
describe Arachni::Page do
|
2628
|
+
describe 'Arachni::Page::DOM' do
|
2436
2629
|
it 'loads it' do
|
2437
2630
|
expect(hit_count).to eq(0)
|
2438
2631
|
|
2439
|
-
|
2632
|
+
page = Arachni::HTTP::Client.get( @url, mode: :sync ).to_page
|
2633
|
+
|
2634
|
+
expect(hit_count).to eq(1)
|
2635
|
+
|
2636
|
+
@browser.load page.dom
|
2637
|
+
|
2440
2638
|
expect(@browser.source).to include( ua )
|
2441
2639
|
expect(@browser.preloads).not_to include( @url )
|
2442
2640
|
|
2641
|
+
expect(hit_count).to eq(2)
|
2642
|
+
end
|
2643
|
+
|
2644
|
+
it 'replays its #transitions' do
|
2645
|
+
@browser.load "#{@url}play-transitions"
|
2646
|
+
page = @browser.explore_and_flush.last
|
2647
|
+
expect(page.body).to include ua
|
2648
|
+
|
2649
|
+
@browser.load page.dom
|
2650
|
+
expect(@browser.source).to include ua
|
2651
|
+
|
2652
|
+
page.dom.transitions.clear
|
2653
|
+
@browser.load page.dom
|
2654
|
+
expect(@browser.source).not_to include ua
|
2655
|
+
end
|
2656
|
+
|
2657
|
+
it 'loads its #skip_states' do
|
2658
|
+
@browser.load( @url )
|
2659
|
+
pages = @browser.load( @url + '/explore' ).trigger_events.
|
2660
|
+
page_snapshots
|
2661
|
+
|
2662
|
+
page = pages.last
|
2663
|
+
expect(page.dom.skip_states).to be_subset @browser.skip_states
|
2664
|
+
|
2665
|
+
token = @browser.generate_token
|
2666
|
+
|
2667
|
+
dpage = page.dup
|
2668
|
+
dpage.dom.skip_states << token
|
2669
|
+
|
2670
|
+
@browser.load dpage.dom
|
2671
|
+
expect(@browser.skip_states).to include token
|
2672
|
+
end
|
2673
|
+
end
|
2674
|
+
|
2675
|
+
describe 'Arachni::Page' do
|
2676
|
+
it 'loads it' do
|
2677
|
+
expect(hit_count).to eq(0)
|
2678
|
+
|
2679
|
+
page = Arachni::HTTP::Client.get( @url, mode: :sync ).to_page
|
2680
|
+
|
2443
2681
|
expect(hit_count).to eq(1)
|
2682
|
+
|
2683
|
+
@browser.load page
|
2684
|
+
|
2685
|
+
expect(@browser.source).to include( ua )
|
2686
|
+
expect(@browser.preloads).not_to include( @url )
|
2687
|
+
|
2688
|
+
expect(hit_count).to eq(2)
|
2444
2689
|
end
|
2445
2690
|
|
2446
2691
|
it 'uses its #cookie_jar' do
|
2447
2692
|
expect(@browser.cookies).to be_empty
|
2448
2693
|
|
2694
|
+
cookie = Arachni::Cookie.new(
|
2695
|
+
url: @url,
|
2696
|
+
inputs: {
|
2697
|
+
'my-name' => 'my-value'
|
2698
|
+
}
|
2699
|
+
)
|
2700
|
+
|
2449
2701
|
page = Arachni::Page.from_data(
|
2450
2702
|
url: @url,
|
2451
|
-
cookie_jar: [
|
2452
|
-
Arachni::Cookie.new(
|
2453
|
-
url: @url,
|
2454
|
-
inputs: {
|
2455
|
-
'my-name' => 'my-value'
|
2456
|
-
}
|
2457
|
-
)
|
2458
|
-
]
|
2703
|
+
cookie_jar: [ cookie ]
|
2459
2704
|
)
|
2460
2705
|
|
2706
|
+
expect(@browser.cookies).to_not include cookie
|
2707
|
+
|
2461
2708
|
@browser.load( page )
|
2462
|
-
|
2709
|
+
|
2710
|
+
expect(@browser.cookies).to include cookie
|
2463
2711
|
end
|
2464
2712
|
|
2465
2713
|
it 'replays its DOM#transitions' do
|
@@ -2491,7 +2739,6 @@ describe Arachni::Browser do
|
|
2491
2739
|
@browser.load dpage
|
2492
2740
|
expect(@browser.skip_states).to include token
|
2493
2741
|
end
|
2494
|
-
|
2495
2742
|
end
|
2496
2743
|
|
2497
2744
|
describe 'other' do
|
@@ -2534,7 +2781,7 @@ describe Arachni::Browser do
|
|
2534
2781
|
end
|
2535
2782
|
|
2536
2783
|
context 'when given a' do
|
2537
|
-
describe Arachni::HTTP::Response do
|
2784
|
+
describe 'Arachni::HTTP::Response' do
|
2538
2785
|
it 'preloads it' do
|
2539
2786
|
@browser.preload Arachni::HTTP::Client.get( @url, mode: :sync )
|
2540
2787
|
clear_hit_count
|
@@ -2549,7 +2796,7 @@ describe Arachni::Browser do
|
|
2549
2796
|
end
|
2550
2797
|
end
|
2551
2798
|
|
2552
|
-
describe Arachni::Page do
|
2799
|
+
describe 'Arachni::Page' do
|
2553
2800
|
it 'preloads it' do
|
2554
2801
|
@browser.preload Arachni::Page.from_url( @url )
|
2555
2802
|
clear_hit_count
|
@@ -2605,7 +2852,7 @@ describe Arachni::Browser do
|
|
2605
2852
|
end
|
2606
2853
|
|
2607
2854
|
context 'when given a' do
|
2608
|
-
describe Arachni::HTTP::Response do
|
2855
|
+
describe 'Arachni::HTTP::Response' do
|
2609
2856
|
it 'caches it' do
|
2610
2857
|
@browser.cache Arachni::HTTP::Client.get( @url, mode: :sync )
|
2611
2858
|
clear_hit_count
|
@@ -2620,7 +2867,7 @@ describe Arachni::Browser do
|
|
2620
2867
|
end
|
2621
2868
|
end
|
2622
2869
|
|
2623
|
-
describe Arachni::Page do
|
2870
|
+
describe 'Arachni::Page' do
|
2624
2871
|
it 'caches it' do
|
2625
2872
|
@browser.cache Arachni::Page.from_url( @url )
|
2626
2873
|
clear_hit_count
|
@@ -2795,19 +3042,72 @@ describe Arachni::Browser do
|
|
2795
3042
|
end
|
2796
3043
|
|
2797
3044
|
describe '#cookies' do
|
2798
|
-
it 'returns
|
3045
|
+
it 'returns cookies visible via JavaScript' do
|
2799
3046
|
@browser.load @url
|
2800
|
-
|
3047
|
+
|
2801
3048
|
cookie = @browser.cookies.first
|
3049
|
+
expect(cookie.name).to eq 'cookie_name'
|
3050
|
+
expect(cookie.value).to eq 'cookie value'
|
3051
|
+
expect(cookie.raw_name).to eq 'cookie_name'
|
3052
|
+
expect(cookie.raw_value).to eq '"cookie value"'
|
3053
|
+
end
|
2802
3054
|
|
2803
|
-
|
2804
|
-
|
2805
|
-
|
3055
|
+
it 'preserves expiration value' do
|
3056
|
+
@browser.load "#{@url}/cookies/expires"
|
3057
|
+
|
3058
|
+
cookie = @browser.cookies.first
|
3059
|
+
expect(cookie.name).to eq 'without_expiration'
|
3060
|
+
expect(cookie.value).to eq 'stuff'
|
3061
|
+
expect(cookie.expires).to be_nil
|
3062
|
+
|
3063
|
+
cookie = @browser.cookies.last
|
3064
|
+
expect(cookie.name).to eq 'with_expiration'
|
3065
|
+
expect(cookie.value).to eq 'bar'
|
3066
|
+
expect(cookie.expires.to_s).to eq Time.parse( '2047-08-01 09:30:11 +0000' ).to_s
|
2806
3067
|
end
|
2807
3068
|
|
2808
|
-
it 'preserves the
|
2809
|
-
@browser.load @url
|
2810
|
-
|
3069
|
+
it 'preserves the domain' do
|
3070
|
+
@browser.load "#{@url}/cookies/domains"
|
3071
|
+
|
3072
|
+
cookies = @browser.cookies
|
3073
|
+
|
3074
|
+
cookie = cookies.find { |c| c.name == 'include_subdomains' }
|
3075
|
+
expect(cookie.name).to eq 'include_subdomains'
|
3076
|
+
expect(cookie.value).to eq 'bar1'
|
3077
|
+
expect(cookie.domain).to eq '.127.0.0.2'
|
3078
|
+
end
|
3079
|
+
|
3080
|
+
it 'ignores cookies for other domains' do
|
3081
|
+
@browser.load "#{@url}/cookies/domains"
|
3082
|
+
|
3083
|
+
cookies = @browser.cookies
|
3084
|
+
expect(cookies.find { |c| c.name == 'other_domain' }).to be_nil
|
3085
|
+
end
|
3086
|
+
|
3087
|
+
it 'preserves the path' do
|
3088
|
+
@browser.load "#{@url}/cookies/under/path"
|
3089
|
+
|
3090
|
+
cookie = @browser.cookies.first
|
3091
|
+
expect(cookie.name).to eq 'cookie_under_path'
|
3092
|
+
expect(cookie.value).to eq 'value'
|
3093
|
+
expect(cookie.path).to eq '/cookies/under/'
|
3094
|
+
end
|
3095
|
+
|
3096
|
+
it 'preserves httpOnly' do
|
3097
|
+
@browser.load "#{@url}/cookies/under/path"
|
3098
|
+
|
3099
|
+
cookie = @browser.cookies.first
|
3100
|
+
expect(cookie.name).to eq 'cookie_under_path'
|
3101
|
+
expect(cookie.value).to eq 'value'
|
3102
|
+
expect(cookie.path).to eq '/cookies/under/'
|
3103
|
+
expect(cookie).to_not be_http_only
|
3104
|
+
|
3105
|
+
@browser.load "#{@url}/cookies/httpOnly"
|
3106
|
+
|
3107
|
+
cookie = @browser.cookies.first
|
3108
|
+
expect(cookie.name).to eq 'http_only'
|
3109
|
+
expect(cookie.value).to eq 'stuff'
|
3110
|
+
expect(cookie).to be_http_only
|
2811
3111
|
end
|
2812
3112
|
|
2813
3113
|
context 'when parsing v1 cookies' do
|
@@ -2817,7 +3117,9 @@ describe Arachni::Browser do
|
|
2817
3117
|
@browser.load @url
|
2818
3118
|
@browser.javascript.run( "document.cookie = '#{cookie}';" )
|
2819
3119
|
|
2820
|
-
|
3120
|
+
cookie = @browser.cookies.find { |c| c.name == 'rsession' }
|
3121
|
+
expect(cookie.value).to eq('06142010_0:e275d357943e9a2de0')
|
3122
|
+
expect(cookie.raw_value).to eq('"06142010_0%3Ae275d357943e9a2de0"')
|
2821
3123
|
end
|
2822
3124
|
end
|
2823
3125
|
|
@@ -2829,14 +3131,20 @@ describe Arachni::Browser do
|
|
2829
3131
|
end
|
2830
3132
|
|
2831
3133
|
describe '#snapshot_id' do
|
2832
|
-
before(:each)
|
3134
|
+
before(:each) do
|
3135
|
+
Arachni::Options.url = @url
|
3136
|
+
|
3137
|
+
@empty_snapshot_id ||= @browser.load( empty_snapshot_id_url ).snapshot_id
|
3138
|
+
|
3139
|
+
@snapshot_id = @browser.load( url ).snapshot_id
|
3140
|
+
end
|
2833
3141
|
|
2834
3142
|
let(:empty_snapshot_id_url) { @url + '/snapshot_id/default' }
|
2835
3143
|
let(:empty_snapshot_id) do
|
2836
|
-
@
|
3144
|
+
@empty_snapshot_id
|
2837
3145
|
end
|
2838
3146
|
let(:snapshot_id) do
|
2839
|
-
@
|
3147
|
+
@snapshot_id
|
2840
3148
|
end
|
2841
3149
|
|
2842
3150
|
let(:url) { @url + '/trigger_events' }
|
@@ -2845,7 +3153,22 @@ describe Arachni::Browser do
|
|
2845
3153
|
expect(snapshot_id).to eq(@browser.load( url ).snapshot_id)
|
2846
3154
|
end
|
2847
3155
|
|
2848
|
-
context
|
3156
|
+
context 'when there are new cookies' do
|
3157
|
+
let(:url) { @url + '/each_element_with_events/set-cookie' }
|
3158
|
+
|
3159
|
+
it 'takes them into account' do
|
3160
|
+
@browser.fire_event described_class::ElementLocator.new(
|
3161
|
+
tag_name: :button,
|
3162
|
+
attributes: {
|
3163
|
+
onclick: 'setCookie()'
|
3164
|
+
}
|
3165
|
+
), :click
|
3166
|
+
|
3167
|
+
expect(@browser.snapshot_id).not_to eq(snapshot_id)
|
3168
|
+
end
|
3169
|
+
end
|
3170
|
+
|
3171
|
+
context ':a' do
|
2849
3172
|
context 'and the href is not empty' do
|
2850
3173
|
context 'and it starts with javascript:' do
|
2851
3174
|
let(:url) { @url + '/each_element_with_events/a/href/javascript' }
|
@@ -2881,10 +3204,10 @@ describe Arachni::Browser do
|
|
2881
3204
|
end
|
2882
3205
|
end
|
2883
3206
|
|
2884
|
-
context :form do
|
3207
|
+
context ':form' do
|
2885
3208
|
let(:empty_snapshot_id_url) { @url + '/snapshot_id/form/default' }
|
2886
3209
|
|
2887
|
-
context :input do
|
3210
|
+
context ':input' do
|
2888
3211
|
context 'of type "image"' do
|
2889
3212
|
let(:url) { @url + '/each_element_with_events/form/input/image' }
|
2890
3213
|
|