arachni 1.3.2 → 1.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|