arachni 1.1 → 1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +159 -0
- data/LICENSE.md +126 -196
- data/README.md +32 -24
- data/arachni.gemspec +7 -7
- data/components/checks/active/code_injection_timing.rb +3 -3
- data/components/checks/active/csrf.rb +2 -2
- data/components/checks/active/file_inclusion.rb +6 -7
- data/components/checks/active/os_cmd_injection.rb +3 -3
- data/components/checks/active/path_traversal.rb +7 -7
- data/components/checks/active/response_splitting.rb +9 -4
- data/components/checks/active/session_fixation.rb +7 -3
- data/components/checks/active/source_code_disclosure.rb +5 -5
- data/components/checks/active/unvalidated_redirect.rb +12 -3
- data/components/checks/active/unvalidated_redirect_dom.rb +3 -3
- data/components/checks/active/xss.rb +23 -10
- data/components/checks/active/xss_dom_inputs.rb +113 -11
- data/components/checks/active/xxe.rb +3 -3
- data/components/checks/passive/backdoors.rb +6 -5
- data/components/checks/passive/backup_directories.rb +6 -6
- data/components/checks/passive/backup_files.rb +6 -6
- data/components/checks/passive/common_admin_interfaces.rb +58 -0
- data/components/checks/passive/common_admin_interfaces/admin-panels.txt +49 -0
- data/components/checks/passive/common_directories/directories.txt +0 -16
- data/components/checks/passive/common_files.rb +6 -5
- data/components/checks/passive/common_files/filenames.txt +0 -2
- data/components/checks/passive/directory_listing.rb +6 -6
- data/components/checks/passive/grep/cookie_set_for_parent_domain.rb +3 -3
- data/components/checks/passive/grep/hsts.rb +6 -3
- data/components/checks/passive/grep/http_only_cookies.rb +3 -3
- data/components/checks/passive/grep/insecure_cookies.rb +2 -2
- data/components/checks/passive/grep/insecure_cors_policy.rb +6 -4
- data/components/checks/passive/grep/x_frame_options.rb +6 -4
- data/components/checks/passive/htaccess_limit.rb +6 -2
- data/components/checks/passive/http_put.rb +8 -4
- data/components/checks/passive/interesting_responses.rb +3 -2
- data/components/checks/passive/localstart_asp.rb +6 -2
- data/components/checks/passive/origin_spoof_access_restriction_bypass.rb +5 -1
- data/components/checks/passive/xst.rb +6 -2
- data/components/fingerprinters/frameworks/aspx_mvc.rb +43 -0
- data/components/fingerprinters/frameworks/cakephp.rb +28 -0
- data/components/fingerprinters/frameworks/cherrypy.rb +31 -0
- data/components/fingerprinters/frameworks/django.rb +33 -0
- data/components/fingerprinters/frameworks/jsf.rb +30 -0
- data/components/fingerprinters/frameworks/rack.rb +5 -7
- data/components/fingerprinters/frameworks/rails.rb +43 -0
- data/components/fingerprinters/languages/aspx.rb +11 -11
- data/components/fingerprinters/languages/{jsp.rb → java.rb} +11 -7
- data/components/fingerprinters/languages/php.rb +6 -6
- data/components/fingerprinters/languages/python.rb +14 -6
- data/components/fingerprinters/languages/ruby.rb +3 -5
- data/components/fingerprinters/servers/apache.rb +5 -4
- data/components/fingerprinters/servers/gunicorn.rb +33 -0
- data/components/fingerprinters/servers/jetty.rb +1 -1
- data/components/fingerprinters/servers/tomcat.rb +11 -4
- data/components/path_extractors/anchors.rb +5 -12
- data/components/path_extractors/areas.rb +5 -13
- data/components/path_extractors/comments.rb +5 -3
- data/components/path_extractors/data_url.rb +21 -0
- data/components/path_extractors/forms.rb +5 -13
- data/components/path_extractors/frames.rb +6 -13
- data/components/path_extractors/generic.rb +3 -12
- data/components/path_extractors/links.rb +5 -13
- data/components/path_extractors/meta_refresh.rb +5 -13
- data/components/path_extractors/scripts.rb +8 -14
- data/components/plugins/autologin.rb +17 -5
- data/components/plugins/defaults/meta/remedies/discovery.rb +11 -29
- data/components/plugins/login_script.rb +40 -10
- data/components/plugins/metrics.rb +235 -0
- data/components/plugins/proxy.rb +21 -4
- data/components/plugins/proxy/panel/page_accordion.html.erb +34 -2
- data/components/plugins/restrict_to_dom_state.rb +70 -0
- data/components/plugins/vector_feed.rb +38 -9
- data/components/reporters/plugin_formatters/html/metrics.rb +290 -0
- data/components/reporters/plugin_formatters/stdout/metrics.rb +80 -0
- data/components/reporters/plugin_formatters/xml/metrics.rb +29 -0
- data/components/reporters/stdout.rb +4 -2
- data/components/reporters/xml.rb +4 -4
- data/components/reporters/xml/schema.xsd +95 -0
- data/lib/arachni.rb +2 -0
- data/lib/arachni/browser.rb +132 -77
- data/lib/arachni/browser/javascript.rb +173 -45
- data/lib/arachni/browser/javascript/scripts/dom_monitor.js +81 -6
- data/lib/arachni/browser/javascript/scripts/taint_tracer.js +31 -3
- data/lib/arachni/browser_cluster.rb +41 -15
- data/lib/arachni/browser_cluster/job.rb +4 -0
- data/lib/arachni/browser_cluster/jobs/resource_exploration.rb +0 -9
- data/lib/arachni/browser_cluster/worker.rb +8 -5
- data/lib/arachni/check/auditor.rb +20 -8
- data/lib/arachni/check/base.rb +38 -6
- data/lib/arachni/element/base.rb +18 -1
- data/lib/arachni/element/capabilities/analyzable/differential.rb +0 -1
- data/lib/arachni/element/capabilities/analyzable/taint.rb +40 -10
- data/lib/arachni/element/capabilities/analyzable/timeout.rb +27 -23
- data/lib/arachni/element/capabilities/auditable/dom.rb +22 -0
- data/lib/arachni/element/capabilities/inputtable.rb +6 -2
- data/lib/arachni/element/capabilities/submittable.rb +1 -1
- data/lib/arachni/element/cookie.rb +37 -23
- data/lib/arachni/element/cookie/capabilities/mutable.rb +6 -6
- data/lib/arachni/element/cookie/dom.rb +0 -8
- data/lib/arachni/element/form.rb +28 -14
- data/lib/arachni/element/form/capabilities/auditable.rb +2 -2
- data/lib/arachni/element/form/capabilities/mutable.rb +5 -5
- data/lib/arachni/element/form/dom.rb +0 -8
- data/lib/arachni/element/generic_dom.rb +1 -1
- data/lib/arachni/element/json.rb +2 -1
- data/lib/arachni/element/json/capabilities/inputtable.rb +6 -6
- data/lib/arachni/element/json/capabilities/mutable.rb +1 -1
- data/lib/arachni/element/link.rb +13 -16
- data/lib/arachni/element/link/dom.rb +1 -14
- data/lib/arachni/element/link_template.rb +3 -2
- data/lib/arachni/element/link_template/dom.rb +0 -16
- data/lib/arachni/element/server.rb +51 -9
- data/lib/arachni/element/xml.rb +1 -0
- data/lib/arachni/ethon/easy.rb +4 -1
- data/lib/arachni/framework/parts/audit.rb +26 -77
- data/lib/arachni/framework/parts/browser.rb +50 -55
- data/lib/arachni/framework/parts/check.rb +4 -3
- data/lib/arachni/framework/parts/data.rb +41 -6
- data/lib/arachni/framework/parts/state.rb +16 -7
- data/lib/arachni/http/client.rb +66 -38
- data/lib/arachni/http/client/dynamic_404_handler.rb +46 -14
- data/lib/arachni/http/headers.rb +22 -10
- data/lib/arachni/http/proxy_server.rb +67 -22
- data/lib/arachni/http/proxy_server/ssl-interceptor-cacert.pem +34 -0
- data/lib/arachni/http/proxy_server/ssl-interceptor-cakey.pem +51 -0
- data/lib/arachni/http/request.rb +71 -18
- data/lib/arachni/issue.rb +17 -3
- data/lib/arachni/option_groups/browser_cluster.rb +34 -1
- data/lib/arachni/option_groups/http.rb +1 -1
- data/lib/arachni/page.rb +26 -13
- data/lib/arachni/page/dom/transition.rb +2 -2
- data/lib/arachni/parser.rb +28 -11
- data/lib/arachni/platform/fingerprinter.rb +5 -0
- data/lib/arachni/platform/manager.rb +65 -32
- data/lib/arachni/plugin/base.rb +8 -0
- data/lib/arachni/processes/instances.rb +25 -11
- data/lib/arachni/reporter/manager.rb +2 -2
- data/lib/arachni/rpc/client/instance.rb +4 -0
- data/lib/arachni/rpc/server/framework/master.rb +3 -3
- data/lib/arachni/rpc/server/framework/multi_instance.rb +0 -8
- data/lib/arachni/rpc/server/instance.rb +2 -1
- data/lib/arachni/ruby/array.rb +5 -0
- data/lib/arachni/ruby/hash.rb +5 -0
- data/lib/arachni/ruby/string.rb +2 -3
- data/lib/arachni/session.rb +32 -6
- data/lib/arachni/state/framework.rb +6 -2
- data/lib/arachni/support/cache.rb +1 -0
- data/lib/arachni/support/cache/base.rb +12 -8
- data/lib/arachni/support/cache/least_recently_pushed.rb +29 -0
- data/lib/arachni/support/cache/least_recently_used.rb +5 -8
- data/lib/arachni/support/cache/preference.rb +1 -1
- data/lib/arachni/support/cache/random_replacement.rb +1 -25
- data/lib/arachni/support/database/queue.rb +21 -8
- data/lib/arachni/support/lookup/base.rb +7 -1
- data/lib/arachni/support/mixins/observable.rb +3 -1
- data/lib/arachni/support/profiler.rb +51 -10
- data/lib/arachni/support/signature.rb +11 -2
- data/lib/arachni/trainer.rb +8 -2
- data/lib/arachni/uri.rb +28 -25
- data/lib/arachni/uri/scope.rb +1 -1
- data/lib/arachni/utilities.rb +8 -0
- data/lib/arachni/watir/element.rb +1 -1
- data/lib/version +1 -1
- data/spec/arachni/browser/javascript/dom_monitor_spec.rb +388 -53
- data/spec/arachni/browser/javascript/taint_tracer_spec.rb +41 -0
- data/spec/arachni/browser/javascript_spec.rb +235 -61
- data/spec/arachni/browser_cluster/jobs/resource_exploration_spec.rb +0 -9
- data/spec/arachni/browser_cluster_spec.rb +58 -10
- data/spec/arachni/browser_spec.rb +170 -26
- data/spec/arachni/check/auditor_spec.rb +22 -3
- data/spec/arachni/check/base_spec.rb +84 -0
- data/spec/arachni/element/body_spec.rb +1 -1
- data/spec/arachni/element/capabilities/analyzable/taint_spec.rb +3 -3
- data/spec/arachni/element/capabilities/analyzable/timeout_spec.rb +1 -1
- data/spec/arachni/element/cookie/dom_spec.rb +0 -9
- data/spec/arachni/element/cookie_spec.rb +85 -0
- data/spec/arachni/element/form/dom_spec.rb +0 -9
- data/spec/arachni/element/form_spec.rb +46 -3
- data/spec/arachni/element/json_spec.rb +20 -0
- data/spec/arachni/element/link/dom_spec.rb +0 -9
- data/spec/arachni/element/link_spec.rb +40 -15
- data/spec/arachni/element/link_template/dom_spec.rb +0 -8
- data/spec/arachni/element/link_template_spec.rb +2 -6
- data/spec/arachni/element/server_spec.rb +94 -8
- data/spec/arachni/element/xml_spec.rb +20 -0
- data/spec/arachni/framework/parts/audit_spec.rb +12 -14
- data/spec/arachni/framework/parts/browser_spec.rb +0 -171
- data/spec/arachni/framework/parts/platform_spec.rb +14 -8
- data/spec/arachni/framework/parts/report_spec.rb +1 -1
- data/spec/arachni/framework/parts/state_spec.rb +0 -9
- data/spec/arachni/http/client/dynamic_404_handlers_spec.rb +19 -0
- data/spec/arachni/http/client_spec.rb +169 -42
- data/spec/arachni/http/headers_spec.rb +18 -0
- data/spec/arachni/http/request_spec.rb +23 -0
- data/spec/arachni/issue_spec.rb +17 -6
- data/spec/arachni/page_spec.rb +22 -2
- data/spec/arachni/parser_spec.rb +5 -0
- data/spec/arachni/platform/manager_spec.rb +57 -25
- data/spec/arachni/reporter/manager_spec.rb +26 -0
- data/spec/arachni/rpc/server/active_options_spec.rb +9 -4
- data/spec/arachni/state/framework_spec.rb +2 -8
- data/spec/arachni/support/cache/least_recently_pushed_spec.rb +90 -0
- data/spec/arachni/support/cache/least_recently_used_spec.rb +5 -13
- data/spec/arachni/support/database/queue_spec.rb +7 -0
- data/spec/arachni/support/mixins/observable_spec.rb +15 -1
- data/spec/arachni/trainer_spec.rb +2 -2
- data/spec/components/checks/active/code_injection_timing_spec.rb +1 -1
- data/spec/components/checks/active/file_inclusion_spec.rb +6 -6
- data/spec/components/checks/active/path_traversal_spec.rb +2 -2
- data/spec/components/checks/active/source_code_disclosure_spec.rb +2 -2
- data/spec/components/checks/active/unvalidated_redirect_spec.rb +6 -6
- data/spec/components/checks/active/xss_dom_inputs_spec.rb +3 -5
- data/spec/components/checks/active/xss_dom_script_context_spec.rb +1 -1
- data/spec/components/checks/active/xss_spec.rb +5 -5
- data/spec/components/checks/passive/common_admin_interfaces_spec.rb +15 -0
- data/spec/components/checks/passive/interesting_responses_spec.rb +14 -1
- data/spec/components/fingerprinters/frameworks/aspx_mvc_spec.rb +31 -0
- data/spec/components/fingerprinters/frameworks/cakephp_spec.rb +22 -0
- data/spec/components/fingerprinters/frameworks/cherrypy_spec.rb +28 -0
- data/spec/components/fingerprinters/frameworks/django_spec.rb +37 -0
- data/spec/components/fingerprinters/frameworks/jsf_spec.rb +27 -0
- data/spec/components/fingerprinters/frameworks/rack_spec.rb +11 -14
- data/spec/components/fingerprinters/frameworks/rails_spec.rb +53 -0
- data/spec/components/fingerprinters/languages/asp_spec.rb +7 -9
- data/spec/components/fingerprinters/languages/aspx_spec.rb +10 -24
- data/spec/components/fingerprinters/languages/java_spec.rb +88 -0
- data/spec/components/fingerprinters/languages/php_spec.rb +19 -12
- data/spec/components/fingerprinters/languages/python_spec.rb +22 -9
- data/spec/components/fingerprinters/languages/ruby.rb +6 -4
- data/spec/components/fingerprinters/os/bsd_spec.rb +6 -4
- data/spec/components/fingerprinters/os/linux_spec.rb +6 -4
- data/spec/components/fingerprinters/os/solaris_spec.rb +6 -4
- data/spec/components/fingerprinters/os/unix_spec.rb +6 -4
- data/spec/components/fingerprinters/os/windows_spec.rb +6 -4
- data/spec/components/fingerprinters/servers/apache_spec.rb +15 -4
- data/spec/components/fingerprinters/servers/gunicorn_spec.rb +28 -0
- data/spec/components/fingerprinters/servers/iis_spec.rb +6 -6
- data/spec/components/fingerprinters/servers/jetty_spec.rb +6 -6
- data/spec/components/fingerprinters/servers/nginx_spec.rb +6 -4
- data/spec/components/fingerprinters/servers/tomcat_spec.rb +15 -6
- data/spec/components/path_extractors/data_url_spec.rb +19 -0
- data/spec/components/plugins/autologin_spec.rb +23 -0
- data/spec/components/plugins/login_script_spec.rb +112 -24
- data/spec/components/plugins/restrict_to_dom_state_spec.rb +16 -0
- data/spec/components/plugins/vector_feed_spec.rb +39 -1
- data/spec/support/factories/page/dom.rb +9 -4
- data/spec/support/factories/page/dom/transition.rb +31 -9
- data/spec/support/factories/scan_report.rb +8 -6
- data/spec/support/fixtures/empty/placeholder +0 -0
- data/spec/support/fixtures/report.afr +0 -0
- data/spec/support/fixtures/reporters/manager_spec/error.rb +18 -0
- data/spec/support/servers/arachni/browser.rb +117 -11
- data/spec/support/servers/arachni/browser/javascript/dom_monitor.rb +148 -4
- data/spec/support/servers/arachni/check/auditor.rb +4 -0
- data/spec/support/servers/arachni/element/cookie/cookie_dom.rb +1 -1
- data/spec/support/servers/arachni/http/client.rb +5 -0
- data/spec/support/servers/arachni/http/client/dynamic_404_handler.rb +13 -0
- data/spec/support/servers/checks/active/code_injection_timing.rb +1 -1
- data/spec/support/servers/checks/active/file_inclusion.rb +2 -2
- data/spec/support/servers/checks/active/path_traversal.rb +2 -2
- data/spec/support/servers/checks/active/source_code_disclosure.rb +40 -33
- data/spec/support/servers/checks/active/trainer_check.rb +9 -10
- data/spec/support/servers/checks/active/unvalidated_redirect_dom.rb +7 -4
- data/spec/support/servers/checks/active/xss.rb +35 -0
- data/spec/support/servers/checks/active/xss_dom.rb +1 -1
- data/spec/support/servers/checks/active/xss_dom_inputs.rb +24 -0
- data/spec/support/servers/checks/active/xss_dom_script_context.rb +1 -1
- data/spec/support/servers/checks/passive/common_admin_interfaces.rb +6 -0
- data/spec/support/servers/plugins/autologin.rb +9 -0
- data/spec/support/servers/plugins/restrict_to_dom_state.rb +4 -0
- data/spec/support/shared/element/base.rb +42 -0
- data/spec/support/shared/element/capabilities/auditable.rb +4 -4
- data/spec/support/shared/element/capabilities/auditable/dom.rb +26 -0
- data/spec/support/shared/element/capabilities/inputtable.rb +16 -11
- data/spec/support/shared/element/capabilities/submitable.rb +7 -2
- data/spec/support/shared/fingerprinter.rb +8 -0
- data/spec/support/shared/path_extractor.rb +1 -1
- data/ui/cli/framework.rb +3 -3
- data/ui/cli/framework/option_parser.rb +9 -0
- data/ui/cli/output.rb +9 -0
- data/ui/cli/reporter.rb +5 -2
- data/ui/cli/utilities.rb +4 -2
- metadata +76 -17
- data/lib/arachni/http/proxy_server/ssl-interceptor-cert.pem +0 -34
- data/lib/arachni/http/proxy_server/ssl-interceptor-pkey.pem +0 -51
- data/spec/components/fingerprinters/languages/jsp_spec.rb +0 -56
@@ -1342,6 +1342,21 @@ describe Arachni::Browser::Javascript::TaintTracer do
|
|
1342
1342
|
event['srcElement'].should == form
|
1343
1343
|
event['type'].should == 'submit'
|
1344
1344
|
end
|
1345
|
+
|
1346
|
+
it 'is limited to 50' do
|
1347
|
+
load 'debug'
|
1348
|
+
|
1349
|
+
100.times do |i|
|
1350
|
+
@browser.javascript.run( subject.stub.function( :log_execution_flow_sink, i ) )
|
1351
|
+
end
|
1352
|
+
|
1353
|
+
sinks = subject.execution_flow_sinks
|
1354
|
+
sinks.size.should == 50
|
1355
|
+
|
1356
|
+
50.times do |i|
|
1357
|
+
sinks[i].data.should == [50 + i]
|
1358
|
+
end
|
1359
|
+
end
|
1345
1360
|
end
|
1346
1361
|
|
1347
1362
|
describe '#log_data_flow_sink' do
|
@@ -1373,6 +1388,32 @@ describe Arachni::Browser::Javascript::TaintTracer do
|
|
1373
1388
|
event['srcElement'].should == form
|
1374
1389
|
event['type'].should == 'submit'
|
1375
1390
|
end
|
1391
|
+
|
1392
|
+
it 'is limited to 50 per taint' do
|
1393
|
+
load 'debug'
|
1394
|
+
|
1395
|
+
100.times do |i|
|
1396
|
+
@browser.javascript.run(
|
1397
|
+
subject.stub.function(
|
1398
|
+
:log_data_flow_sink,
|
1399
|
+
'taint',
|
1400
|
+
{
|
1401
|
+
function: {
|
1402
|
+
name: "f_#{i}"
|
1403
|
+
}
|
1404
|
+
}
|
1405
|
+
)
|
1406
|
+
)
|
1407
|
+
end
|
1408
|
+
|
1409
|
+
sinks = subject.data_flow_sinks['taint']
|
1410
|
+
sinks.size.should == 50
|
1411
|
+
|
1412
|
+
50.times do |i|
|
1413
|
+
sinks[i].function.name.should == "f_#{i+50}"
|
1414
|
+
end
|
1415
|
+
end
|
1416
|
+
|
1376
1417
|
end
|
1377
1418
|
|
1378
1419
|
describe '#debugging_data' do
|
@@ -18,6 +18,14 @@ describe Arachni::Browser::Javascript do
|
|
18
18
|
|
19
19
|
subject { @browser.javascript }
|
20
20
|
|
21
|
+
describe '.events_for' do
|
22
|
+
it 'returns events for the given element' do
|
23
|
+
described_class::EVENTS_PER_ELEMENT.each do |element, events|
|
24
|
+
described_class.events_for( element ).should == described_class::GLOBAL_EVENTS | events
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
21
29
|
describe '.select_event_attributes' do
|
22
30
|
it 'selects only attributes that are events' do
|
23
31
|
attributes = {
|
@@ -140,25 +148,83 @@ describe Arachni::Browser::Javascript do
|
|
140
148
|
end
|
141
149
|
|
142
150
|
describe '#dom_elements_with_events' do
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
151
|
+
context 'when using event attributes' do
|
152
|
+
it 'returns information about all DOM elements along with their events' do
|
153
|
+
@browser.load @dom_monitor_url + 'elements_with_events/attributes'
|
154
|
+
|
155
|
+
subject.dom_elements_with_events.should == [
|
156
|
+
{
|
157
|
+
'tag_name' => 'body', 'events' => [], 'attributes' => {}
|
158
|
+
},
|
159
|
+
{
|
160
|
+
'tag_name' => 'button',
|
161
|
+
'events' => [
|
162
|
+
[:onclick, 'handler_1()']
|
163
|
+
],
|
164
|
+
'attributes' => { 'onclick' => 'handler_1()', 'id' => 'my-button' }
|
165
|
+
},
|
166
|
+
{
|
167
|
+
'tag_name' => 'button',
|
168
|
+
'events' => [
|
169
|
+
[:onclick, 'handler_2()']
|
170
|
+
],
|
171
|
+
'attributes' => { 'onclick' => 'handler_2()', 'id' => 'my-button2' }
|
172
|
+
},
|
173
|
+
{
|
174
|
+
'tag_name' => 'button',
|
175
|
+
'events' => [
|
176
|
+
[:onclick, 'handler_3()']
|
177
|
+
],
|
178
|
+
'attributes' => { 'onclick' => 'handler_3()', 'id' => 'my-button3' }
|
179
|
+
}
|
180
|
+
]
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context 'when using event listeners' do
|
185
|
+
it 'returns information about all DOM elements along with their events' do
|
186
|
+
@browser.load @dom_monitor_url + 'elements_with_events/listeners'
|
187
|
+
|
188
|
+
subject.dom_elements_with_events.should == [
|
189
|
+
{
|
190
|
+
'tag_name' => 'body', 'events' => [], 'attributes' => {}
|
191
|
+
},
|
192
|
+
{
|
193
|
+
'tag_name' => 'button',
|
194
|
+
'events' => [
|
195
|
+
[:click, 'function (my_button_click) {}'],
|
196
|
+
[:click, 'function (my_button_click2) {}'],
|
197
|
+
[:onmouseover, 'function (my_button_onmouseover) {}']
|
198
|
+
],
|
199
|
+
'attributes' => { 'id' => 'my-button' } },
|
200
|
+
{
|
201
|
+
'tag_name' => 'button',
|
202
|
+
'events' => [
|
203
|
+
[:click, 'function (my_button2_click) {}']
|
204
|
+
],
|
205
|
+
'attributes' => { 'id' => 'my-button2' } },
|
206
|
+
{
|
207
|
+
'tag_name' => 'button',
|
208
|
+
'events' => [],
|
209
|
+
'attributes' => { 'id' => 'my-button3' }
|
210
|
+
}
|
211
|
+
]
|
212
|
+
end
|
213
|
+
|
214
|
+
it 'does not include custom events' do
|
215
|
+
@browser.load @dom_monitor_url + 'elements_with_events/listeners/custom'
|
216
|
+
|
217
|
+
subject.dom_elements_with_events.should == [
|
218
|
+
{
|
219
|
+
'tag_name' => 'body', 'events' => [], 'attributes' => {}
|
220
|
+
},
|
221
|
+
{
|
222
|
+
'tag_name' => 'button',
|
223
|
+
'events' => [],
|
224
|
+
'attributes' => { 'id' => 'my-button' }
|
225
|
+
}
|
226
|
+
]
|
227
|
+
end
|
162
228
|
end
|
163
229
|
end
|
164
230
|
|
@@ -316,71 +382,179 @@ describe Arachni::Browser::Javascript do
|
|
316
382
|
end
|
317
383
|
|
318
384
|
describe '#inject' do
|
319
|
-
|
385
|
+
context 'when the response is' do
|
386
|
+
context 'JavaScript' do
|
387
|
+
let(:response) do
|
388
|
+
Arachni::HTTP::Response.new(
|
389
|
+
url: "#{@dom_monitor_url}/jquery.js",
|
390
|
+
headers: {
|
391
|
+
'Content-Type' => 'text/javascript'
|
392
|
+
},
|
393
|
+
body: <<EOHTML
|
394
|
+
foo()
|
395
|
+
EOHTML
|
396
|
+
)
|
397
|
+
end
|
320
398
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
399
|
+
let(:injected) do
|
400
|
+
r = response.deep_clone
|
401
|
+
subject.inject( r )
|
402
|
+
r
|
403
|
+
end
|
325
404
|
|
326
|
-
|
327
|
-
|
328
|
-
|
405
|
+
let(:taint_tracer_update) do
|
406
|
+
"#{subject.taint_tracer.stub.function( :update_tracers )};"
|
407
|
+
end
|
408
|
+
|
409
|
+
let(:dom_monitor_update) do
|
410
|
+
"#{subject.dom_monitor.stub.function( :update_trackers )};"
|
411
|
+
end
|
329
412
|
|
330
|
-
|
331
|
-
|
413
|
+
it 'inject a TaintTracer.update_tracers() call before the code' do
|
414
|
+
injected.body.scan( /(.*)foo/m ).flatten.first.should include taint_tracer_update
|
415
|
+
end
|
332
416
|
|
333
|
-
|
417
|
+
it 'inject a DOMMonitor.update_trackers() call before the code' do
|
418
|
+
injected.body.scan( /(.*)foo/m ).flatten.first.should include dom_monitor_update
|
419
|
+
end
|
334
420
|
|
335
|
-
|
421
|
+
it 'appends a semicolon and newline to the body' do
|
422
|
+
injected.body.should include "#{response.body};\n"
|
423
|
+
end
|
336
424
|
|
337
|
-
|
338
|
-
|
339
|
-
end
|
425
|
+
it 'updates the Content-Length' do
|
426
|
+
old_content_length = response.headers['content-length'].to_i
|
340
427
|
|
341
|
-
|
342
|
-
|
428
|
+
subject.inject( response )
|
429
|
+
|
430
|
+
new_content_length = response.headers['content-length'].to_i
|
431
|
+
|
432
|
+
new_content_length.should > old_content_length
|
433
|
+
new_content_length.should == response.body.bytesize
|
434
|
+
end
|
343
435
|
end
|
344
436
|
|
345
|
-
context '
|
346
|
-
|
437
|
+
context 'HTML' do
|
438
|
+
let(:response) do
|
439
|
+
Arachni::HTTP::Response.new(
|
440
|
+
url: @dom_monitor_url,
|
441
|
+
headers: {
|
442
|
+
'Content-Type' => 'text/html'
|
443
|
+
},
|
444
|
+
body: <<EOHTML
|
445
|
+
<body>
|
446
|
+
</body>
|
447
|
+
EOHTML
|
448
|
+
)
|
449
|
+
end
|
450
|
+
|
451
|
+
it 'updates the Content-Length' do
|
452
|
+
old_content_length = response.headers['content-length'].to_i
|
347
453
|
|
348
|
-
|
349
|
-
before { subject.taint = 'my_taint' }
|
454
|
+
subject.inject( response )
|
350
455
|
|
351
|
-
|
456
|
+
new_content_length = response.headers['content-length'].to_i
|
457
|
+
|
458
|
+
new_content_length.should > old_content_length
|
459
|
+
new_content_length.should == response.body.bytesize
|
460
|
+
end
|
461
|
+
|
462
|
+
context 'when the response does not already contain the JS code' do
|
463
|
+
it 'injects the system\'s JS interfaces in the response body' do
|
464
|
+
subject.inject( response )
|
465
|
+
|
466
|
+
%w(taint_tracer dom_monitor).each do |name|
|
467
|
+
src = "#{described_class::SCRIPT_BASE_URL}#{name}.js"
|
468
|
+
Nokogiri::HTML( response.body ).xpath( "//script[@src='#{src}']" ).should be_any
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
context 'when the response body contains script elements' do
|
473
|
+
before { response.body = '<script>// My code and stuff</script>' }
|
474
|
+
|
475
|
+
it 'injects taint tracer update calls at the top of the script' do
|
476
|
+
subject.inject( response )
|
477
|
+
Nokogiri::HTML(response.body).css('script')[-2].to_s.should ==
|
478
|
+
"<script>
|
479
|
+
|
480
|
+
// Injected by #{described_class}
|
481
|
+
_#{subject.token}TaintTracer.update_tracers();
|
482
|
+
_#{subject.token}DOMMonitor.update_trackers();
|
483
|
+
|
484
|
+
// My code and stuff</script>"
|
485
|
+
end
|
486
|
+
|
487
|
+
it 'injects taint tracer update calls after the script' do
|
488
|
+
subject.inject( response )
|
489
|
+
Nokogiri::HTML(response.body).css('script')[-1].to_s.should ==
|
490
|
+
"<script type=\"text/javascript\">" +
|
491
|
+
"_#{subject.token}TaintTracer.update_tracers();" +
|
492
|
+
"_#{subject.token}DOMMonitor.update_trackers();" +
|
493
|
+
'</script>'
|
494
|
+
end
|
495
|
+
end
|
496
|
+
end
|
497
|
+
|
498
|
+
context 'when the response already contains the JS code' do
|
499
|
+
it 'updates the taints' do
|
500
|
+
subject.inject( response )
|
501
|
+
|
502
|
+
presponse = response.deep_clone
|
503
|
+
pintializer = subject.taint_tracer.stub.function( :initialize, [] )
|
504
|
+
|
505
|
+
subject.taint = [ 'taint1', 'taint2' ]
|
352
506
|
subject.inject( response )
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
// My code and stuff </script>"
|
507
|
+
intializer = subject.taint_tracer.stub.function( :initialize, subject.taint )
|
508
|
+
|
509
|
+
response.body.should == presponse.body.gsub( pintializer, intializer )
|
357
510
|
end
|
358
511
|
|
359
|
-
it '
|
512
|
+
it 'updates the custom code' do
|
513
|
+
subject.custom_code = 'alert(1);'
|
360
514
|
subject.inject( response )
|
515
|
+
|
516
|
+
presponse = response.deep_clone
|
517
|
+
code = subject.custom_code
|
518
|
+
|
519
|
+
subject.custom_code = 'alert(2);'
|
361
520
|
subject.inject( response )
|
362
|
-
|
363
|
-
|
521
|
+
|
522
|
+
response.body.should == presponse.body.gsub( code, subject.custom_code )
|
364
523
|
end
|
365
524
|
end
|
366
525
|
end
|
367
526
|
end
|
527
|
+
end
|
368
528
|
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
original_response.should_not == response
|
529
|
+
describe '#javascript?' do
|
530
|
+
context 'when the Content-Type includes javascript' do
|
531
|
+
it 'returns true'
|
532
|
+
end
|
374
533
|
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
534
|
+
context 'when the Content-Type does not include javascript' do
|
535
|
+
it 'returns false'
|
536
|
+
end
|
537
|
+
end
|
379
538
|
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
539
|
+
describe '#html?' do
|
540
|
+
context 'when the body is empty' do
|
541
|
+
it 'returns false'
|
542
|
+
end
|
543
|
+
|
544
|
+
context 'when the Content-Type does not include text/html' do
|
545
|
+
it 'returns false'
|
546
|
+
end
|
547
|
+
|
548
|
+
context 'when the body does not include HTML identifiers such as' do
|
549
|
+
it 'returns false'
|
550
|
+
end
|
551
|
+
|
552
|
+
context 'when it matches the last loaded URL' do
|
553
|
+
it 'returns true'
|
554
|
+
end
|
555
|
+
|
556
|
+
context 'when it contains markup' do
|
557
|
+
it 'returns true'
|
384
558
|
end
|
385
559
|
end
|
386
560
|
|
@@ -75,15 +75,6 @@ describe Arachni::BrowserCluster::Jobs::ResourceExploration do
|
|
75
75
|
restored = q.pop
|
76
76
|
restored.should == subject
|
77
77
|
end
|
78
|
-
|
79
|
-
it 'dups the page' do
|
80
|
-
q = Arachni::Support::Database::Queue.new
|
81
|
-
q.max_buffer_size = 0
|
82
|
-
|
83
|
-
expect_any_instance_of(Arachni::Page).to receive(:dup)
|
84
|
-
|
85
|
-
q << subject
|
86
|
-
end
|
87
78
|
end
|
88
79
|
end
|
89
80
|
end
|
@@ -18,6 +18,24 @@ describe Arachni::BrowserCluster do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
describe '#initialize' do
|
21
|
+
it "sets window width to #{Arachni::OptionGroups::BrowserCluster}#screen_width" do
|
22
|
+
Arachni::Options.browser_cluster.screen_width = 100
|
23
|
+
|
24
|
+
@cluster = described_class.new
|
25
|
+
@cluster.workers.each do |browser|
|
26
|
+
browser.javascript.run('return window.innerWidth').should == 100
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
it "sets window height to #{Arachni::OptionGroups::BrowserCluster}#screen_height" do
|
31
|
+
Arachni::Options.browser_cluster.screen_height = 200
|
32
|
+
|
33
|
+
@cluster = described_class.new
|
34
|
+
@cluster.workers.each do |browser|
|
35
|
+
browser.javascript.run('return window.innerHeight').should == 200
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
21
39
|
describe :pool_size do
|
22
40
|
it 'sets the amount of browsers to instantiate' do
|
23
41
|
@cluster = described_class.new( pool_size: 3 )
|
@@ -31,21 +49,51 @@ describe Arachni::BrowserCluster do
|
|
31
49
|
end
|
32
50
|
end
|
33
51
|
|
34
|
-
|
35
|
-
|
52
|
+
describe :on_pop do
|
53
|
+
it 'assigns blocks to be passed each poped job' do
|
54
|
+
cj = nil
|
55
|
+
@cluster = described_class.new(
|
56
|
+
on_pop: proc do |j|
|
57
|
+
cj = j
|
58
|
+
end
|
59
|
+
)
|
36
60
|
|
37
|
-
|
38
|
-
|
39
|
-
|
61
|
+
@cluster.queue( job ){}
|
62
|
+
@cluster.wait
|
63
|
+
|
64
|
+
cj.id.should == job.id
|
40
65
|
end
|
41
66
|
end
|
42
67
|
|
43
|
-
|
44
|
-
|
68
|
+
describe :on_queue do
|
69
|
+
it 'assigns blocks to be passed each queued job' do
|
70
|
+
cj = nil
|
71
|
+
@cluster = described_class.new(
|
72
|
+
on_queue: proc do |j|
|
73
|
+
cj = j
|
74
|
+
end
|
75
|
+
)
|
45
76
|
|
46
|
-
|
47
|
-
|
48
|
-
|
77
|
+
@cluster.queue( job ){}
|
78
|
+
|
79
|
+
cj.id.should == job.id
|
80
|
+
@cluster.wait
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe :on_job_done do
|
85
|
+
it 'assigns blocks to be passed each finished job' do
|
86
|
+
cj = nil
|
87
|
+
@cluster = described_class.new(
|
88
|
+
on_job_done: proc do |j|
|
89
|
+
cj = j
|
90
|
+
end
|
91
|
+
)
|
92
|
+
|
93
|
+
@cluster.queue( job ){}
|
94
|
+
@cluster.wait
|
95
|
+
|
96
|
+
cj.id.should == job.id
|
49
97
|
end
|
50
98
|
end
|
51
99
|
end
|