arachni 1.0.5 → 1.0.6
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 +50 -0
- data/README.md +9 -2
- data/components/checks/active/code_injection.rb +5 -5
- data/components/checks/active/code_injection_timing.rb +3 -3
- data/components/checks/active/no_sql_injection_differential.rb +3 -2
- data/components/checks/active/os_cmd_injection.rb +11 -5
- data/components/checks/active/os_cmd_injection_timing.rb +11 -4
- data/components/checks/active/path_traversal.rb +2 -2
- data/components/checks/active/sql_injection.rb +1 -1
- data/components/checks/active/sql_injection/patterns/mssql +1 -0
- data/components/checks/active/sql_injection_differential.rb +3 -2
- data/components/checks/active/unvalidated_redirect.rb +3 -3
- data/components/checks/passive/common_directories/directories.txt +2 -0
- data/components/checks/passive/common_files/filenames.txt +1 -0
- data/lib/arachni/browser.rb +17 -1
- data/lib/arachni/check/auditor.rb +5 -2
- data/lib/arachni/check/base.rb +30 -5
- data/lib/arachni/element/capabilities/analyzable/differential.rb +2 -5
- data/lib/arachni/element/capabilities/auditable.rb +3 -1
- data/lib/arachni/element/capabilities/with_dom.rb +1 -0
- data/lib/arachni/element/capabilities/with_node.rb +1 -1
- data/lib/arachni/element/cookie.rb +2 -2
- data/lib/arachni/element/form.rb +1 -1
- data/lib/arachni/element/header.rb +2 -2
- data/lib/arachni/element/link_template.rb +1 -1
- data/lib/arachni/framework.rb +21 -1144
- data/lib/arachni/framework/parts/audit.rb +282 -0
- data/lib/arachni/framework/parts/browser.rb +132 -0
- data/lib/arachni/framework/parts/check.rb +86 -0
- data/lib/arachni/framework/parts/data.rb +158 -0
- data/lib/arachni/framework/parts/platform.rb +34 -0
- data/lib/arachni/framework/parts/plugin.rb +61 -0
- data/lib/arachni/framework/parts/report.rb +128 -0
- data/lib/arachni/framework/parts/scope.rb +40 -0
- data/lib/arachni/framework/parts/state.rb +457 -0
- data/lib/arachni/http/client.rb +33 -30
- data/lib/arachni/http/request.rb +6 -2
- data/lib/arachni/issue.rb +55 -1
- data/lib/arachni/platform/manager.rb +25 -21
- data/lib/arachni/state/framework.rb +7 -1
- data/lib/arachni/utilities.rb +10 -0
- data/lib/version +1 -1
- data/spec/arachni/browser_spec.rb +13 -0
- data/spec/arachni/check/auditor_spec.rb +1 -0
- data/spec/arachni/check/base_spec.rb +80 -0
- data/spec/arachni/element/cookie_spec.rb +2 -2
- data/spec/arachni/framework/parts/audit_spec.rb +391 -0
- data/spec/arachni/framework/parts/browser_spec.rb +26 -0
- data/spec/arachni/framework/parts/check_spec.rb +24 -0
- data/spec/arachni/framework/parts/data_spec.rb +187 -0
- data/spec/arachni/framework/parts/platform_spec.rb +62 -0
- data/spec/arachni/framework/parts/plugin_spec.rb +41 -0
- data/spec/arachni/framework/parts/report_spec.rb +66 -0
- data/spec/arachni/framework/parts/scope_spec.rb +86 -0
- data/spec/arachni/framework/parts/state_spec.rb +528 -0
- data/spec/arachni/framework_spec.rb +17 -1344
- data/spec/arachni/http/client_spec.rb +12 -7
- data/spec/arachni/issue_spec.rb +35 -0
- data/spec/arachni/platform/manager_spec.rb +2 -3
- data/spec/arachni/state/framework_spec.rb +15 -0
- data/spec/components/checks/active/code_injection_timing_spec.rb +5 -5
- data/spec/components/checks/active/no_sql_injection_differential_spec.rb +4 -0
- data/spec/components/checks/active/os_cmd_injection_spec.rb +20 -7
- data/spec/components/checks/active/os_cmd_injection_timing_spec.rb +5 -5
- data/spec/components/checks/active/sql_injection_differential_spec.rb +4 -0
- data/spec/components/checks/active/sql_injection_spec.rb +2 -3
- data/spec/support/servers/arachni/browser.rb +31 -0
- data/spec/support/servers/checks/active/code_injection.rb +1 -1
- data/spec/support/servers/checks/active/no_sql_injection_differential.rb +36 -34
- data/spec/support/servers/checks/active/os_cmd_injection.rb +6 -12
- data/spec/support/servers/checks/active/os_cmd_injection_timing.rb +9 -4
- data/spec/support/servers/checks/active/sql_injection.rb +1 -1
- data/spec/support/servers/checks/active/sql_injection_differential.rb +37 -34
- data/spec/support/shared/element/capabilities/with_node.rb +25 -0
- data/spec/support/shared/framework.rb +26 -0
- data/ui/cli/output.rb +2 -0
- data/ui/cli/rpc/server/dispatcher/option_parser.rb +1 -1
- metadata +32 -4
- data/components/checks/active/sql_injection/patterns/coldfusion +0 -1
@@ -218,9 +218,9 @@ describe Arachni::Element::Cookie do
|
|
218
218
|
end
|
219
219
|
end
|
220
220
|
|
221
|
-
describe '
|
221
|
+
describe '.encode' do
|
222
222
|
it 'encodes the string in a way that makes is suitable to be included in a cookie header' do
|
223
|
-
described_class.encode( 'some stuff \'"
|
223
|
+
described_class.encode( 'some stuff \'";%=&' ).should == 'some+stuff+%27%22%3B%25=%26'
|
224
224
|
end
|
225
225
|
end
|
226
226
|
|
@@ -0,0 +1,391 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Arachni::Framework::Parts::Audit do
|
4
|
+
include_examples 'framework'
|
5
|
+
|
6
|
+
describe Arachni::OptionGroups::Scope do
|
7
|
+
describe '#exclude_binaries' do
|
8
|
+
it 'excludes binary pages from the scan' do
|
9
|
+
audited = []
|
10
|
+
Arachni::Framework.new do |f|
|
11
|
+
f.options.url = @url
|
12
|
+
f.options.scope.restrict_paths << @url + '/binary'
|
13
|
+
f.options.audit.elements :links, :forms, :cookies
|
14
|
+
f.checks.load :taint
|
15
|
+
|
16
|
+
f.on_page_audit { |p| audited << p.url }
|
17
|
+
f.run
|
18
|
+
end
|
19
|
+
audited.sort.should == [@url + '/binary'].sort
|
20
|
+
|
21
|
+
audited = []
|
22
|
+
Arachni::Framework.new do |f|
|
23
|
+
f.options.url = @url
|
24
|
+
f.options.scope.restrict_paths << @url + '/binary'
|
25
|
+
f.options.scope.exclude_binaries = true
|
26
|
+
f.checks.load :taint
|
27
|
+
|
28
|
+
f.on_page_audit { |p| audited << p.url }
|
29
|
+
f.run
|
30
|
+
end
|
31
|
+
audited.should be_empty
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#extend_paths' do
|
36
|
+
it 'extends the crawl scope' do
|
37
|
+
Arachni::Framework.new do |f|
|
38
|
+
f.options.url = "#{@url}/elem_combo"
|
39
|
+
f.options.scope.extend_paths = %w(/some/stuff /more/stuff)
|
40
|
+
f.options.audit.elements :links, :forms, :cookies
|
41
|
+
f.checks.load :taint
|
42
|
+
|
43
|
+
f.run
|
44
|
+
|
45
|
+
f.report.sitemap.should include "#{@url}/some/stuff"
|
46
|
+
f.report.sitemap.should include "#{@url}/more/stuff"
|
47
|
+
f.report.sitemap.size.should > 3
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#restrict_paths' do
|
53
|
+
it 'serves as a replacement to crawling' do
|
54
|
+
Arachni::Framework.new do |f|
|
55
|
+
f.options.url = "#{@url}/elem_combo"
|
56
|
+
f.options.scope.restrict_paths = %w(/log_remote_file_if_exists/true)
|
57
|
+
f.options.audit.elements :links, :forms, :cookies
|
58
|
+
f.checks.load :taint
|
59
|
+
|
60
|
+
f.run
|
61
|
+
|
62
|
+
sitemap = f.report.sitemap.map { |u, _| u.split( '?' ).first }
|
63
|
+
sitemap.sort.uniq.should == f.options.scope.restrict_paths.
|
64
|
+
map { |p| f.to_absolute( p ) }.sort
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'when unable to get a response for the given URL' do
|
71
|
+
context 'due to a network error' do
|
72
|
+
it 'returns an empty sitemap and have failures' do
|
73
|
+
@options.url = 'http://blahaha'
|
74
|
+
@options.scope.restrict_paths = [@options.url]
|
75
|
+
|
76
|
+
subject.checks.load :taint
|
77
|
+
subject.run
|
78
|
+
subject.failures.should be_any
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'due to a server error' do
|
83
|
+
it 'returns an empty sitemap and have failures' do
|
84
|
+
@options.url = @f_url + '/fail'
|
85
|
+
@options.scope.restrict_paths = [@options.url]
|
86
|
+
|
87
|
+
subject.checks.load :taint
|
88
|
+
subject.run
|
89
|
+
subject.failures.should be_any
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
it "retries #{Arachni::Framework::AUDIT_PAGE_MAX_TRIES} times" do
|
94
|
+
@options.url = @f_url + '/fail_4_times'
|
95
|
+
@options.scope.restrict_paths = [@options.url]
|
96
|
+
|
97
|
+
subject.checks.load :taint
|
98
|
+
subject.run
|
99
|
+
subject.failures.should be_empty
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
describe '#http' do
|
104
|
+
it 'provides access to the HTTP interface' do
|
105
|
+
subject.http.is_a?( Arachni::HTTP::Client ).should be_true
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe '#failures' do
|
110
|
+
context 'when there are no failed requests' do
|
111
|
+
it 'returns an empty array' do
|
112
|
+
@options.url = @f_url
|
113
|
+
@options.scope.restrict_paths = [@options.url]
|
114
|
+
|
115
|
+
subject.checks.load :taint
|
116
|
+
subject.run
|
117
|
+
subject.failures.should be_empty
|
118
|
+
end
|
119
|
+
end
|
120
|
+
context 'when there are failed requests' do
|
121
|
+
it 'returns an array containing the failed URLs' do
|
122
|
+
@options.url = @f_url + '/fail'
|
123
|
+
@options.scope.restrict_paths = [@options.url]
|
124
|
+
|
125
|
+
subject.checks.load :taint
|
126
|
+
subject.run
|
127
|
+
subject.failures.should be_any
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe '#on_page_audit' do
|
133
|
+
it 'calls the given block before each page is audited' do
|
134
|
+
ok = false
|
135
|
+
Arachni::Framework.new do |f|
|
136
|
+
f.options.url = @url
|
137
|
+
f.on_page_audit { ok = true }
|
138
|
+
|
139
|
+
f.audit_page Arachni::Page.from_url( @url + '/link' )
|
140
|
+
end
|
141
|
+
ok.should be_true
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe '#after_page_audit' do
|
146
|
+
it 'calls the given block before each page is audited' do
|
147
|
+
ok = false
|
148
|
+
Arachni::Framework.new do |f|
|
149
|
+
f.options.url = @url
|
150
|
+
f.after_page_audit { ok = true }
|
151
|
+
|
152
|
+
f.audit_page Arachni::Page.from_url( @url + '/link' )
|
153
|
+
end
|
154
|
+
ok.should be_true
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe '#audit_page' do
|
159
|
+
it 'updates the #sitemap with the DOM URL' do
|
160
|
+
subject.options.audit.elements :links, :forms, :cookies
|
161
|
+
subject.checks.load :taint
|
162
|
+
|
163
|
+
subject.sitemap.should be_empty
|
164
|
+
|
165
|
+
page = Arachni::Page.from_url( @url + '/link' )
|
166
|
+
page.dom.url = @url + '/link/#/stuff'
|
167
|
+
|
168
|
+
subject.audit_page page
|
169
|
+
subject.sitemap.should include @url + '/link/#/stuff'
|
170
|
+
end
|
171
|
+
|
172
|
+
it "runs #{Arachni::Check::Manager}#without_platforms before #{Arachni::Check::Manager}#with_platforms" do
|
173
|
+
@options.paths.checks = fixtures_path + '/checks/'
|
174
|
+
|
175
|
+
Arachni::Framework.new do |f|
|
176
|
+
f.checks.load_all
|
177
|
+
|
178
|
+
page = Arachni::Page.from_url( @url + '/link' )
|
179
|
+
|
180
|
+
responses = []
|
181
|
+
f.http.on_complete do |response|
|
182
|
+
responses << response.url
|
183
|
+
end
|
184
|
+
|
185
|
+
f.audit_page page
|
186
|
+
|
187
|
+
responses.sort.should ==
|
188
|
+
%w(http://localhost/test3 http://localhost/test
|
189
|
+
http://localhost/test2).sort
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context 'when checks were' do
|
194
|
+
context 'ran against the page' do
|
195
|
+
it 'returns true' do
|
196
|
+
subject.checks.load :taint
|
197
|
+
subject.audit_page( Arachni::Page.from_url( @url + '/link' ) ).should be_true
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
context 'not ran against the page' do
|
202
|
+
it 'returns false' do
|
203
|
+
subject.audit_page( Arachni::Page.from_url( @url + '/link' ) ).should be_false
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
context 'when the page contains JavaScript code' do
|
209
|
+
it 'analyzes the DOM and pushes new pages to the page queue' do
|
210
|
+
Arachni::Framework.new do |f|
|
211
|
+
f.options.audit.elements :links, :forms, :cookies
|
212
|
+
f.checks.load :taint
|
213
|
+
|
214
|
+
f.page_queue_total_size.should == 0
|
215
|
+
|
216
|
+
f.audit_page( Arachni::Page.from_url( @url + '/with_javascript' ) )
|
217
|
+
|
218
|
+
sleep 0.1 while f.wait_for_browser?
|
219
|
+
|
220
|
+
f.page_queue_total_size.should > 0
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'analyzes the DOM and pushes new paths to the url queue' do
|
225
|
+
Arachni::Framework.new do |f|
|
226
|
+
f.options.url = @url
|
227
|
+
f.options.audit.elements :links, :forms, :cookies
|
228
|
+
f.checks.load :taint
|
229
|
+
|
230
|
+
f.url_queue_total_size.should == 0
|
231
|
+
|
232
|
+
f.audit_page( Arachni::Page.from_url( @url + '/with_javascript' ) )
|
233
|
+
|
234
|
+
sleep 0.1 while f.wait_for_browser?
|
235
|
+
|
236
|
+
f.url_queue_total_size.should == 2
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
context 'when the DOM depth limit has been reached' do
|
241
|
+
it 'does not analyze the DOM' do
|
242
|
+
Arachni::Framework.new do |f|
|
243
|
+
f.options.url = @url
|
244
|
+
|
245
|
+
f.options.audit.elements :links, :forms, :cookies
|
246
|
+
f.checks.load :taint
|
247
|
+
f.options.scope.dom_depth_limit = 1
|
248
|
+
f.url_queue_total_size.should == 0
|
249
|
+
f.audit_page( Arachni::Page.from_url( @url + '/with_javascript' ) ).should be_true
|
250
|
+
sleep 0.1 while f.wait_for_browser?
|
251
|
+
f.url_queue_total_size.should == 2
|
252
|
+
|
253
|
+
f.reset
|
254
|
+
|
255
|
+
f.options.audit.elements :links, :forms, :cookies
|
256
|
+
f.checks.load :taint
|
257
|
+
f.options.scope.dom_depth_limit = 1
|
258
|
+
f.url_queue_total_size.should == 0
|
259
|
+
|
260
|
+
page = Arachni::Page.from_url( @url + '/with_javascript' )
|
261
|
+
page.dom.push_transition Arachni::Page::DOM::Transition.new( :page, :load )
|
262
|
+
|
263
|
+
f.audit_page( page ).should be_true
|
264
|
+
sleep 0.1 while f.wait_for_browser?
|
265
|
+
f.url_queue_total_size.should == 0
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
it 'returns false' do
|
270
|
+
page = Arachni::Page.from_data(
|
271
|
+
url: @url,
|
272
|
+
dom: {
|
273
|
+
transitions: [
|
274
|
+
{ page: :load },
|
275
|
+
{ "<a href='javascript:click();'>" => :click },
|
276
|
+
{ "<button dblclick='javascript:doubleClick();'>" => :ondblclick }
|
277
|
+
].map { |t| Arachni::Page::DOM::Transition.new *t.first }
|
278
|
+
}
|
279
|
+
)
|
280
|
+
|
281
|
+
Arachni::Framework.new do |f|
|
282
|
+
f.checks.load :taint
|
283
|
+
|
284
|
+
f.options.scope.dom_depth_limit = 10
|
285
|
+
f.audit_page( page ).should be_true
|
286
|
+
|
287
|
+
f.options.scope.dom_depth_limit = 2
|
288
|
+
f.audit_page( page ).should be_false
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
context 'when the page matches exclusion criteria' do
|
295
|
+
it 'does not audit it' do
|
296
|
+
subject.options.scope.exclude_path_patterns << /link/
|
297
|
+
subject.options.audit.elements :links, :forms, :cookies
|
298
|
+
|
299
|
+
subject.checks.load :taint
|
300
|
+
|
301
|
+
subject.audit_page( Arachni::Page.from_url( @url + '/link' ) )
|
302
|
+
subject.report.issues.size.should == 0
|
303
|
+
end
|
304
|
+
|
305
|
+
it 'returns false' do
|
306
|
+
subject.options.scope.exclude_path_patterns << /link/
|
307
|
+
subject.audit_page( Arachni::Page.from_url( @url + '/link' ) ).should be_false
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
context "when #{Arachni::Options}#platforms" do
|
312
|
+
context 'have been provided' do
|
313
|
+
context 'and are supported by the check' do
|
314
|
+
it 'audits it' do
|
315
|
+
subject.options.platforms = [:unix]
|
316
|
+
subject.options.audit.elements :links, :forms, :cookies
|
317
|
+
|
318
|
+
subject.checks.load :taint
|
319
|
+
subject.checks[:taint].platforms << :unix
|
320
|
+
|
321
|
+
subject.audit_page( Arachni::Page.from_url( @url + '/link' ) )
|
322
|
+
subject.report.issues.should be_any
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
context 'and are not supported by the check' do
|
327
|
+
it 'does not audit it' do
|
328
|
+
subject.options.platforms = [:windows]
|
329
|
+
subject.options.audit.elements :links, :forms, :cookies
|
330
|
+
|
331
|
+
subject.checks.load :taint
|
332
|
+
subject.checks[:taint].platforms << :unix
|
333
|
+
|
334
|
+
subject.audit_page( Arachni::Page.from_url( @url + '/link' ) )
|
335
|
+
subject.report.issues.should be_empty
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
context 'have not been provided' do
|
341
|
+
it 'audits it' do
|
342
|
+
subject.options.platforms = []
|
343
|
+
subject.options.audit.elements :links, :forms, :cookies
|
344
|
+
|
345
|
+
subject.checks.load :taint
|
346
|
+
subject.checks[:taint].platforms << :unix
|
347
|
+
|
348
|
+
subject.audit_page( Arachni::Page.from_url( @url + '/link' ) )
|
349
|
+
subject.report.issues.should be_any
|
350
|
+
end
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
context "when #{Arachni::Check::Auditor}.has_timeout_candidates?" do
|
355
|
+
it "calls #{Arachni::Check::Auditor}.timeout_audit_run" do
|
356
|
+
Arachni::Check::Auditor.stub(:has_timeout_candidates?){ true }
|
357
|
+
|
358
|
+
Arachni::Check::Auditor.should receive(:timeout_audit_run)
|
359
|
+
subject.audit_page( Arachni::Page.from_url( @url + '/link' ) )
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
context 'when the page contains elements seen in previous pages' do
|
364
|
+
it 'removes them from the page'
|
365
|
+
end
|
366
|
+
|
367
|
+
context 'when a check fails with an exception' do
|
368
|
+
it 'moves to the next one' do
|
369
|
+
@options.paths.checks = fixtures_path + '/checks/'
|
370
|
+
|
371
|
+
Arachni::Framework.new do |f|
|
372
|
+
f.checks.load_all
|
373
|
+
|
374
|
+
f.checks[:test].any_instance.stub(:run) { raise }
|
375
|
+
|
376
|
+
page = Arachni::Page.from_url( @url + '/link' )
|
377
|
+
|
378
|
+
responses = []
|
379
|
+
f.http.on_complete do |response|
|
380
|
+
responses << response.url
|
381
|
+
end
|
382
|
+
|
383
|
+
f.audit_page page
|
384
|
+
|
385
|
+
responses.should == %w(http://localhost/test3 http://localhost/test2)
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Arachni::Framework::Parts::Browser do
|
4
|
+
include_examples 'framework'
|
5
|
+
|
6
|
+
describe '#browser_cluster' do
|
7
|
+
it "returns #{Arachni::BrowserCluster}" do
|
8
|
+
subject.browser_cluster.should be_kind_of Arachni::BrowserCluster
|
9
|
+
end
|
10
|
+
|
11
|
+
context "when #{Arachni::OptionGroups::BrowserCluster}#pool_size" do
|
12
|
+
it 'returns nil' do
|
13
|
+
subject.options.browser_cluster.pool_size = 0
|
14
|
+
subject.browser_cluster.should be_nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "when #{Arachni::OptionGroups::Scope}#dom_depth_limit" do
|
19
|
+
it 'returns nil' do
|
20
|
+
subject.options.scope.dom_depth_limit = 0
|
21
|
+
subject.browser_cluster.should be_nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Arachni::Framework::Parts::Check do
|
4
|
+
include_examples 'framework'
|
5
|
+
|
6
|
+
describe '#checks' do
|
7
|
+
it 'provides access to the check manager' do
|
8
|
+
subject.checks.is_a?( Arachni::Check::Manager ).should be_true
|
9
|
+
subject.checks.available.should == %w(taint)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#list_checks' do
|
14
|
+
context 'when a pattern is given' do
|
15
|
+
it 'uses it to filter out checks that do not match it' do
|
16
|
+
subject.list_checks( 'boo' ).size == 0
|
17
|
+
|
18
|
+
subject.list_checks( 'taint' ).should == subject.list_checks
|
19
|
+
subject.list_checks.size == 1
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|