arachni 1.3.2 → 1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +108 -0
- data/Gemfile +2 -6
- data/LICENSE.md +1 -1
- data/README.md +34 -16
- data/Rakefile +1 -1
- data/arachni.gemspec +28 -20
- data/bin/arachni +1 -1
- data/bin/arachni_console +1 -1
- data/bin/arachni_multi +1 -1
- data/bin/arachni_reporter +1 -1
- data/bin/arachni_rest_server +13 -0
- data/bin/arachni_restore +1 -1
- data/bin/arachni_rpc +1 -1
- data/bin/arachni_rpcd +1 -1
- data/bin/arachni_rpcd_monitor +1 -1
- data/bin/arachni_script +1 -1
- data/components/checks/active/code_injection.rb +8 -10
- data/components/checks/active/code_injection_php_input_wrapper.rb +5 -6
- data/components/checks/active/code_injection_timing.rb +1 -1
- data/components/checks/active/csrf.rb +1 -1
- data/components/checks/active/file_inclusion.rb +20 -26
- data/components/checks/active/ldap_injection.rb +4 -5
- data/components/checks/active/no_sql_injection.rb +11 -20
- data/components/checks/active/no_sql_injection/substrings/mongodb +1 -0
- data/components/checks/active/no_sql_injection_differential.rb +3 -4
- data/components/checks/active/os_cmd_injection.rb +5 -9
- data/components/checks/active/os_cmd_injection_timing.rb +1 -1
- data/components/checks/active/path_traversal.rb +4 -17
- data/components/checks/active/response_splitting.rb +8 -2
- data/components/checks/active/rfi.rb +4 -5
- data/components/checks/active/session_fixation.rb +9 -3
- data/components/checks/active/source_code_disclosure.rb +5 -20
- data/components/checks/active/sql_injection.rb +30 -18
- data/components/checks/active/sql_injection/{regexp_ignore.txt → ignore_substrings} +0 -0
- data/components/checks/active/sql_injection/regexps/db2.yaml +2 -0
- data/components/checks/active/sql_injection/regexps/frontbase.yaml +1 -0
- data/components/checks/active/sql_injection/regexps/informix.yaml +1 -0
- data/components/checks/active/sql_injection/regexps/ingres.yaml +2 -0
- data/components/checks/active/sql_injection/regexps/maxdb.yaml +2 -0
- data/components/checks/active/sql_injection/regexps/mssql.yaml +8 -0
- data/components/checks/active/sql_injection/regexps/mysql.yaml +4 -0
- data/components/checks/active/sql_injection/regexps/oracle.yaml +4 -0
- data/components/checks/active/sql_injection/regexps/pgsql.yaml +3 -0
- data/components/checks/active/sql_injection/regexps/sqlite.yaml +2 -0
- data/components/checks/active/sql_injection/regexps/sybase.yaml +2 -0
- data/components/checks/active/sql_injection/substrings/access +3 -0
- data/components/checks/active/sql_injection/substrings/db2 +2 -0
- data/components/checks/active/sql_injection/{patterns → substrings}/emc +1 -1
- data/components/checks/active/sql_injection/{patterns → substrings}/firebird +0 -1
- data/components/checks/active/sql_injection/substrings/hsqldb +1 -0
- data/components/checks/active/sql_injection/{patterns → substrings}/informix +1 -2
- data/components/checks/active/sql_injection/substrings/ingres +1 -0
- data/components/checks/active/sql_injection/{patterns → substrings}/interbase +0 -0
- data/components/checks/active/sql_injection/substrings/mssql +17 -0
- data/components/checks/active/sql_injection/{patterns → substrings}/mysql +3 -6
- data/components/checks/active/sql_injection/substrings/oracle +2 -0
- data/components/checks/active/sql_injection/{patterns → substrings}/pgsql +3 -6
- data/components/checks/active/sql_injection/substrings/sqlite +3 -0
- data/components/checks/active/sql_injection/substrings/sybase +1 -0
- data/components/checks/active/sql_injection_differential.rb +5 -7
- data/components/checks/active/sql_injection_differential/payloads.txt +1 -1
- data/components/checks/active/sql_injection_timing.rb +1 -1
- data/components/checks/active/trainer.rb +5 -4
- data/components/checks/active/unvalidated_redirect.rb +1 -1
- data/components/checks/active/unvalidated_redirect_dom.rb +1 -1
- data/components/checks/active/xpath_injection.rb +3 -4
- data/components/checks/active/xss.rb +33 -12
- data/components/checks/active/xss_dom.rb +7 -4
- data/components/checks/active/xss_dom_script_context.rb +1 -1
- data/components/checks/active/xss_event.rb +43 -20
- data/components/checks/active/xss_path.rb +5 -4
- data/components/checks/active/xss_script_context.rb +41 -11
- data/components/checks/active/xss_tag.rb +14 -15
- data/components/checks/active/xxe.rb +5 -16
- data/components/checks/passive/allowed_methods.rb +1 -1
- data/components/checks/passive/backdoors.rb +4 -2
- data/components/checks/passive/backup_directories.rb +4 -2
- data/components/checks/passive/backup_files.rb +4 -2
- data/components/checks/passive/common_admin_interfaces.rb +4 -3
- data/components/checks/passive/common_directories.rb +3 -1
- data/components/checks/passive/common_files.rb +3 -1
- data/components/checks/passive/directory_listing.rb +4 -4
- data/components/checks/passive/grep/captcha.rb +1 -1
- data/components/checks/passive/grep/cookie_set_for_parent_domain.rb +1 -1
- data/components/checks/passive/grep/credit_card.rb +5 -7
- data/components/checks/passive/grep/cvs_svn_users.rb +1 -1
- data/components/checks/passive/grep/emails.rb +135 -8
- data/components/checks/passive/grep/form_upload.rb +1 -1
- data/components/checks/passive/grep/hsts.rb +4 -3
- data/components/checks/passive/grep/html_objects.rb +1 -1
- data/components/checks/passive/grep/http_only_cookies.rb +5 -3
- data/components/checks/passive/grep/insecure_cookies.rb +5 -3
- data/components/checks/passive/grep/insecure_cors_policy.rb +1 -1
- data/components/checks/passive/grep/mixed_resource.rb +1 -1
- data/components/checks/passive/grep/password_autocomplete.rb +1 -1
- data/components/checks/passive/grep/private_ip.rb +1 -1
- data/components/checks/passive/grep/ssn.rb +6 -3
- data/components/checks/passive/grep/unencrypted_password_forms.rb +1 -1
- data/components/checks/passive/grep/x_frame_options.rb +4 -3
- data/components/checks/passive/htaccess_limit.rb +1 -1
- data/components/checks/passive/http_put.rb +1 -1
- data/components/checks/passive/insecure_client_access_policy.rb +2 -2
- data/components/checks/passive/insecure_cross_domain_policy_access.rb +2 -2
- data/components/checks/passive/insecure_cross_domain_policy_headers.rb +2 -2
- data/components/checks/passive/interesting_responses.rb +1 -1
- data/components/checks/passive/localstart_asp.rb +1 -1
- data/components/checks/passive/origin_spoof_access_restriction_bypass.rb +1 -1
- data/components/checks/passive/webdav.rb +1 -1
- data/components/checks/passive/xst.rb +1 -1
- data/components/fingerprinters/frameworks/aspx_mvc.rb +1 -1
- data/components/fingerprinters/frameworks/cakephp.rb +1 -1
- data/components/fingerprinters/frameworks/cherrypy.rb +1 -1
- data/components/fingerprinters/frameworks/django.rb +1 -1
- data/components/fingerprinters/frameworks/jsf.rb +1 -1
- data/components/fingerprinters/frameworks/nette.rb +1 -1
- data/components/fingerprinters/frameworks/rack.rb +1 -1
- data/components/fingerprinters/frameworks/rails.rb +1 -1
- data/components/fingerprinters/frameworks/symfony.rb +1 -1
- data/components/fingerprinters/languages/asp.rb +1 -1
- data/components/fingerprinters/languages/aspx.rb +1 -1
- data/components/fingerprinters/languages/java.rb +1 -1
- data/components/fingerprinters/languages/php.rb +1 -1
- data/components/fingerprinters/languages/python.rb +1 -1
- data/components/fingerprinters/languages/ruby.rb +1 -1
- data/components/fingerprinters/os/bsd.rb +1 -1
- data/components/fingerprinters/os/linux.rb +1 -1
- data/components/fingerprinters/os/solaris.rb +1 -1
- data/components/fingerprinters/os/unix.rb +1 -1
- data/components/fingerprinters/os/windows.rb +1 -1
- data/components/fingerprinters/servers/apache.rb +1 -1
- data/components/fingerprinters/servers/gunicorn.rb +1 -1
- data/components/fingerprinters/servers/iis.rb +1 -1
- data/components/fingerprinters/servers/jetty.rb +1 -1
- data/components/fingerprinters/servers/nginx.rb +1 -1
- data/components/fingerprinters/servers/tomcat.rb +1 -1
- data/components/path_extractors/anchors.rb +1 -1
- data/components/path_extractors/areas.rb +1 -1
- data/components/path_extractors/comments.rb +1 -1
- data/components/path_extractors/data_url.rb +1 -1
- data/components/path_extractors/forms.rb +1 -1
- data/components/path_extractors/frames.rb +1 -1
- data/components/path_extractors/generic.rb +1 -1
- data/components/path_extractors/links.rb +1 -1
- data/components/path_extractors/meta_refresh.rb +3 -3
- data/components/path_extractors/scripts.rb +1 -1
- data/components/plugins/autologin.rb +16 -24
- data/components/plugins/beep_notify.rb +1 -1
- data/components/plugins/content_types.rb +1 -1
- data/components/plugins/cookie_collector.rb +1 -1
- data/components/plugins/defaults/autothrottle.rb +1 -1
- data/components/plugins/defaults/healthmap.rb +1 -1
- data/components/plugins/defaults/meta/remedies/discovery.rb +10 -9
- data/components/plugins/defaults/meta/remedies/timing_attacks.rb +1 -1
- data/components/plugins/defaults/meta/uniformity.rb +1 -1
- data/components/plugins/email_notify.rb +3 -5
- data/components/plugins/exec.rb +1 -1
- data/components/plugins/form_dicattack.rb +1 -1
- data/components/plugins/headers_collector.rb +1 -1
- data/components/plugins/http_dicattack.rb +1 -1
- data/components/plugins/login_script.rb +47 -22
- data/components/plugins/metrics.rb +1 -1
- data/components/plugins/proxy.rb +69 -44
- data/components/plugins/proxy/panel/help.html.erb +1 -18
- data/components/plugins/proxy/panel/inspect.html.erb +4 -3
- data/components/plugins/proxy/panel/page_accordion.html.erb +78 -43
- data/components/plugins/proxy/panel/panel.html.erb +2 -7
- data/components/plugins/proxy/template_scope.rb +1 -1
- data/components/plugins/restrict_to_dom_state.rb +3 -15
- data/components/plugins/script.rb +1 -1
- data/components/plugins/uncommon_headers.rb +1 -1
- data/components/plugins/vector_collector.rb +1 -1
- data/components/plugins/vector_feed.rb +3 -11
- data/components/plugins/waf_detector.rb +1 -1
- data/components/reporters/ap.rb +1 -1
- data/components/reporters/html.rb +2 -2
- data/components/reporters/json.rb +1 -1
- data/components/reporters/marshal.rb +1 -1
- data/components/reporters/plugin_formatters/html/autologin.rb +1 -1
- data/components/reporters/plugin_formatters/html/content_types.rb +1 -1
- data/components/reporters/plugin_formatters/html/cookie_collector.rb +1 -1
- data/components/reporters/plugin_formatters/html/exec.rb +1 -1
- data/components/reporters/plugin_formatters/html/form_dicattack.rb +1 -1
- data/components/reporters/plugin_formatters/html/healthmap.rb +1 -1
- data/components/reporters/plugin_formatters/html/http_dicattack.rb +1 -1
- data/components/reporters/plugin_formatters/html/login_script.rb +1 -1
- data/components/reporters/plugin_formatters/html/metrics.rb +1 -1
- data/components/reporters/plugin_formatters/html/uncommon_headers.rb +1 -1
- data/components/reporters/plugin_formatters/html/uniformity.rb +1 -1
- data/components/reporters/plugin_formatters/html/vector_collector.rb +1 -1
- data/components/reporters/plugin_formatters/html/waf_detector.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/autologin.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/content_types.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/cookie_collector.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/exec.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/form_dicattack.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/healthmap.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/http_dicattack.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/login_script.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/metrics.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/uncommon_headers.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/uniformity.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/vector_collector.rb +1 -1
- data/components/reporters/plugin_formatters/stdout/waf_detector.rb +1 -1
- data/components/reporters/plugin_formatters/xml/autologin.rb +1 -1
- data/components/reporters/plugin_formatters/xml/content_types.rb +1 -1
- data/components/reporters/plugin_formatters/xml/cookie_collector.rb +1 -1
- data/components/reporters/plugin_formatters/xml/exec.rb +1 -1
- data/components/reporters/plugin_formatters/xml/form_dicattack.rb +1 -1
- data/components/reporters/plugin_formatters/xml/healthmap.rb +1 -1
- data/components/reporters/plugin_formatters/xml/http_dicattack.rb +1 -1
- data/components/reporters/plugin_formatters/xml/login_script.rb +1 -1
- data/components/reporters/plugin_formatters/xml/metrics.rb +1 -1
- data/components/reporters/plugin_formatters/xml/uncommon_headers.rb +1 -1
- data/components/reporters/plugin_formatters/xml/uniformity.rb +1 -1
- data/components/reporters/plugin_formatters/xml/vector_collector.rb +1 -1
- data/components/reporters/plugin_formatters/xml/waf_detector.rb +1 -1
- data/components/reporters/stdout.rb +1 -1
- data/components/reporters/txt.rb +1 -1
- data/components/reporters/xml.rb +29 -4
- data/components/reporters/yaml.rb +1 -1
- data/lib/arachni.rb +48 -3
- data/lib/arachni/banner.rb +1 -1
- data/lib/arachni/browser.rb +601 -358
- data/lib/arachni/browser/element_locator.rb +25 -6
- data/lib/arachni/browser/javascript.rb +103 -35
- data/lib/arachni/browser/javascript/dom_monitor.rb +1 -1
- data/lib/arachni/browser/javascript/proxy.rb +28 -16
- data/lib/arachni/browser/javascript/proxy/stub.rb +1 -1
- data/lib/arachni/browser/javascript/scripts/dom_monitor.js +138 -67
- data/lib/arachni/browser/javascript/scripts/polyfills.js +28 -0
- data/lib/arachni/browser/javascript/scripts/taint_tracer.js +27 -6
- data/lib/arachni/browser/javascript/taint_tracer.rb +1 -1
- data/lib/arachni/browser/javascript/taint_tracer/frame.rb +1 -1
- data/lib/arachni/browser/javascript/taint_tracer/frame/called_function.rb +1 -1
- data/lib/arachni/browser/javascript/taint_tracer/sink/base.rb +1 -1
- data/lib/arachni/browser/javascript/taint_tracer/sink/data_flow.rb +1 -1
- data/lib/arachni/browser/javascript/taint_tracer/sink/execution_flow.rb +1 -1
- data/lib/arachni/browser_cluster.rb +10 -14
- data/lib/arachni/browser_cluster/job.rb +1 -1
- data/lib/arachni/browser_cluster/job/result.rb +1 -1
- data/lib/arachni/browser_cluster/jobs/browser_provider.rb +1 -1
- data/lib/arachni/browser_cluster/jobs/{resource_exploration.rb → dom_exploration.rb} +5 -5
- data/lib/arachni/browser_cluster/jobs/{resource_exploration → dom_exploration}/event_trigger.rb +7 -4
- data/lib/arachni/browser_cluster/jobs/{resource_exploration → dom_exploration}/event_trigger/result.rb +3 -3
- data/lib/arachni/browser_cluster/jobs/{resource_exploration → dom_exploration}/result.rb +2 -2
- data/lib/arachni/browser_cluster/jobs/taint_trace.rb +3 -3
- data/lib/arachni/browser_cluster/jobs/taint_trace/event_trigger.rb +2 -2
- data/lib/arachni/browser_cluster/jobs/taint_trace/event_trigger/result.rb +2 -2
- data/lib/arachni/browser_cluster/jobs/taint_trace/result.rb +1 -1
- data/lib/arachni/browser_cluster/worker.rb +12 -40
- data/lib/arachni/check.rb +1 -1
- data/lib/arachni/check/auditor.rb +15 -1
- data/lib/arachni/check/base.rb +1 -1
- data/lib/arachni/check/manager.rb +1 -1
- data/lib/arachni/component.rb +1 -1
- data/lib/arachni/component/base.rb +5 -5
- data/lib/arachni/component/manager.rb +39 -13
- data/lib/arachni/component/options.rb +1 -1
- data/lib/arachni/component/options/address.rb +1 -1
- data/lib/arachni/component/options/base.rb +1 -1
- data/lib/arachni/component/options/bool.rb +1 -1
- data/lib/arachni/component/options/float.rb +1 -1
- data/lib/arachni/component/options/int.rb +1 -1
- data/lib/arachni/component/options/multiple_choice.rb +1 -1
- data/lib/arachni/component/options/object.rb +1 -1
- data/lib/arachni/component/options/path.rb +1 -1
- data/lib/arachni/component/options/port.rb +1 -1
- data/lib/arachni/component/options/string.rb +1 -1
- data/lib/arachni/component/options/url.rb +1 -1
- data/lib/arachni/component/output.rb +1 -1
- data/lib/arachni/component/utilities.rb +1 -1
- data/lib/arachni/data.rb +1 -1
- data/lib/arachni/data/framework.rb +1 -1
- data/lib/arachni/data/framework/rpc.rb +1 -1
- data/lib/arachni/data/issues.rb +1 -1
- data/lib/arachni/data/plugins.rb +1 -1
- data/lib/arachni/data/session.rb +1 -1
- data/lib/arachni/element/base.rb +19 -5
- data/lib/arachni/element/body.rb +1 -1
- data/lib/arachni/element/capabilities/analyzable.rb +1 -1
- data/lib/arachni/element/capabilities/analyzable/differential.rb +15 -5
- data/lib/arachni/element/capabilities/analyzable/signature.rb +147 -89
- data/lib/arachni/element/capabilities/analyzable/timeout.rb +43 -16
- data/lib/arachni/element/capabilities/auditable.rb +20 -15
- data/lib/arachni/element/capabilities/dom_only.rb +5 -4
- data/lib/arachni/element/capabilities/inputtable.rb +62 -12
- data/lib/arachni/element/capabilities/mutable.rb +74 -13
- data/lib/arachni/element/capabilities/refreshable.rb +1 -1
- data/lib/arachni/element/capabilities/submittable.rb +5 -2
- data/lib/arachni/element/capabilities/with_auditor.rb +1 -1
- data/lib/arachni/element/capabilities/with_auditor/output.rb +5 -5
- data/lib/arachni/element/capabilities/with_dom.rb +1 -1
- data/lib/arachni/element/capabilities/with_node.rb +2 -2
- data/lib/arachni/element/capabilities/with_scope.rb +1 -1
- data/lib/arachni/element/capabilities/with_scope/scope.rb +1 -1
- data/lib/arachni/element/capabilities/with_source.rb +4 -4
- data/lib/arachni/element/cookie.rb +57 -34
- data/lib/arachni/element/cookie/capabilities/inputtable.rb +1 -1
- data/lib/arachni/element/cookie/capabilities/mutable.rb +10 -1
- data/lib/arachni/element/cookie/capabilities/with_dom.rb +1 -1
- data/lib/arachni/element/cookie/dom.rb +1 -1
- data/lib/arachni/element/dom.rb +1 -15
- data/lib/arachni/element/dom/capabilities/auditable.rb +1 -1
- data/lib/arachni/element/dom/capabilities/inputtable.rb +1 -1
- data/lib/arachni/element/dom/capabilities/locatable.rb +29 -0
- data/lib/arachni/element/dom/capabilities/mutable.rb +11 -1
- data/lib/arachni/element/dom/capabilities/submittable.rb +2 -2
- data/lib/arachni/element/form.rb +33 -14
- data/lib/arachni/element/form/capabilities/auditable.rb +1 -1
- data/lib/arachni/element/form/capabilities/mutable.rb +18 -17
- data/lib/arachni/element/form/capabilities/submittable.rb +1 -1
- data/lib/arachni/element/form/capabilities/with_dom.rb +2 -1
- data/lib/arachni/element/form/dom.rb +3 -2
- data/lib/arachni/element/generic_dom.rb +1 -1
- data/lib/arachni/element/header.rb +16 -4
- data/lib/arachni/element/header/capabilities/inputtable.rb +1 -1
- data/lib/arachni/element/header/capabilities/mutable.rb +11 -1
- data/lib/arachni/element/json.rb +2 -2
- data/lib/arachni/element/json/capabilities/inputtable.rb +1 -1
- data/lib/arachni/element/json/capabilities/mutable.rb +8 -2
- data/lib/arachni/element/link.rb +14 -7
- data/lib/arachni/element/link/capabilities/auditable.rb +1 -1
- data/lib/arachni/element/link/capabilities/submittable.rb +1 -1
- data/lib/arachni/element/link/capabilities/with_dom.rb +8 -1
- data/lib/arachni/element/link/dom.rb +2 -1
- data/lib/arachni/element/link/dom/capabilities/submittable.rb +1 -1
- data/lib/arachni/element/link_template.rb +8 -3
- data/lib/arachni/element/link_template/capabilities/auditable.rb +1 -1
- data/lib/arachni/element/link_template/capabilities/inputtable.rb +1 -1
- data/lib/arachni/element/link_template/capabilities/with_dom.rb +1 -1
- data/lib/arachni/element/link_template/dom.rb +2 -1
- data/lib/arachni/element/link_template/dom/capabilities/submittable.rb +1 -1
- data/lib/arachni/element/path.rb +1 -1
- data/lib/arachni/element/server.rb +3 -3
- data/lib/arachni/element/ui_form.rb +24 -21
- data/lib/arachni/element/ui_form/dom.rb +12 -3
- data/lib/arachni/element/ui_input.rb +17 -11
- data/lib/arachni/element/{input → ui_input}/dom.rb +11 -2
- data/lib/arachni/element/xml.rb +3 -3
- data/lib/arachni/element/xml/capabilities/inputtable.rb +7 -1
- data/lib/arachni/element/xml/capabilities/mutable.rb +7 -13
- data/lib/arachni/element_filter.rb +1 -1
- data/lib/arachni/error.rb +1 -1
- data/lib/arachni/ethon/easy.rb +1 -1
- data/lib/arachni/framework.rb +2 -5
- data/lib/arachni/framework/parts/audit.rb +8 -2
- data/lib/arachni/framework/parts/browser.rb +8 -9
- data/lib/arachni/framework/parts/check.rb +2 -6
- data/lib/arachni/framework/parts/data.rb +23 -8
- data/lib/arachni/framework/parts/platform.rb +1 -1
- data/lib/arachni/framework/parts/plugin.rb +2 -8
- data/lib/arachni/framework/parts/report.rb +3 -9
- data/lib/arachni/framework/parts/scope.rb +1 -1
- data/lib/arachni/framework/parts/state.rb +8 -8
- data/lib/arachni/http.rb +1 -1
- data/lib/arachni/http/client.rb +72 -68
- data/lib/arachni/http/client/dynamic_404_handler.rb +85 -60
- data/lib/arachni/http/cookie_jar.rb +48 -27
- data/lib/arachni/http/headers.rb +4 -3
- data/lib/arachni/http/message.rb +17 -3
- data/lib/arachni/http/message/scope.rb +1 -1
- data/lib/arachni/http/proxy_server.rb +46 -344
- data/lib/arachni/http/proxy_server/connection.rb +316 -0
- data/lib/arachni/http/proxy_server/ssl_interceptor.rb +102 -0
- data/lib/arachni/http/proxy_server/tunnel.rb +54 -0
- data/lib/arachni/http/request.rb +126 -29
- data/lib/arachni/http/request/scope.rb +1 -1
- data/lib/arachni/http/response.rb +42 -12
- data/lib/arachni/http/response/scope.rb +1 -1
- data/lib/arachni/issue.rb +2 -2
- data/lib/arachni/issue/severity.rb +1 -1
- data/lib/arachni/issue/severity/base.rb +1 -1
- data/lib/arachni/option_group.rb +1 -1
- data/lib/arachni/option_groups.rb +1 -1
- data/lib/arachni/option_groups/audit.rb +20 -4
- data/lib/arachni/option_groups/browser_cluster.rb +8 -4
- data/lib/arachni/option_groups/datastore.rb +1 -1
- data/lib/arachni/option_groups/dispatcher.rb +1 -1
- data/lib/arachni/option_groups/http.rb +2 -2
- data/lib/arachni/option_groups/input.rb +6 -3
- data/lib/arachni/option_groups/output.rb +1 -1
- data/lib/arachni/option_groups/paths.rb +10 -3
- data/lib/arachni/option_groups/rpc.rb +1 -1
- data/lib/arachni/option_groups/scope.rb +35 -6
- data/lib/arachni/option_groups/session.rb +1 -1
- data/lib/arachni/option_groups/snapshot.rb +1 -1
- data/lib/arachni/options.rb +1 -1
- data/lib/arachni/page.rb +26 -12
- data/lib/arachni/page/dom.rb +29 -22
- data/lib/arachni/page/dom/transition.rb +2 -2
- data/lib/arachni/page/scope.rb +1 -1
- data/lib/arachni/parser.rb +42 -5
- data/lib/arachni/platform.rb +1 -1
- data/lib/arachni/platform/fingerprinter.rb +1 -1
- data/lib/arachni/platform/list.rb +1 -1
- data/lib/arachni/platform/manager.rb +2 -2
- data/lib/arachni/plugin.rb +1 -1
- data/lib/arachni/plugin/base.rb +1 -1
- data/lib/arachni/plugin/formatter.rb +1 -1
- data/lib/arachni/plugin/manager.rb +7 -13
- data/lib/arachni/processes.rb +1 -1
- data/lib/arachni/processes/dispatchers.rb +2 -2
- data/lib/arachni/processes/executables/base.rb +45 -4
- data/lib/arachni/processes/executables/browser.rb +91 -0
- data/lib/arachni/processes/executables/rest_service.rb +14 -0
- data/lib/arachni/processes/helpers.rb +1 -1
- data/lib/arachni/processes/helpers/dispatchers.rb +1 -1
- data/lib/arachni/processes/helpers/instances.rb +1 -1
- data/lib/arachni/processes/helpers/processes.rb +1 -1
- data/lib/arachni/processes/instances.rb +5 -5
- data/lib/arachni/processes/manager.rb +68 -9
- data/lib/arachni/report.rb +1 -1
- data/lib/arachni/reporter.rb +1 -1
- data/lib/arachni/reporter/base.rb +1 -1
- data/lib/arachni/reporter/formatter_manager.rb +4 -2
- data/lib/arachni/reporter/manager.rb +3 -2
- data/lib/arachni/reporter/options.rb +1 -1
- data/lib/arachni/rest/server.rb +231 -0
- data/lib/arachni/rest/server/instance_helpers.rb +37 -0
- data/lib/arachni/rpc/client/base.rb +1 -1
- data/lib/arachni/rpc/client/dispatcher.rb +1 -1
- data/lib/arachni/rpc/client/instance.rb +1 -1
- data/lib/arachni/rpc/client/instance/framework.rb +1 -1
- data/lib/arachni/rpc/client/instance/service.rb +1 -1
- data/lib/arachni/rpc/serializer.rb +1 -1
- data/lib/arachni/rpc/server/active_options.rb +20 -3
- data/lib/arachni/rpc/server/base.rb +1 -1
- data/lib/arachni/rpc/server/check/manager.rb +1 -1
- data/lib/arachni/rpc/server/dispatcher.rb +4 -4
- data/lib/arachni/rpc/server/dispatcher/node.rb +1 -1
- data/lib/arachni/rpc/server/dispatcher/service.rb +1 -1
- data/lib/arachni/rpc/server/framework.rb +3 -1
- data/lib/arachni/rpc/server/framework/distributor.rb +1 -1
- data/lib/arachni/rpc/server/framework/master.rb +1 -1
- data/lib/arachni/rpc/server/framework/multi_instance.rb +1 -1
- data/lib/arachni/rpc/server/framework/slave.rb +1 -1
- data/lib/arachni/rpc/server/instance.rb +1 -3
- data/lib/arachni/rpc/server/output.rb +1 -1
- data/lib/arachni/rpc/server/plugin/manager.rb +1 -1
- data/lib/arachni/ruby.rb +1 -2
- data/lib/arachni/ruby/array.rb +1 -1
- data/lib/arachni/ruby/hash.rb +1 -1
- data/lib/arachni/ruby/object.rb +15 -1
- data/lib/arachni/ruby/set.rb +1 -1
- data/lib/arachni/ruby/string.rb +23 -4
- data/lib/arachni/ruby/webrick.rb +1 -1
- data/lib/arachni/ruby/webrick/cookie.rb +1 -1
- data/lib/arachni/ruby/webrick/httprequest.rb +1 -1
- data/lib/arachni/scope.rb +1 -1
- data/lib/arachni/{watir → selenium/webdriver}/element.rb +12 -13
- data/lib/arachni/session.rb +19 -4
- data/lib/arachni/snapshot.rb +9 -5
- data/lib/arachni/state.rb +1 -1
- data/lib/arachni/state/audit.rb +1 -1
- data/lib/arachni/state/element_filter.rb +1 -1
- data/lib/arachni/state/framework.rb +1 -1
- data/lib/arachni/state/framework/rpc.rb +1 -1
- data/lib/arachni/state/http.rb +1 -1
- data/lib/arachni/state/options.rb +1 -1
- data/lib/arachni/state/plugins.rb +1 -1
- data/lib/arachni/support.rb +2 -1
- data/lib/arachni/support/buffer.rb +1 -1
- data/lib/arachni/support/buffer/autoflush.rb +1 -1
- data/lib/arachni/support/buffer/base.rb +1 -1
- data/lib/arachni/support/cache.rb +1 -1
- data/lib/arachni/support/cache/base.rb +20 -8
- data/lib/arachni/support/cache/least_cost_replacement.rb +1 -1
- data/lib/arachni/support/cache/least_recently_pushed.rb +1 -1
- data/lib/arachni/support/cache/least_recently_used.rb +8 -9
- data/lib/arachni/support/cache/preference.rb +7 -20
- data/lib/arachni/support/cache/random_replacement.rb +1 -1
- data/lib/arachni/support/crypto.rb +1 -1
- data/lib/arachni/support/crypto/rsa_aes_cbc.rb +1 -1
- data/lib/arachni/support/database.rb +1 -1
- data/lib/arachni/support/database/base.rb +2 -2
- data/lib/arachni/support/database/hash.rb +1 -1
- data/lib/arachni/support/database/queue.rb +1 -1
- data/lib/arachni/support/glob.rb +35 -0
- data/lib/arachni/support/lookup.rb +1 -1
- data/lib/arachni/support/lookup/base.rb +1 -1
- data/lib/arachni/support/lookup/hash_set.rb +1 -1
- data/lib/arachni/support/lookup/moolb.rb +1 -1
- data/lib/arachni/support/mixins.rb +1 -1
- data/lib/arachni/support/mixins/observable.rb +1 -1
- data/lib/arachni/support/mixins/terminal.rb +1 -1
- data/lib/arachni/support/profiler.rb +12 -10
- data/lib/arachni/support/signature.rb +12 -5
- data/lib/arachni/trainer.rb +18 -4
- data/lib/arachni/ui/foo/output.rb +17 -1
- data/lib/arachni/uri.rb +285 -203
- data/lib/arachni/uri/scope.rb +13 -2
- data/lib/arachni/utilities.rb +22 -5
- data/lib/arachni/version.rb +1 -1
- data/lib/version +1 -1
- data/spec/arachni/browser/element_locator_spec.rb +42 -14
- data/spec/arachni/browser/javascript/dom_monitor_spec.rb +34 -304
- data/spec/arachni/browser/javascript/polyfills_spec.rb +35 -0
- data/spec/arachni/browser/javascript/taint_tracer_spec.rb +24 -4
- data/spec/arachni/browser/javascript_spec.rb +92 -65
- data/spec/arachni/browser_cluster/job_spec.rb +3 -3
- data/spec/arachni/browser_cluster/jobs/{resource_exploration → dom_exploration}/event_trigger/result_spec.rb +1 -1
- data/spec/arachni/browser_cluster/jobs/{resource_exploration → dom_exploration}/event_trigger_spec.rb +4 -4
- data/spec/arachni/browser_cluster/jobs/{resource_exploration → dom_exploration}/result_spec.rb +1 -1
- data/spec/arachni/browser_cluster/jobs/{resource_exploration_spec.rb → dom_exploration_spec.rb} +4 -4
- data/spec/arachni/browser_cluster/jobs/taint_tracer_spec.rb +9 -9
- data/spec/arachni/browser_cluster/worker_spec.rb +46 -67
- data/spec/arachni/browser_cluster_spec.rb +19 -17
- data/spec/arachni/browser_spec.rb +506 -183
- data/spec/arachni/check/auditor_spec.rb +70 -25
- data/spec/arachni/component/manager_spec.rb +19 -20
- data/spec/arachni/data/framework/rpc_spec.rb +1 -1
- data/spec/arachni/data/framework_spec.rb +1 -1
- data/spec/arachni/data/issues_spec.rb +3 -3
- data/spec/arachni/element/capabilities/analyzable/differential_spec.rb +44 -0
- data/spec/arachni/element/capabilities/analyzable/signature_spec.rb +33 -162
- data/spec/arachni/element/capabilities/analyzable/timeout_spec.rb +4 -4
- data/spec/arachni/element/cookie_spec.rb +98 -49
- data/spec/arachni/element/form/dom_spec.rb +1 -22
- data/spec/arachni/element/form_spec.rb +7 -7
- data/spec/arachni/element/header_spec.rb +2 -2
- data/spec/arachni/element/json_spec.rb +2 -2
- data/spec/arachni/element/link/dom_spec.rb +1 -22
- data/spec/arachni/element/link_spec.rb +17 -1
- data/spec/arachni/element/link_template/dom_spec.rb +1 -22
- data/spec/arachni/element/link_template_spec.rb +3 -3
- data/spec/arachni/element/ui_form/{ui_form_dom_spec.rb → dom_spec.rb} +72 -22
- data/spec/arachni/element/ui_form_spec.rb +1 -0
- data/spec/arachni/element/ui_input/dom_spec.rb +64 -22
- data/spec/arachni/element/ui_input_spec.rb +1 -0
- data/spec/arachni/element/xml_spec.rb +1 -0
- data/spec/arachni/framework/parts/audit_spec.rb +7 -5
- data/spec/arachni/framework/parts/browser_spec.rb +8 -8
- data/spec/arachni/framework/parts/check_spec.rb +1 -1
- data/spec/arachni/framework/parts/data_spec.rb +4 -4
- data/spec/arachni/framework/parts/scope_spec.rb +2 -2
- data/spec/arachni/framework_spec.rb +1 -1
- data/spec/arachni/http/client/dynamic_404_handlers_spec.rb +26 -13
- data/spec/arachni/http/client_spec.rb +80 -45
- data/spec/arachni/http/cookie_jar_spec.rb +6 -6
- data/spec/arachni/http/proxy_server_spec.rb +69 -66
- data/spec/arachni/http/request_spec.rb +147 -23
- data/spec/arachni/http/response/scope_spec.rb +12 -12
- data/spec/arachni/http/response_spec.rb +62 -4
- data/spec/arachni/issue_spec.rb +6 -6
- data/spec/arachni/option_groups/audit_spec.rb +25 -8
- data/spec/arachni/option_groups/browser_cluster_spec.rb +27 -1
- data/spec/arachni/option_groups/dispatcher_spec.rb +3 -3
- data/spec/arachni/option_groups/input_spec.rb +9 -9
- data/spec/arachni/option_groups/paths_spec.rb +2 -2
- data/spec/arachni/option_groups/scope_spec.rb +32 -16
- data/spec/arachni/options_spec.rb +4 -4
- data/spec/arachni/page/dom/transition_spec.rb +17 -10
- data/spec/arachni/page/dom_spec.rb +19 -0
- data/spec/arachni/page/scope_spec.rb +4 -4
- data/spec/arachni/page_spec.rb +15 -15
- data/spec/arachni/platform/manager_spec.rb +2 -2
- data/spec/arachni/plugin/base_spec.rb +1 -0
- data/spec/arachni/reporter/base_spec.rb +2 -2
- data/spec/arachni/reporter/manager_spec.rb +2 -2
- data/spec/arachni/rest/server_spec.rb +495 -0
- data/spec/arachni/rpc/server/active_options_spec.rb +63 -12
- data/spec/arachni/rpc/server/base_spec.rb +1 -1
- data/spec/arachni/rpc/server/framework/distributor_spec.rb +2 -2
- data/spec/arachni/rpc/server/framework_multi_spec.rb +6 -6
- data/spec/arachni/rpc/server/framework_spec.rb +4 -4
- data/spec/arachni/rpc/server/instance_spec.rb +24 -24
- data/spec/arachni/ruby/array_spec.rb +2 -2
- data/spec/arachni/ruby/string_spec.rb +52 -0
- data/spec/arachni/session_spec.rb +19 -2
- data/spec/arachni/snapshot_spec.rb +1 -1
- data/spec/arachni/state/audit_spec.rb +1 -1
- data/spec/arachni/state/framework_spec.rb +2 -2
- data/spec/arachni/support/cache/least_recently_used_spec.rb +0 -2
- data/spec/arachni/support/glob_spec.rb +75 -0
- data/spec/arachni/support/lookup/hash_set_spec.rb +1 -1
- data/spec/arachni/support/lookup/moolb_spec.rb +2 -2
- data/spec/arachni/support/signature_spec.rb +4 -4
- data/spec/arachni/trainer_spec.rb +48 -4
- data/spec/arachni/uri/scope_spec.rb +54 -10
- data/spec/arachni/uri_spec.rb +110 -89
- data/spec/arachni/utilities_spec.rb +8 -8
- data/spec/components/checks/active/code_injection_spec.rb +9 -9
- data/spec/components/checks/active/file_inclusion_spec.rb +20 -20
- data/spec/components/checks/active/ldap_injection_spec.rb +1 -1
- data/spec/components/checks/active/no_sql_injection_spec.rb +1 -1
- data/spec/components/checks/active/os_cmd_injection_spec.rb +3 -3
- data/spec/components/checks/active/path_traversal_spec.rb +11 -11
- data/spec/components/checks/active/response_splitting_spec.rb +2 -2
- data/spec/components/checks/active/rfi_spec.rb +3 -3
- data/spec/components/checks/active/session_fixation_spec.rb +1 -1
- data/spec/components/checks/active/source_code_disclosure_spec.rb +4 -4
- data/spec/components/checks/active/sql_injection_spec.rb +58 -59
- data/spec/components/checks/active/unvalidated_redirect_spec.rb +2 -2
- data/spec/components/checks/active/xpath_injection_spec.rb +3 -3
- data/spec/components/checks/active/xss_dom_script_context_spec.rb +1 -1
- data/spec/components/checks/active/xss_dom_spec.rb +1 -1
- data/spec/components/checks/active/xss_script_context_spec.rb +5 -5
- data/spec/components/checks/active/xss_spec.rb +5 -5
- data/spec/components/checks/passive/grep/credit_card_spec.rb +1 -1
- data/spec/components/checks/passive/grep/emails_spec.rb +12 -2
- data/spec/components/checks/passive/grep/ssn_spec.rb +1 -1
- data/spec/components/path_extractors/meta_refresh_spec.rb +3 -1
- data/spec/components/plugins/exec_spec.rb +2 -2
- data/spec/components/plugins/login_script_spec.rb +22 -2
- data/spec/components/plugins/vector_feed_spec.rb +3 -3
- data/spec/spec_helper.rb +10 -4
- data/spec/support/factories/browser_cluster/job.rb +1 -0
- data/spec/support/fixtures/check_with_invalid_platforms/with_invalid_platforms.rb +1 -1
- data/spec/support/fixtures/checks/test.rb +1 -1
- data/spec/support/fixtures/checks/test2.rb +1 -1
- data/spec/support/fixtures/checks/test3.rb +1 -1
- data/spec/support/fixtures/fingerprinters/test.rb +1 -1
- data/spec/support/fixtures/plugins/bad.rb +1 -1
- data/spec/support/fixtures/plugins/defaults/default.rb +1 -1
- data/spec/support/fixtures/plugins/distributable.rb +1 -1
- data/spec/support/fixtures/plugins/loop.rb +1 -1
- data/spec/support/fixtures/plugins/suspendable.rb +1 -1
- data/spec/support/fixtures/plugins/wait.rb +1 -1
- data/spec/support/fixtures/plugins/with_options.rb +1 -1
- data/spec/support/fixtures/plugins_with_priorities/p0.rb +1 -1
- data/spec/support/fixtures/plugins_with_priorities/p00.rb +1 -1
- data/spec/support/fixtures/plugins_with_priorities/p1.rb +1 -1
- data/spec/support/fixtures/plugins_with_priorities/p2.rb +1 -1
- data/spec/support/fixtures/plugins_with_priorities/p22.rb +1 -1
- data/spec/support/fixtures/plugins_with_priorities/p222.rb +1 -1
- data/spec/support/fixtures/plugins_with_priorities/p_nil.rb +1 -1
- data/spec/support/fixtures/plugins_with_priorities/p_nil2.rb +1 -1
- data/spec/support/fixtures/report.afr +0 -0
- data/spec/support/fixtures/reporters/base_spec/plugin_formatters/with_formatters/foobar.rb +1 -1
- data/spec/support/fixtures/reporters/base_spec/with_formatters.rb +1 -1
- data/spec/support/fixtures/reporters/base_spec/with_outfile.rb +1 -1
- data/spec/support/fixtures/reporters/base_spec/without_outfile.rb +1 -1
- data/spec/support/fixtures/reporters/manager_spec/afr.rb +1 -1
- data/spec/support/fixtures/reporters/manager_spec/error.rb +1 -1
- data/spec/support/fixtures/reporters/manager_spec/foo.rb +1 -1
- data/spec/support/fixtures/run_check/body.rb +1 -1
- data/spec/support/fixtures/run_check/cookies.rb +1 -1
- data/spec/support/fixtures/run_check/empty.rb +1 -1
- data/spec/support/fixtures/run_check/flch.rb +1 -1
- data/spec/support/fixtures/run_check/forms.rb +1 -1
- data/spec/support/fixtures/run_check/headers.rb +1 -1
- data/spec/support/fixtures/run_check/links.rb +1 -1
- data/spec/support/fixtures/run_check/nil.rb +1 -1
- data/spec/support/fixtures/run_check/path.rb +1 -1
- data/spec/support/fixtures/run_check/server.rb +1 -1
- data/spec/support/fixtures/signature_check/signature.rb +1 -1
- data/spec/support/fixtures/wait_check/wait.rb +1 -1
- data/spec/support/helpers/framework.rb +1 -1
- data/spec/support/helpers/misc.rb +1 -1
- data/spec/support/helpers/paths.rb +1 -1
- data/spec/support/helpers/request_helpers.rb +38 -0
- data/spec/support/helpers/requires.rb +1 -1
- data/spec/support/helpers/resets.rb +1 -1
- data/spec/support/helpers/web_server.rb +1 -1
- data/spec/support/lib/factory.rb +1 -1
- data/spec/support/lib/web_server_client.rb +1 -1
- data/spec/support/lib/web_server_dispatcher.rb +1 -1
- data/spec/support/lib/web_server_manager.rb +2 -2
- data/spec/support/servers/arachni/browser.rb +182 -15
- data/spec/support/servers/arachni/browser/javascript/angular-1.2.8.js +1 -1
- data/spec/support/servers/arachni/browser/javascript/angular-route.js +1 -1
- data/spec/support/servers/arachni/browser/javascript/dom_monitor.rb +27 -4
- data/spec/support/servers/arachni/element/capabilities/analyzable/differential.rb +103 -0
- data/spec/support/servers/arachni/element/capabilities/analyzable/timeout.rb +5 -2
- data/spec/support/servers/arachni/element/header.rb +1 -1
- data/spec/support/servers/arachni/http/client.rb +46 -0
- data/spec/support/servers/arachni/http/client/dynamic_404_handler.rb +7 -1
- data/spec/support/servers/checks/active/code_injection.rb +5 -5
- data/spec/support/servers/checks/active/no_sql_injection.rb +0 -6
- data/spec/support/servers/checks/active/no_sql_injection_differential.rb +1 -1
- data/spec/support/servers/checks/active/sql_injection.rb +5 -2
- data/spec/support/servers/checks/active/sql_injection_differential.rb +1 -1
- data/spec/support/servers/checks/active/trainer_check.rb +6 -6
- data/spec/support/servers/checks/passive/backdoors.rb +1 -0
- data/spec/support/servers/checks/passive/backup_directories.rb +2 -0
- data/spec/support/servers/checks/passive/backup_files.rb +2 -0
- data/spec/support/servers/checks/passive/grep/emails.rb +6 -6
- data/spec/support/shared/check.rb +28 -0
- data/spec/support/shared/element/capabilities/auditable.rb +76 -13
- data/spec/support/shared/element/capabilities/dom_only.rb +5 -6
- data/spec/support/shared/element/capabilities/inputtable.rb +74 -4
- data/spec/support/shared/element/capabilities/mutable.rb +86 -14
- data/spec/support/shared/element/capabilities/submittable.rb +12 -0
- data/spec/support/shared/element/capabilities/with_dom.rb +13 -4
- data/spec/support/shared/element/capabilities/with_node.rb +1 -1
- data/spec/support/shared/element/capabilities/with_source.rb +1 -6
- data/spec/support/shared/element/dom/locatable.rb +20 -0
- data/spec/support/shared/element/dom/submittable.rb +4 -17
- data/spec/support/shared/http/message.rb +37 -5
- data/spec/support/shared/support/cache.rb +5 -4
- data/ui/cli/framework.rb +4 -3
- data/ui/cli/framework/option_parser.rb +20 -8
- data/ui/cli/option_parser.rb +1 -1
- data/ui/cli/output.rb +40 -4
- data/ui/cli/reporter.rb +1 -1
- data/ui/cli/reporter/option_parser.rb +4 -4
- data/ui/cli/rest/server.rb +43 -0
- data/ui/cli/rest/server/option_parser.rb +115 -0
- data/ui/cli/restored_framework.rb +1 -1
- data/ui/cli/restored_framework/option_parser.rb +1 -1
- data/ui/cli/rpc/client/dispatcher_monitor.rb +1 -1
- data/ui/cli/rpc/client/dispatcher_monitor/option_parser.rb +1 -1
- data/ui/cli/rpc/client/instance.rb +1 -1
- data/ui/cli/rpc/client/local.rb +1 -1
- data/ui/cli/rpc/client/local/option_parser.rb +1 -1
- data/ui/cli/rpc/client/remote.rb +1 -1
- data/ui/cli/rpc/client/remote/option_parser.rb +1 -1
- data/ui/cli/rpc/server/dispatcher.rb +1 -1
- data/ui/cli/rpc/server/dispatcher/option_parser.rb +1 -1
- data/ui/cli/utilities.rb +1 -1
- metadata +197 -84
- data/components/checks/active/no_sql_injection/patterns/mongodb +0 -1
- data/components/checks/active/no_sql_injection/regexp_ignore.txt +0 -0
- data/components/checks/active/sql_injection/patterns/access +0 -3
- data/components/checks/active/sql_injection/patterns/db2 +0 -5
- data/components/checks/active/sql_injection/patterns/frontbase +0 -1
- data/components/checks/active/sql_injection/patterns/hsqldb +0 -1
- data/components/checks/active/sql_injection/patterns/ingres +0 -3
- data/components/checks/active/sql_injection/patterns/maxdb +0 -2
- data/components/checks/active/sql_injection/patterns/mssql +0 -25
- data/components/checks/active/sql_injection/patterns/oracle +0 -6
- data/components/checks/active/sql_injection/patterns/sqlite +0 -5
- data/components/checks/active/sql_injection/patterns/sybase +0 -3
- data/lib/arachni/ruby/io.rb +0 -39
- data/lib/arachni/selenium/webdriver/remote/http/typhoeus.rb +0 -63
- data/spec/arachni/ruby/io_spec.rb +0 -26
@@ -1,5 +1,5 @@
|
|
1
1
|
=begin
|
2
|
-
Copyright 2010-
|
2
|
+
Copyright 2010-2016 Tasos Laskos <tasos.laskos@arachni-scanner.com>
|
3
3
|
|
4
4
|
This file is part of the Arachni Framework project and is subject to
|
5
5
|
redistribution and commercial restrictions. Please see the Arachni Framework
|
@@ -1,5 +1,5 @@
|
|
1
1
|
=begin
|
2
|
-
Copyright 2010-
|
2
|
+
Copyright 2010-2016 Tasos Laskos <tasos.laskos@arachni-scanner.com>
|
3
3
|
|
4
4
|
This file is part of the Arachni Framework project and is subject to
|
5
5
|
redistribution and commercial restrictions. Please see the Arachni Framework
|
@@ -1,5 +1,5 @@
|
|
1
1
|
=begin
|
2
|
-
Copyright 2010-
|
2
|
+
Copyright 2010-2016 Tasos Laskos <tasos.laskos@arachni-scanner.com>
|
3
3
|
|
4
4
|
This file is part of the Arachni Framework project and is subject to
|
5
5
|
redistribution and commercial restrictions. Please see the Arachni Framework
|
@@ -19,6 +19,7 @@ class Profiler
|
|
19
19
|
|
20
20
|
def self.write_samples_to_disk( file, options = {} )
|
21
21
|
profiler = Support::Profiler.new
|
22
|
+
# profiler.trace_allocations
|
22
23
|
|
23
24
|
Thread.new do
|
24
25
|
begin
|
@@ -42,11 +43,11 @@ class Profiler
|
|
42
43
|
ap 'Object ID: ' + o.object_id.to_s
|
43
44
|
ap 'Source file: ' + ObjectSpace.allocation_sourcefile(o)
|
44
45
|
ap 'Source line: ' + ObjectSpace.allocation_sourceline(o).to_s
|
45
|
-
ap 'Generation: ' + ObjectSpace.allocation_generation(o).to_s
|
46
|
-
ap 'Class path: ' + ObjectSpace.allocation_class_path(o).to_s
|
46
|
+
# ap 'Generation: ' + ObjectSpace.allocation_generation(o).to_s
|
47
|
+
# ap 'Class path: ' + ObjectSpace.allocation_class_path(o).to_s
|
47
48
|
ap 'Method: ' + ObjectSpace.allocation_method_id(o).to_s
|
48
49
|
ap 'Memsize: ' + ObjectSpace.memsize_of(o).to_s
|
49
|
-
|
50
|
+
ap 'Reachable: ' + ObjectSpace.reachable_objects_from(o).to_s #=> [referenced, objects, ...]
|
50
51
|
ap '-' * 200
|
51
52
|
end
|
52
53
|
|
@@ -103,11 +104,12 @@ class Profiler
|
|
103
104
|
ObjectSpace.each_object do |o|
|
104
105
|
next if o.class != klass && !object_within_namespace?( o, namespaces )
|
105
106
|
|
106
|
-
# if o.class ==
|
107
|
-
#
|
108
|
-
#
|
109
|
-
# ap
|
110
|
-
# ap
|
107
|
+
# if o.class == Page
|
108
|
+
# print_object_allocations( o )
|
109
|
+
#
|
110
|
+
# # ap ObjectSpace.allocation_class_path( o ).to_s
|
111
|
+
# # ap "#{ObjectSpace.allocation_sourcefile( o )}:#{ObjectSpace.allocation_sourceline( o )}"
|
112
|
+
# # ap '-' * 120
|
111
113
|
# end
|
112
114
|
|
113
115
|
object_space[o.class] ||= {
|
@@ -119,7 +121,7 @@ class Profiler
|
|
119
121
|
object_space[o.class][:count] += 1
|
120
122
|
end
|
121
123
|
|
122
|
-
object_space = Hash[object_space.sort_by { |_, v| v[:
|
124
|
+
object_space = Hash[object_space.sort_by { |_, v| v[:count] }.reverse[0..max_entries]]
|
123
125
|
|
124
126
|
with_deltas = {}
|
125
127
|
object_space.each do |k, v|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
=begin
|
2
|
-
Copyright 2010-
|
2
|
+
Copyright 2010-2016 Tasos Laskos <tasos.laskos@arachni-scanner.com>
|
3
3
|
|
4
4
|
This file is part of the Arachni Framework project and is subject to
|
5
5
|
redistribution and commercial restrictions. Please see the Arachni Framework
|
@@ -109,15 +109,14 @@ class Signature
|
|
109
109
|
# @param [Signature, String] data
|
110
110
|
#
|
111
111
|
# @return [Array<String,Integer>]
|
112
|
-
# Words as tokens
|
113
|
-
# hashes, depending on which is smaller in size.
|
112
|
+
# Words as tokens.
|
114
113
|
def tokenize( data )
|
115
114
|
return data.tokens if data.is_a? self.class
|
116
115
|
|
117
116
|
if CACHE[:tokens][data]
|
118
117
|
CACHE[:tokens][data].dup
|
119
118
|
else
|
120
|
-
CACHE[:tokens][data] = compress( data.split( /
|
119
|
+
CACHE[:tokens][data] = compress( data.split( /\W/ ) )
|
121
120
|
end
|
122
121
|
end
|
123
122
|
|
@@ -125,7 +124,15 @@ class Signature
|
|
125
124
|
# Seems kinda silly but this can actually save us GB of RAM when comparing
|
126
125
|
# large signatures, not to mention CPU cycles.
|
127
126
|
def compress( tokens )
|
128
|
-
Set.new
|
127
|
+
s = Set.new
|
128
|
+
tokens.each do |token|
|
129
|
+
# Left-over non-word characters will be on their own, this is a
|
130
|
+
# low-overhead way to dispose of them.
|
131
|
+
next if token.empty?
|
132
|
+
|
133
|
+
s << token.hash
|
134
|
+
end
|
135
|
+
s
|
129
136
|
end
|
130
137
|
|
131
138
|
end
|
data/lib/arachni/trainer.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
=begin
|
2
|
-
Copyright 2010-
|
2
|
+
Copyright 2010-2016 Tasos Laskos <tasos.laskos@arachni-scanner.com>
|
3
3
|
|
4
4
|
This file is part of the Arachni Framework project and is subject to
|
5
5
|
redistribution and commercial restrictions. Please see the Arachni Framework
|
@@ -34,6 +34,8 @@ class Trainer
|
|
34
34
|
@framework = framework
|
35
35
|
@updated = false
|
36
36
|
|
37
|
+
@seen_pages = Support::LookUp::HashSet.new
|
38
|
+
|
37
39
|
@trainings_per_url = Hash.new( 0 )
|
38
40
|
|
39
41
|
# get us setup using the page that is being audited as a seed page
|
@@ -73,8 +75,6 @@ class Trainer
|
|
73
75
|
return
|
74
76
|
end
|
75
77
|
|
76
|
-
return false if !response.text?
|
77
|
-
|
78
78
|
skip_message = nil
|
79
79
|
if @trainings_per_url[response.url] >= MAX_TRAININGS_PER_URL
|
80
80
|
skip_message = "Reached maximum trainings (#{MAX_TRAININGS_PER_URL})"
|
@@ -89,6 +89,20 @@ class Trainer
|
|
89
89
|
return false
|
90
90
|
end
|
91
91
|
|
92
|
+
param_names = response.parsed_url.query_parameters.keys
|
93
|
+
cookies = Cookie.from_headers( response.url, response.headers ).map(&:name)
|
94
|
+
|
95
|
+
k = "#{param_names.hash}:#{cookies.hash}:#{response.body}"
|
96
|
+
|
97
|
+
# Naive optimization but it works a lot of the time. :)
|
98
|
+
if @seen_pages.include? k
|
99
|
+
print_debug "Already seen response for request ID: ##{response.request.id}"
|
100
|
+
return
|
101
|
+
end
|
102
|
+
@seen_pages << k
|
103
|
+
|
104
|
+
return false if !response.text?
|
105
|
+
|
92
106
|
analyze response
|
93
107
|
true
|
94
108
|
rescue => e
|
@@ -102,7 +116,7 @@ class Trainer
|
|
102
116
|
# @param [Arachni::Page] page
|
103
117
|
def page=( page )
|
104
118
|
ElementFilter.update_from_page page
|
105
|
-
@page = page
|
119
|
+
@page = page
|
106
120
|
end
|
107
121
|
|
108
122
|
private
|
@@ -1,5 +1,5 @@
|
|
1
1
|
=begin
|
2
|
-
Copyright 2010-
|
2
|
+
Copyright 2010-2016 Tasos Laskos <tasos.laskos@arachni-scanner.com>
|
3
3
|
|
4
4
|
This file is part of the Arachni Framework project and is subject to
|
5
5
|
redistribution and commercial restrictions. Please see the Arachni Framework
|
@@ -63,12 +63,28 @@ module Output
|
|
63
63
|
def print_debug_level_3(*)
|
64
64
|
end
|
65
65
|
|
66
|
+
def print_debug_level_4(*)
|
67
|
+
end
|
68
|
+
|
66
69
|
def print_debug_backtrace(*)
|
67
70
|
end
|
68
71
|
|
69
72
|
def print_error_backtrace(*)
|
70
73
|
end
|
71
74
|
|
75
|
+
def debug_level_1?
|
76
|
+
debug? 1
|
77
|
+
end
|
78
|
+
def debug_level_2?
|
79
|
+
debug? 2
|
80
|
+
end
|
81
|
+
def debug_level_3?
|
82
|
+
debug? 3
|
83
|
+
end
|
84
|
+
def debug_level_4?
|
85
|
+
debug? 4
|
86
|
+
end
|
87
|
+
|
72
88
|
def print_verbose(*)
|
73
89
|
end
|
74
90
|
|
data/lib/arachni/uri.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
=begin
|
2
|
-
Copyright 2010-
|
2
|
+
Copyright 2010-2016 Tasos Laskos <tasos.laskos@arachni-scanner.com>
|
3
3
|
|
4
4
|
This file is part of the Arachni Framework project and is subject to
|
5
5
|
redistribution and commercial restrictions. Please see the Arachni Framework
|
@@ -21,16 +21,13 @@ module Arachni
|
|
21
21
|
end
|
22
22
|
|
23
23
|
# The URI class automatically normalizes the URLs it is passed to parse
|
24
|
-
# while maintaining compatibility with Ruby's URI core class
|
25
|
-
# missing methods to it -- thus, you can treat it like a Ruby URI and enjoy some
|
26
|
-
# extra perks along the way.
|
24
|
+
# while maintaining compatibility with Ruby's URI core class.
|
27
25
|
#
|
28
26
|
# It also provides *cached* (to maintain a low latency) helper class methods to
|
29
27
|
# ease common operations such as:
|
30
28
|
#
|
31
29
|
# * {.normalize Normalization}.
|
32
|
-
# * Parsing to {.parse Arachni::URI} (see also {.URI})
|
33
|
-
# {.fast_parse Hash} objects.
|
30
|
+
# * Parsing to {.parse Arachni::URI} (see also {.URI}) or {.fast_parse Hash} objects.
|
34
31
|
# * Conversion to {.to_absolute absolute URLs}.
|
35
32
|
#
|
36
33
|
# @author Tasos "Zapotek" Laskos <tasos.laskos@arachni-scanner.com>
|
@@ -50,13 +47,12 @@ class URI
|
|
50
47
|
end
|
51
48
|
|
52
49
|
CACHE_SIZES = {
|
53
|
-
parse:
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
to_absolute: 1000
|
50
|
+
parse: 5_000,
|
51
|
+
fast_parse: 5_000,
|
52
|
+
encode: 10_000,
|
53
|
+
decode: 10_000,
|
54
|
+
normalize: 10_000,
|
55
|
+
to_absolute: 10_000
|
60
56
|
}
|
61
57
|
|
62
58
|
CACHE = {
|
@@ -66,6 +62,8 @@ class URI
|
|
66
62
|
CACHE[name] = Support::Cache::LeastRecentlyPushed.new( size )
|
67
63
|
end
|
68
64
|
|
65
|
+
QUERY_CHARACTER_CLASS = Addressable::URI::CharacterClasses::QUERY.sub( '\\&', '' )
|
66
|
+
|
69
67
|
class <<self
|
70
68
|
|
71
69
|
# @return [URI::Parser] cached URI parser
|
@@ -83,8 +81,9 @@ class URI
|
|
83
81
|
# @return [String]
|
84
82
|
# Encoded string.
|
85
83
|
def encode( string, good_characters = nil )
|
86
|
-
CACHE[__method__][
|
84
|
+
CACHE[__method__].fetch [string, good_characters] do
|
87
85
|
Addressable::URI.encode_component( *[string, good_characters].compact )
|
86
|
+
end
|
88
87
|
end
|
89
88
|
|
90
89
|
# URL decodes a string.
|
@@ -93,7 +92,7 @@ class URI
|
|
93
92
|
#
|
94
93
|
# @return [String]
|
95
94
|
def decode( string )
|
96
|
-
CACHE[__method__]
|
95
|
+
CACHE[__method__].fetch( string ) { Addressable::URI.unencode( string ) }
|
97
96
|
end
|
98
97
|
|
99
98
|
# @note This method's results are cached for performance reasons.
|
@@ -106,35 +105,10 @@ class URI
|
|
106
105
|
# @see URI#initialize
|
107
106
|
def parse( url )
|
108
107
|
return url if !url || url.is_a?( Arachni::URI )
|
109
|
-
CACHE[__method__][url] ||= begin
|
110
|
-
new( url )
|
111
|
-
rescue => e
|
112
|
-
print_debug "Failed to parse '#{url}'."
|
113
|
-
print_debug "Error: #{e}"
|
114
|
-
print_debug_backtrace( e )
|
115
|
-
nil
|
116
|
-
end
|
117
|
-
end
|
118
108
|
|
119
|
-
|
120
|
-
# If you plan on doing something destructive with its return value
|
121
|
-
# duplicate it first because there may be references to it elsewhere.
|
122
|
-
#
|
123
|
-
# {.normalize Normalizes} `url` and uses Ruby's core URI lib to parse it.
|
124
|
-
#
|
125
|
-
# @param [String] url
|
126
|
-
# URL to parse
|
127
|
-
#
|
128
|
-
# @return [URI]
|
129
|
-
def ruby_parse( url )
|
130
|
-
return url if url.to_s.empty? || url.is_a?( ::URI )
|
131
|
-
return if url.downcase.start_with? 'javascript:'
|
132
|
-
|
133
|
-
CACHE[__method__][url] ||= begin
|
134
|
-
::URI::Generic.build( fast_parse( url ) )
|
135
|
-
rescue
|
109
|
+
CACHE[__method__].fetch url do
|
136
110
|
begin
|
137
|
-
|
111
|
+
new( url )
|
138
112
|
rescue => e
|
139
113
|
print_debug "Failed to parse '#{url}'."
|
140
114
|
print_debug "Error: #{e}"
|
@@ -148,11 +122,6 @@ class URI
|
|
148
122
|
# If you plan on doing something destructive with its return value
|
149
123
|
# duplicate it first because there may be references to it elsewhere.
|
150
124
|
#
|
151
|
-
# @note The Hash is suitable for passing to `::URI::Generic.build` -- if
|
152
|
-
# however you plan on doing that you'll be better off just using
|
153
|
-
# {.ruby_parse} which does the same thing and caches the results for some
|
154
|
-
# extra schnell.
|
155
|
-
#
|
156
125
|
# Performs a parse that is less resource intensive than Ruby's URI lib's
|
157
126
|
# method while normalizing the URL (will also discard the fragment and
|
158
127
|
# path parameters).
|
@@ -170,18 +139,19 @@ class URI
|
|
170
139
|
# * `:query`
|
171
140
|
def fast_parse( url )
|
172
141
|
return if !url || url.empty?
|
173
|
-
return if url.downcase.start_with? 'javascript:'
|
142
|
+
return if url.downcase.start_with?( 'javascript:' ) ||
|
143
|
+
url.start_with?( '#' )
|
174
144
|
|
175
145
|
cache = CACHE[__method__]
|
176
146
|
|
177
|
-
|
147
|
+
# One to rip apart.
|
148
|
+
url = url.dup
|
178
149
|
|
179
150
|
# Remove the fragment if there is one.
|
180
|
-
|
181
|
-
url = url.split( '#', 2 )[0...-1].join
|
182
|
-
end
|
151
|
+
url.sub!( /#.*/, '' )
|
183
152
|
|
184
|
-
|
153
|
+
# One for reference.
|
154
|
+
c_url = url
|
185
155
|
|
186
156
|
components = {
|
187
157
|
scheme: nil,
|
@@ -201,14 +171,14 @@ class URI
|
|
201
171
|
return v
|
202
172
|
end
|
203
173
|
|
204
|
-
#
|
205
|
-
#
|
206
|
-
#
|
207
|
-
if url.start_with?( '//' )
|
208
|
-
|
174
|
+
# Parsing the URL in its schemeless form is trickier, so we
|
175
|
+
# fake it, pass a valid scheme to get through the parsing and
|
176
|
+
# then remove it at the other end.
|
177
|
+
if (schemeless = url.start_with?( '//' ))
|
178
|
+
url = "http:#{url}"
|
209
179
|
end
|
210
180
|
|
211
|
-
|
181
|
+
# url.recode!
|
212
182
|
url = html_decode( url )
|
213
183
|
|
214
184
|
dupped_url = url.dup
|
@@ -216,41 +186,39 @@ class URI
|
|
216
186
|
|
217
187
|
splits = url.split( ':' )
|
218
188
|
if !splits.empty? && valid_schemes.include?( splits.first.downcase )
|
189
|
+
|
219
190
|
splits = url.split( '://', 2 )
|
220
191
|
components[:scheme] = splits.shift
|
221
192
|
components[:scheme].downcase! if components[:scheme]
|
222
193
|
|
223
|
-
if url = splits.shift
|
224
|
-
|
194
|
+
if (url = splits.shift)
|
195
|
+
userinfo_host, url = url.to_s.split( '?' ).first.to_s.split( '/', 2 )
|
196
|
+
url = url.to_s
|
197
|
+
splits = userinfo_host.to_s.split( '@', 2 )
|
225
198
|
|
226
199
|
if splits.size > 1
|
227
200
|
components[:userinfo] = splits.first
|
228
|
-
url = splits.shift
|
229
201
|
end
|
230
202
|
|
231
203
|
if !splits.empty?
|
232
204
|
splits = splits.last.split( '/', 2 )
|
233
|
-
url = splits.last
|
234
205
|
|
235
206
|
splits = splits.first.split( ':', 2 )
|
236
207
|
if splits.size == 2
|
237
208
|
host = splits.first
|
238
209
|
|
239
210
|
if splits.last && !splits.last.empty?
|
240
|
-
components[:port] =
|
211
|
+
components[:port] = splits.last.to_i
|
241
212
|
end
|
242
213
|
|
243
214
|
if components[:port] == 80
|
244
215
|
components[:port] = nil
|
245
216
|
end
|
246
|
-
|
247
|
-
url.gsub!( ':' + components[:port].to_s, '' )
|
248
217
|
else
|
249
218
|
host = splits.last
|
250
219
|
end
|
251
220
|
|
252
|
-
if components[:host] = host
|
253
|
-
url.gsub!( host, '' )
|
221
|
+
if (components[:host] = host)
|
254
222
|
components[:host].downcase!
|
255
223
|
end
|
256
224
|
else
|
@@ -265,20 +233,20 @@ class URI
|
|
265
233
|
splits = url.split( '?', 2 )
|
266
234
|
if (components[:path] = splits.shift)
|
267
235
|
if components[:scheme]
|
268
|
-
components[:path] =
|
236
|
+
components[:path] = "/#{components[:path]}"
|
269
237
|
end
|
270
238
|
|
271
239
|
components[:path].gsub!( /\/+/, '/' )
|
272
240
|
|
273
241
|
# Remove path params
|
274
|
-
components[:path]
|
242
|
+
components[:path].sub!( /\;.*/, '' )
|
275
243
|
|
276
244
|
if components[:path]
|
277
245
|
components[:path] =
|
278
246
|
encode( decode( components[:path] ),
|
279
|
-
Addressable::URI::CharacterClasses::PATH )
|
247
|
+
Addressable::URI::CharacterClasses::PATH ).dup
|
280
248
|
|
281
|
-
components[:path]
|
249
|
+
components[:path].gsub!( ';', '%3B' )
|
282
250
|
end
|
283
251
|
end
|
284
252
|
|
@@ -286,68 +254,33 @@ class URI
|
|
286
254
|
!(query = dupped_url.split( '?', 2 ).last).empty?
|
287
255
|
|
288
256
|
components[:query] = (query.split( '&', -1 ).map do |pair|
|
289
|
-
encode( decode( pair ),
|
290
|
-
Addressable::URI::CharacterClasses::QUERY.sub( '\\&', '' ) )
|
257
|
+
encode( decode( pair ), QUERY_CHARACTER_CLASS )
|
291
258
|
end).join( '&' )
|
292
259
|
end
|
293
260
|
end
|
294
261
|
|
262
|
+
if schemeless
|
263
|
+
components.delete :scheme
|
264
|
+
end
|
265
|
+
|
295
266
|
components[:path] ||= components[:scheme] ? '/' : nil
|
296
267
|
|
297
268
|
components.values.each(&:freeze)
|
298
269
|
|
299
270
|
cache[c_url] = components.freeze
|
300
271
|
rescue => e
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
272
|
+
ap e
|
273
|
+
ap e.backtrace
|
274
|
+
ap c_url
|
275
|
+
ap url
|
305
276
|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
print_debug "Error: #{ex}"
|
310
|
-
print_debug_backtrace( ex )
|
311
|
-
|
312
|
-
cache[c_url] = :err
|
313
|
-
nil
|
314
|
-
end
|
315
|
-
end
|
316
|
-
end
|
277
|
+
print_debug "Failed to parse '#{c_url}'."
|
278
|
+
print_debug "Error: #{e}"
|
279
|
+
print_debug_backtrace( e )
|
317
280
|
|
318
|
-
|
319
|
-
|
320
|
-
# {.ruby_parse} which does the same thing and caches the results for
|
321
|
-
# some extra schnell.
|
322
|
-
#
|
323
|
-
# Performs a parse using the `URI::Addressable` lib while normalizing the
|
324
|
-
# URL (will also discard the fragment).
|
325
|
-
#
|
326
|
-
# This method is not cached and solely exists as a fallback used by {.fast_parse}.
|
327
|
-
#
|
328
|
-
# @param [String] url
|
329
|
-
#
|
330
|
-
# @return [Hash]
|
331
|
-
# URL components:
|
332
|
-
#
|
333
|
-
# * `:scheme` -- HTTP or HTTPS
|
334
|
-
# * `:userinfo` -- `username:password`
|
335
|
-
# * `:host`
|
336
|
-
# * `:port`
|
337
|
-
# * `:path`
|
338
|
-
# * `:query`
|
339
|
-
#
|
340
|
-
def addressable_parse( url )
|
341
|
-
u = Addressable::URI.parse( html_decode( url.to_s ) ).normalize
|
342
|
-
u.fragment = nil
|
343
|
-
h = u.to_hash
|
344
|
-
|
345
|
-
h[:path].gsub!( /\/+/, '/' ) if h[:path]
|
346
|
-
if h[:user]
|
347
|
-
h[:userinfo] = h.delete( :user )
|
348
|
-
h[:userinfo] << ":#{h.delete( :password )}" if h[:password]
|
281
|
+
cache[c_url] = :err
|
282
|
+
nil
|
349
283
|
end
|
350
|
-
h
|
351
284
|
end
|
352
285
|
|
353
286
|
# @note This method's results are cached for performance reasons.
|
@@ -366,8 +299,8 @@ class URI
|
|
366
299
|
# @return [String]
|
367
300
|
# Absolute URL (frozen).
|
368
301
|
def to_absolute( relative, reference = Options.instance.url.to_s )
|
369
|
-
return reference if !relative || relative.empty?
|
370
|
-
key = relative
|
302
|
+
return normalize( reference ) if !relative || relative.empty?
|
303
|
+
key = [relative, reference].hash
|
371
304
|
|
372
305
|
cache = CACHE[__method__]
|
373
306
|
begin
|
@@ -385,7 +318,13 @@ class URI
|
|
385
318
|
relative = "#{parsed_ref.scheme}:#{relative}"
|
386
319
|
end
|
387
320
|
|
388
|
-
|
321
|
+
parsed = parse( relative )
|
322
|
+
|
323
|
+
# Doesn't contain anything or interest (javascript: or fragment only),
|
324
|
+
# return the ref.
|
325
|
+
return parsed_ref.to_s if !parsed
|
326
|
+
|
327
|
+
cache[key] = parsed.to_absolute( parsed_ref ).to_s.freeze
|
389
328
|
rescue
|
390
329
|
cache[key] = :err
|
391
330
|
nil
|
@@ -418,25 +357,7 @@ class URI
|
|
418
357
|
return v
|
419
358
|
end
|
420
359
|
|
421
|
-
|
422
|
-
|
423
|
-
normalized = ''
|
424
|
-
normalized << components[:scheme] + '://' if components[:scheme]
|
425
|
-
|
426
|
-
if components[:userinfo]
|
427
|
-
normalized << components[:userinfo]
|
428
|
-
normalized << '@'
|
429
|
-
end
|
430
|
-
|
431
|
-
if components[:host]
|
432
|
-
normalized << components[:host]
|
433
|
-
normalized << ':' + components[:port].to_s if components[:port]
|
434
|
-
end
|
435
|
-
|
436
|
-
normalized << components[:path] if components[:path]
|
437
|
-
normalized << '?' + components[:query] if components[:query]
|
438
|
-
|
439
|
-
cache[c_url] = normalized.freeze
|
360
|
+
cache[c_url] = parse( url ).to_s.freeze
|
440
361
|
rescue => e
|
441
362
|
print_debug "Failed to normalize '#{c_url}'."
|
442
363
|
print_debug "Error: #{e}"
|
@@ -488,35 +409,19 @@ class URI
|
|
488
409
|
#
|
489
410
|
# {.normalize Normalizes} and parses the provided URL.
|
490
411
|
#
|
491
|
-
# @param [
|
412
|
+
# @param [String] url
|
492
413
|
# {String} URL to parse, `URI` to convert, or a `Hash` holding URL components
|
493
414
|
# (for `URI::Generic.build`). Also accepts {Arachni::URI} for convenience.
|
494
415
|
def initialize( url )
|
495
|
-
@
|
496
|
-
when String
|
497
|
-
self.class.ruby_parse( url )
|
498
|
-
|
499
|
-
when ::URI
|
500
|
-
url
|
501
|
-
|
502
|
-
when Hash
|
503
|
-
::URI::Generic.build( url )
|
416
|
+
@data = self.class.fast_parse( url )
|
504
417
|
|
505
|
-
|
506
|
-
self.parsed_url = url.parsed_url
|
418
|
+
fail Error, 'Failed to parse URL.' if !@data
|
507
419
|
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
msg << " -- #{url.class.name} '#{to_string}' passed."
|
512
|
-
fail ArgumentError.new( msg )
|
513
|
-
end
|
514
|
-
|
515
|
-
fail Error, 'Failed to parse URL.' if !@parsed_url
|
420
|
+
%w(scheme userinfo host port path query).each do |part|
|
421
|
+
instance_variable_set( "@#{part}", @data[part.to_sym] )
|
422
|
+
end
|
516
423
|
|
517
|
-
|
518
|
-
# entries.
|
519
|
-
@parsed_url = @parsed_url.dup
|
424
|
+
reset_userpass
|
520
425
|
end
|
521
426
|
|
522
427
|
# @return [Scope]
|
@@ -528,25 +433,106 @@ class URI
|
|
528
433
|
to_s == other.to_s
|
529
434
|
end
|
530
435
|
|
436
|
+
def absolute?
|
437
|
+
!!@scheme
|
438
|
+
end
|
439
|
+
|
440
|
+
def relative?
|
441
|
+
!absolute?
|
442
|
+
end
|
443
|
+
|
531
444
|
# Converts self into an absolute URL using `reference` to fill in the
|
532
445
|
# missing data.
|
533
446
|
#
|
534
|
-
# @param [Arachni::URI,
|
447
|
+
# @param [Arachni::URI, #to_s] reference
|
535
448
|
# Full, absolute URL.
|
536
449
|
#
|
537
450
|
# @return [Arachni::URI]
|
538
|
-
#
|
539
|
-
def to_absolute( reference )
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
451
|
+
# Copy of self, as an absolute URL.
|
452
|
+
def to_absolute!( reference )
|
453
|
+
if !reference.is_a?( self.class )
|
454
|
+
reference = self.class.new( reference.to_s )
|
455
|
+
end
|
456
|
+
|
457
|
+
%w(scheme userinfo host port).each do |part|
|
458
|
+
next if send( part )
|
459
|
+
|
460
|
+
ref_part = reference.send( "#{part}" )
|
461
|
+
next if !ref_part
|
548
462
|
|
549
|
-
|
463
|
+
send( "#{part}=", ref_part )
|
464
|
+
end
|
465
|
+
|
466
|
+
base_path = reference.path.split( %r{/+}, -1 )
|
467
|
+
rel_path = path.split( %r{/+}, -1 )
|
468
|
+
|
469
|
+
# RFC2396, Section 5.2, 6), a)
|
470
|
+
base_path << '' if base_path.last == '..'
|
471
|
+
while (i = base_path.index( '..' ))
|
472
|
+
base_path.slice!( i - 1, 2 )
|
473
|
+
end
|
474
|
+
|
475
|
+
if (first = rel_path.first) && first.empty?
|
476
|
+
base_path.clear
|
477
|
+
rel_path.shift
|
478
|
+
end
|
479
|
+
|
480
|
+
# RFC2396, Section 5.2, 6), c)
|
481
|
+
# RFC2396, Section 5.2, 6), d)
|
482
|
+
rel_path.push('') if rel_path.last == '.' || rel_path.last == '..'
|
483
|
+
rel_path.delete('.')
|
484
|
+
|
485
|
+
# RFC2396, Section 5.2, 6), e)
|
486
|
+
tmp = []
|
487
|
+
rel_path.each do |x|
|
488
|
+
if x == '..' &&
|
489
|
+
!(tmp.empty? || tmp.last == '..')
|
490
|
+
tmp.pop
|
491
|
+
else
|
492
|
+
tmp << x
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
add_trailer_slash = !tmp.empty?
|
497
|
+
if base_path.empty?
|
498
|
+
base_path = [''] # keep '/' for root directory
|
499
|
+
elsif add_trailer_slash
|
500
|
+
base_path.pop
|
501
|
+
end
|
502
|
+
|
503
|
+
while (x = tmp.shift)
|
504
|
+
if x == '..'
|
505
|
+
# RFC2396, Section 4
|
506
|
+
# a .. or . in an absolute path has no special meaning
|
507
|
+
base_path.pop if base_path.size > 1
|
508
|
+
else
|
509
|
+
# if x == '..'
|
510
|
+
# valid absolute (but abnormal) path "/../..."
|
511
|
+
# else
|
512
|
+
# valid absolute path
|
513
|
+
# end
|
514
|
+
base_path << x
|
515
|
+
tmp.each {|t| base_path << t}
|
516
|
+
add_trailer_slash = false
|
517
|
+
break
|
518
|
+
end
|
519
|
+
end
|
520
|
+
|
521
|
+
base_path.push('') if add_trailer_slash
|
522
|
+
@path = base_path.join('/')
|
523
|
+
|
524
|
+
self
|
525
|
+
end
|
526
|
+
|
527
|
+
# @return [Bool]
|
528
|
+
# `true` if the scan #{Utilities.random_seed seed} is included in the
|
529
|
+
# domain, `false` otherwise.
|
530
|
+
def seed_in_host?
|
531
|
+
host.to_s.include?( Utilities.random_seed )
|
532
|
+
end
|
533
|
+
|
534
|
+
def to_absolute( reference )
|
535
|
+
dup.to_absolute!( reference )
|
550
536
|
end
|
551
537
|
|
552
538
|
# @return [String]
|
@@ -580,9 +566,19 @@ class URI
|
|
580
566
|
|
581
567
|
uri_path << '/' if uri_path[-1] != '/'
|
582
568
|
|
569
|
+
up_to_port << uri_path
|
570
|
+
end
|
571
|
+
|
572
|
+
# @return [String]
|
573
|
+
# Scheme, host & port only.
|
574
|
+
def up_to_port
|
583
575
|
uri_str = "#{scheme}://#{host}"
|
584
|
-
|
585
|
-
|
576
|
+
|
577
|
+
if port && ((scheme == 'http' && port != 80) || (scheme == 'https' && port != 443))
|
578
|
+
uri_str << ':' + port.to_s
|
579
|
+
end
|
580
|
+
|
581
|
+
uri_str
|
586
582
|
end
|
587
583
|
|
588
584
|
# @return [String]
|
@@ -621,15 +617,15 @@ class URI
|
|
621
617
|
!(IPAddr.new( host ) rescue nil).nil?
|
622
618
|
end
|
623
619
|
|
624
|
-
def
|
625
|
-
|
620
|
+
def query
|
621
|
+
@query
|
626
622
|
end
|
627
623
|
|
628
624
|
def query=( q )
|
629
625
|
q = q.to_s
|
630
626
|
q = nil if q.empty?
|
631
627
|
|
632
|
-
@
|
628
|
+
@query = q
|
633
629
|
end
|
634
630
|
|
635
631
|
# @return [Hash]
|
@@ -645,9 +641,95 @@ class URI
|
|
645
641
|
end
|
646
642
|
end
|
647
643
|
|
644
|
+
def userinfo=( ui )
|
645
|
+
@userinfo = ui
|
646
|
+
ensure
|
647
|
+
reset_userpass
|
648
|
+
end
|
649
|
+
|
650
|
+
def userinfo
|
651
|
+
@userinfo
|
652
|
+
end
|
653
|
+
|
654
|
+
def user
|
655
|
+
@user
|
656
|
+
end
|
657
|
+
|
658
|
+
def password
|
659
|
+
@password
|
660
|
+
end
|
661
|
+
|
662
|
+
def port
|
663
|
+
@port
|
664
|
+
end
|
665
|
+
|
666
|
+
def port=( p )
|
667
|
+
if p
|
668
|
+
@port = p.to_i
|
669
|
+
else
|
670
|
+
@port = nil
|
671
|
+
end
|
672
|
+
end
|
673
|
+
|
674
|
+
def host
|
675
|
+
@host
|
676
|
+
end
|
677
|
+
|
678
|
+
def host=( h )
|
679
|
+
@host = h
|
680
|
+
end
|
681
|
+
|
682
|
+
def path
|
683
|
+
@path
|
684
|
+
end
|
685
|
+
|
686
|
+
def path=( p )
|
687
|
+
@path = p
|
688
|
+
end
|
689
|
+
|
690
|
+
def scheme
|
691
|
+
@scheme
|
692
|
+
end
|
693
|
+
|
694
|
+
def scheme=( s )
|
695
|
+
@scheme = s
|
696
|
+
end
|
697
|
+
|
648
698
|
# @return [String]
|
649
699
|
def to_s
|
650
|
-
|
700
|
+
s = ''
|
701
|
+
|
702
|
+
if @scheme
|
703
|
+
s << @scheme
|
704
|
+
s << '://'
|
705
|
+
end
|
706
|
+
|
707
|
+
if @userinfo
|
708
|
+
s << @userinfo
|
709
|
+
s << '@'
|
710
|
+
end
|
711
|
+
|
712
|
+
if @host
|
713
|
+
s << @host
|
714
|
+
|
715
|
+
if @port
|
716
|
+
if (@scheme == 'http' && @port != 80) ||
|
717
|
+
(@scheme == 'https' && @port != 443)
|
718
|
+
|
719
|
+
s << ':'
|
720
|
+
s << @port.to_s
|
721
|
+
end
|
722
|
+
end
|
723
|
+
end
|
724
|
+
|
725
|
+
s << @path.to_s
|
726
|
+
|
727
|
+
if @query
|
728
|
+
s << '?'
|
729
|
+
s << @query
|
730
|
+
end
|
731
|
+
|
732
|
+
s
|
651
733
|
end
|
652
734
|
|
653
735
|
def dup
|
@@ -670,29 +752,29 @@ class URI
|
|
670
752
|
to_s.persistent_hash
|
671
753
|
end
|
672
754
|
|
673
|
-
|
674
|
-
|
675
|
-
def
|
676
|
-
if @
|
677
|
-
@
|
755
|
+
private
|
756
|
+
|
757
|
+
def reset_userpass
|
758
|
+
if @userinfo
|
759
|
+
@user, @password = @userinfo.split( ':', -1 )
|
678
760
|
else
|
679
|
-
|
761
|
+
@user = @password = nil
|
680
762
|
end
|
681
763
|
end
|
682
764
|
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
end
|
692
|
-
|
693
|
-
def
|
694
|
-
|
695
|
-
end
|
765
|
+
# Delegates unimplemented methods to Ruby's `URI::Generic` class for
|
766
|
+
# compatibility.
|
767
|
+
# def method_missing( sym, *args, &block )
|
768
|
+
# if @data.respond_to?( sym )
|
769
|
+
# @parsed_url.send( sym, *args, &block )
|
770
|
+
# else
|
771
|
+
# super
|
772
|
+
# end
|
773
|
+
# end
|
774
|
+
#
|
775
|
+
# def respond_to?( *args )
|
776
|
+
# super || @parsed_url.respond_to?( *args )
|
777
|
+
# end
|
696
778
|
|
697
779
|
end
|
698
780
|
end
|