arachni 1.0.2 → 1.0.3

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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +57 -0
  3. data/README.md +1 -9
  4. data/bin/arachni_script +1 -1
  5. data/components/checks/active/xss_dom_script_context.rb +1 -1
  6. data/components/checks/active/xss_event.rb +1 -1
  7. data/components/checks/active/xss_script_context.rb +1 -1
  8. data/components/plugins/autologin.rb +2 -2
  9. data/components/plugins/content_types.rb +4 -5
  10. data/components/plugins/cookie_collector.rb +6 -3
  11. data/components/plugins/uncommon_headers.rb +6 -2
  12. data/lib/arachni/browser.rb +26 -2
  13. data/lib/arachni/browser/element_locator.rb +9 -2
  14. data/lib/arachni/browser/javascript.rb +6 -0
  15. data/lib/arachni/browser/javascript/scripts/dom_monitor.js +39 -0
  16. data/lib/arachni/browser_cluster.rb +11 -25
  17. data/lib/arachni/element/capabilities/analyzable/differential.rb +4 -0
  18. data/lib/arachni/element/capabilities/analyzable/timeout.rb +4 -0
  19. data/lib/arachni/element/capabilities/auditable/dom.rb +1 -0
  20. data/lib/arachni/element/capabilities/mutable.rb +0 -9
  21. data/lib/arachni/element/capabilities/with_auditor/output.rb +2 -0
  22. data/lib/arachni/element/cookie.rb +9 -4
  23. data/lib/arachni/element/form.rb +6 -6
  24. data/lib/arachni/element/header.rb +1 -1
  25. data/lib/arachni/framework.rb +1 -0
  26. data/lib/arachni/http/client.rb +1 -0
  27. data/lib/arachni/option_groups.rb +3 -0
  28. data/lib/arachni/option_groups/paths.rb +63 -6
  29. data/lib/arachni/option_groups/snapshot.rb +4 -0
  30. data/lib/arachni/session.rb +73 -17
  31. data/lib/arachni/state/audit.rb +2 -0
  32. data/lib/version +1 -1
  33. data/spec/arachni/browser/javascript_spec.rb +20 -0
  34. data/spec/arachni/browser_spec.rb +51 -0
  35. data/spec/arachni/element/cookie_spec.rb +22 -1
  36. data/spec/arachni/element/form_spec.rb +19 -9
  37. data/spec/arachni/framework_spec.rb +17 -0
  38. data/spec/arachni/option_groups/paths_spec.rb +109 -8
  39. data/spec/arachni/option_groups/snapshot_spec.rb +17 -0
  40. data/spec/arachni/session_spec.rb +54 -26
  41. data/spec/components/plugins/autologin_spec.rb +59 -0
  42. data/spec/spec_helper.rb +1 -3
  43. data/spec/support/factories/element/body.rb +3 -0
  44. data/spec/support/factories/element/generic_dom.rb +6 -0
  45. data/spec/support/factories/element/path.rb +3 -0
  46. data/spec/support/factories/element/server.rb +3 -0
  47. data/spec/support/factories/page/dom/transition.rb +21 -0
  48. data/spec/support/helpers/resets.rb +1 -0
  49. data/spec/support/servers/arachni/browser/javascript/dom_monitor.rb +15 -0
  50. data/ui/cli/framework.rb +5 -0
  51. data/ui/cli/framework/option_parser.rb +1 -1
  52. data/ui/cli/option_parser.rb +3 -0
  53. data/ui/cli/output.rb +45 -19
  54. metadata +10 -2
@@ -7,6 +7,11 @@ describe name_from_filename do
7
7
  options.url = url
8
8
  end
9
9
 
10
+ before :each do
11
+ options.session.check_url = nil
12
+ options.session.check_pattern = nil
13
+ end
14
+
10
15
  context 'when given the right params' do
11
16
  it 'locates the form and login successfully' do
