arachni 1.0.2 → 1.0.3

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