12
17
  options.plugins[component_name] = {
@@ -93,4 +98,58 @@ describe name_from_filename do
93
98
  framework.status.should == :aborted
94
99
  end
95
100
  end
101
+
102
+ context "when #{Arachni::OptionGroups::Session}#check_url is" do
103
+ before do
104
+ options.plugins[component_name] = {
105
+ 'url' => url + '/login',
106
+ 'parameters' => 'username=john&password=doe',
107
+ 'check' => 'Hi there logged-in user'
108
+ }
109
+ end
110
+
111
+ context 'nil' do
112
+ it 'sets it to the login response URL' do
113
+ framework.options.session.check_url = nil
114
+ run
115
+ framework.options.session.check_url.should == url
116
+ end
117
+ end
118
+
119
+ context 'is set' do
120
+ it 'does not change it' do
121
+ option_url = url + '/stuff'
122
+ framework.options.session.check_url = option_url
123
+ run
124
+ framework.options.session.check_url.should == option_url
125
+ end
126
+ end
127
+ end
128
+
129
+ context "when #{Arachni::OptionGroups::Session}#check_pattern is" do
130
+ before do
131
+ options.plugins[component_name] = {
132
+ 'url' => url + '/login',
133
+ 'parameters' => 'username=john&password=doe',
134
+ 'check' => 'Hi there logged-in user'
135
+ }
136
+ end
137
+
138
+ context 'nil' do
139
+ it 'sets it to the plugin pattern' do
140
+ framework.options.session.check_pattern = nil
141
+ run
142
+ framework.options.session.check_pattern.should == /Hi there logged-in user/
143
+ end
144
+ end
145
+
146
+ context 'is set' do
147
+ it 'does not change it' do
148
+ framework.options.session.check_pattern = /stuff/
149
+ run
150
+ framework.options.session.check_pattern.should == /stuff/
151
+ end
152
+ end
153
+ end
154
+
96
155
  end
@@ -9,10 +9,8 @@
9
9
  require 'simplecov'
10
10
  require 'faker'
11
11
 
12
- # Uncomment to show output from the Framework.
13
- require_relative '../ui/cli/output'
14
-
15
12
  require_relative '../lib/arachni'
13
+ require_relative '../ui/cli/output'
16
14
  require_relative '../lib/arachni/processes'
17
15
  require_relative '../lib/arachni/processes/helpers'
18
16
 
@@ -0,0 +1,3 @@
1
+ Factory.define :body do
2
+ Arachni::Element::Body.new 'http://test.com/'
3
+ end
@@ -0,0 +1,6 @@
1
+ Factory.define :genericdom do
2
+ Arachni::Element::GenericDOM.new(
3
+ url: Factory[:dom].url,
4
+ transition: Factory[:input_transition]
5
+ )
6
+ end
@@ -0,0 +1,3 @@
1
+ Factory.define :path do
2
+ Arachni::Element::Path.new 'http://test.com/'
3
+ end
@@ -0,0 +1,3 @@
1
+ Factory.define :server do
2
+ Arachni::Element::Server.new 'http://test.com/'
3
+ end
@@ -19,3 +19,24 @@ end
19
19
  Factory.define :empty_transition do
20
20
  Arachni::Page::DOM::Transition.new
21
21
  end
22
+
23
+ Factory.define :empty_transition do
24
+ Arachni::Page::DOM::Transition.new
25
+ end
26
+
27
+ Factory.define :input_transition do
28
+ Arachni::Page::DOM::Transition.new(
29
+ Arachni::Browser::ElementLocator.new(
30
+ tag_name: :input,
31
+ attributes: {
32
+ "oninput" => "handleoninput();",
33
+ "id" => "my-input",
34
+ "name" => "my-input"
35
+ }
36
+ ),
37
+ :input,
38
+ options: {
39
+ value: "<some_dangerous_input_a9838b473d1f6db80b6342d1c61f9fa2></some_dangerous_input_a9838b473d1f6db80b6342d1c61f9fa2> "
40
+ }
41
+ )
42
+ end
@@ -21,6 +21,7 @@ def reset_options
21
21
  end
22
22
 
23
23
  def reset_all
24
+ Arachni::UI::Output.reset_output_options
24
25
  Arachni::Framework.reset
25
26
  reset_options
26
27
  Arachni::HTTP::Client.reset
@@ -88,3 +88,18 @@ get '/elements_with_events/with-hidden' do
88
88
  </script>
89
89
  HTML
90
90
  end
91
+
92
+ get '/set_element_ids' do
93
+ <<HTML
94
+ <a name="1" href="by-ajax" id="by-ajax">Stuff 1</a>
95
+ <a name="2" href="">Stuff 2</a>
96
+
97
+ <a name="3" href="by-ajax" id="by-ajax-1">Stuff 3</a>
98
+ <a name="4" href="">Stuff 4</a>
99
+
100
+ <script>
101
+ document.getElementsByTagName( "a" )[0].addEventListener( "click", function(){}, false )
102
+ document.getElementsByTagName( "a" )[1].addEventListener( "click", function(){}, false )
103
+ </script>
104
+ HTML
105
+ end
@@ -95,6 +95,10 @@ class Framework
95
95
  generate_reports
96
96
  end
97
97
 
98
+ if has_error_log?
99
+ print_info "The scan has logged errors: #{error_logfile}"
100
+ end
101
+
98
102
  print_statistics
99
103
  rescue Component::Options::Error::Invalid => e
100
104
  print_error e
@@ -367,6 +371,7 @@ class Framework
367
371
  filepath = report.save( options.datastore.report_path )
368
372
  filesize = (File.size( filepath ).to_f / 2**20).round(2)
369
373
 
374
+ print_line
370
375
  print_info "Report saved at: #{filepath} [#{filesize}MB]"
371
376
  end
372
377
 
@@ -608,7 +608,7 @@ class OptionParser < UI::CLI::OptionParser
608
608
  def validate_session
609
609
  if (!options.session.check_url && options.session.check_pattern) ||
610
610
  (options.session.check_url && !options.session.check_pattern)
611
- print_bad "Both '--login-check-url' and '--login-check-pattern'" <<
611
+ print_bad "Both '--session-check-url' and '--session-check-pattern'" <<
612
612
  ' options are required.'
613
613
  exit 1
614
614
  end
@@ -21,6 +21,9 @@ class OptionParser
21
21
  separator ''
22
22
  separator 'Generic'
23
23
 
24
+ # This is CLI-related only and not a system option so we set the default here.
25
+ options.datastore.report_path = options.paths.config['cli']['report_path']
26
+
24
27
  on( '-h', '--help', 'Output this message.' ) do
25
28
  puts parser
26
29
  exit
@@ -39,9 +39,16 @@ module Output
39
39
  @@only_positives = false
40
40
  @@reroute_to_file = false
41
41
 
42
- @@opened = false
42
+ @@error_log_written_env = false
43
43
 
44
- @@error_logfile = 'error.log'
44
+ @@error_fd ||= nil
45
+ begin
46
+ @@error_fd.close if @@error_fd
47
+ rescue IOError
48
+ end
49
+ @@error_fd = nil
50
+
51
+ @@error_logfile = "#{Options.paths.logs}error-#{Process.pid}.log"
45
52
  end
46
53
 
47
54
  reset_output_options
@@ -58,6 +65,26 @@ module Output
58
65
  @@error_logfile
59
66
  end
60
67
 
68
+ def has_error_log?
69
+ File.exist? error_logfile
70
+ end
71
+
72
+ def error_log_fd
73
+ return @@error_fd if @@error_fd
74
+
75
+ @@error_fd = File.open( error_logfile, 'a' )
76
+ @@error_fd.sync = true
77
+
78
+ Kernel.at_exit do
79
+ begin
80
+ @@error_fd.close if @@error_fd
81
+ rescue IOError
82
+ end
83
+ end
84
+
85
+ @@error_fd
86
+ end
87
+
61
88
  # Prints and logs an error message.
62
89
  #
63
90
  # @param [String] str
@@ -82,30 +109,29 @@ module Output
82
109
  #
83
110
  # @param [String] str
84
111
  def log_error( str = '' )
85
- File.open( @@error_logfile, 'a' ) do |f|
86
- if !@@opened
87
- f.puts
88
- f.puts "#{Time.now} " + ( "-" * 80 )
112
+ if !@@error_log_written_env
113
+ @@error_log_written_env = true
89
114
 
90
- begin
91
- h = {}
92
- ENV.each { |k, v| h[k] = v }
93
- f.puts 'ENV:'
94
- f.puts h.to_yaml
115
+ error_log_fd.puts
116
+ error_log_fd.puts "#{Time.now} " + ( '-' * 80 )
95
117
 
96
- f.puts "-" * 80
118
+ begin
119
+ h = {}
120
+ ENV.each { |k, v| h[k] = v }
121
+ error_log_fd.puts 'ENV:'
122
+ error_log_fd.puts h.to_yaml
97
123
 
98
- f.puts 'OPTIONS:'
99
- f.puts Arachni::Options.instance.to_yaml
100
- rescue
101
- end
124
+ error_log_fd.puts '-' * 80
102
125
 
103
- f.puts "-" * 80
126
+ error_log_fd.puts 'OPTIONS:'
127
+ error_log_fd.puts Arachni::Options.to_save_data
128
+ rescue
104
129
  end
105
- print_color( "[#{Time.now}]", 31, str, f, true )
130
+
131
+ error_log_fd.puts '-' * 80
106
132
  end
107
133
 
108
- @@opened = true
134
+ print_color( "[#{Time.now}]", 31, str, error_log_fd, true )
109
135
  end
110
136
 
111
137
  # Used to draw attention to a bad situation which isn't an error.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arachni
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tasos Laskos
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-13 00:00:00.000000000 Z
11
+ date: 2014-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -1058,11 +1058,15 @@ files:
1058
1058
  - spec/support/factories/browser/javascript/taint_tracer/sink/data_flow.rb
1059
1059
  - spec/support/factories/browser/javascript/taint_tracer/sink/execution_flow.rb
1060
1060
  - spec/support/factories/browser_cluster/job.rb
1061
+ - spec/support/factories/element/body.rb
1061
1062
  - spec/support/factories/element/cookie.rb
1062
1063
  - spec/support/factories/element/form.rb
1064
+ - spec/support/factories/element/generic_dom.rb
1063
1065
  - spec/support/factories/element/header.rb
1064
1066
  - spec/support/factories/element/link.rb
1065
1067
  - spec/support/factories/element/link_template.rb
1068
+ - spec/support/factories/element/path.rb
1069
+ - spec/support/factories/element/server.rb
1066
1070
  - spec/support/factories/http/request.rb
1067
1071
  - spec/support/factories/http/response.rb
1068
1072
  - spec/support/factories/issue.rb
@@ -1557,11 +1561,15 @@ test_files:
1557
1561
  - spec/support/factories/scan_report.rb
1558
1562
  - spec/support/factories/page/dom.rb
1559
1563
  - spec/support/factories/page/dom/transition.rb
1564
+ - spec/support/factories/element/body.rb
1560
1565
  - spec/support/factories/element/form.rb
1561
1566
  - spec/support/factories/element/cookie.rb
1567
+ - spec/support/factories/element/path.rb
1562
1568
  - spec/support/factories/element/link_template.rb
1563
1569
  - spec/support/factories/element/link.rb
1570
+ - spec/support/factories/element/generic_dom.rb
1564
1571
  - spec/support/factories/element/header.rb
1572
+ - spec/support/factories/element/server.rb
1565
1573
  - spec/support/factories/page.rb
1566
1574
  - spec/support/factories/http/request.rb
1567
1575
  - spec/support/factories/http/response.rb