spec/shared/element/capabilities/auditable.rb in arachni-0.4.1.3 vs spec/shared/element/capabilities/auditable.rb in arachni-0.4.2
- old
+ new
@@ -29,10 +29,20 @@
@seed = 'my_seed'
@default_input_value = @auditable.auditable['param']
end
+ describe '#use_anonymous_auditor' do
+ it 'uses an anonymous auditor' do
+ elem = auditable.new( @url, 'param' => 'val' )
+ elem.auditor.should be_nil
+ elem.use_anonymous_auditor
+ elem.auditor.should be_true
+ elem.auditor.fancy_name.should be_true
+ end
+ end
+
describe '#has_inputs?' do
before do
@has_inputs = auditable.new( @url, { 'param' => 'val', 'param2' => 'val2' } )
@keys = @has_inputs.auditable.keys
@sym_keys = @keys.map( &:to_sym )
@@ -41,48 +51,48 @@
@non_existent_sym_keys = @sym_keys.map { |k| "#{k}1".to_sym }
end
context 'when the given inputs are' do
context 'Variable arguments' do
context 'when it has the given inputs' do
- it 'should return true' do
+ it 'returns true' do
@keys.each do |k|
@has_inputs.has_inputs?( k.to_s.to_sym ).should be_true
@has_inputs.has_inputs?( k.to_s ).should be_true
end
@has_inputs.has_inputs?( *@sym_keys ).should be_true
@has_inputs.has_inputs?( *@keys ).should be_true
end
end
context 'when it does not have the given inputs' do
- it 'should return false' do
+ it 'returns false' do
@has_inputs.has_inputs?( *@non_existent_sym_keys ).should be_false
@has_inputs.has_inputs?( *@non_existent_keys ).should be_false
@has_inputs.has_inputs?( @non_existent_keys.first ).should be_false
end
end
end
context Array do
context 'when it has the given inputs' do
- it 'should return true' do
+ it 'returns true' do
@has_inputs.has_inputs?( @sym_keys ).should be_true
@has_inputs.has_inputs?( @keys ).should be_true
end
end
context 'when it does not have the given inputs' do
- it 'should return false' do
+ it 'returns false' do
@has_inputs.has_inputs?( @non_existent_sym_keys ).should be_false
@has_inputs.has_inputs?( @non_existent_keys ).should be_false
end
end
end
context Hash do
context 'when it has the given inputs (names and values)' do
- it 'should return true' do
+ it 'returns true' do
hash = @has_inputs.auditable.
inject( {} ) { |h, (k, v)| h[k] = v; h}
hash_sym = @has_inputs.auditable.
inject( {} ) { |h, (k, v)| h[k.to_sym] = v; h}
@@ -90,11 +100,11 @@
@has_inputs.has_inputs?( hash_sym ).should be_true
@has_inputs.has_inputs?( hash ).should be_true
end
end
context 'when it does not have the given inputs' do
- it 'should return false' do
+ it 'returns false' do
hash = @has_inputs.auditable.
inject( {} ) { |h, (k, v)| h[k] = "#{v}1"; h}
hash_sym = @has_inputs.auditable.
inject( {} ) { |h, (k, v)| h[k.to_sym] = "#{v}1"; h}
@@ -106,11 +116,11 @@
end
end
end
describe '#auditable' do
- it 'should return a frozen hash of auditable inputs' do
+ it 'returns a frozen hash of auditable inputs' do
@auditable.auditable.should == { 'param' => 'val' }
raised = false
begin
@auditable.auditable['stuff'] = true
@@ -123,27 +133,27 @@
raised.should be_true
end
end
describe '#auditable=' do
- it 'should assign a hash of auditable inputs' do
+ it 'assigns a hash of auditable inputs' do
@auditable.auditable.should == { 'param' => 'val' }
a = @auditable.dup
a.auditable = { 'param1' => 'val1' }
a.auditable.should == { 'param1' => 'val1' }
a.should_not == @auditable
end
- it 'should convert all inputs to strings' do
+ it 'converts all inputs to strings' do
e = auditable.new( @url, { 'key' => nil } )
e.auditable.should == { 'key' => '' }
end
end
describe '#update' do
- it 'should update the auditable inputs using the given hash and return self' do
+ it 'updates the auditable inputs using the given hash and return self' do
a = @auditable.dup
updates = if opts[:single_input]
{ 'param' => 'val1' }
else
@@ -166,19 +176,19 @@
c['stuff'].should == '1'
c['other_stuff'].should == '2'
end
end
- it 'should convert all inputs to strings' do
+ it 'converts all inputs to strings' do
e = auditable.new( @url, 'key' => 'stuff' )
e.update( { 'key' => nil } )
e.auditable.should == { 'key' => '' }
end
end
describe '#changes' do
- it 'should return the changes the inputs have sustained' do
+ it 'returns the changes the inputs have sustained' do
if !opts[:single_input]
[
{ 'param' => 'val1', 'another_param' => 'val3' },
{ 'another_param' => 'val3' },
{ 'new stuff' => 'houa!' },
@@ -202,18 +212,18 @@
end
end
end
describe '#[]' do
- it 'should serve as a reader to the #auditable hash' do
+ it ' serves as a reader to the #auditable hash' do
e = auditable.new( @url, { 'key' => 'stuff', 'key2' => 'val' } )
e['key'].should == 'stuff'
end
end
describe '#[]=' do
- it 'should serve as a writer to the #auditable hash' do
+ it 'serves as a writer to the #auditable hash' do
e = auditable.new( @url, { 'key' => 'stuff', 'key2' => 'val' } )
h = e.hash
e['key'] = 'val2'
@@ -223,13 +233,10 @@
e['key'].should == 'val2'
end
end
describe '#orig' do
- it 'should be the same as auditable' do
- @orig.orig.should == @orig.auditable
- end
it 'should be frozen' do
orig_auditable = @orig.auditable.dup
is_frozen = false
begin
@orig.orig['ff'] = 'ffss'
@@ -237,57 +244,64 @@
is_frozen = true
end
is_frozen.should be_true
@orig.orig.should == orig_auditable
end
- context 'when auditable has been modified' do
- it 'should return original input name/vals' do
- orig_auditable = @orig.auditable.dup
- @orig.auditable = {}
- @orig.orig.should == orig_auditable
- @orig.auditable = orig_auditable.dup
+ context 'when auditable' do
+ context 'has been modified' do
+ it 'returns original input name/vals' do
+ orig_auditable = @orig.auditable.dup
+ @orig.auditable = {}
+ @orig.orig.should == orig_auditable
+ @orig.auditable = orig_auditable.dup
+ end
end
+ context 'has not been modified' do
+ it 'returns #auditable' do
+ @orig.orig.should == @orig.auditable
+ end
+ end
end
- it 'should be aliased to #original' do
+ it 'aliased to #original' do
@orig.orig.should == @orig.original
end
end
describe '#reset' do
- it 'should return the auditable inputs to their original state' do
+ it 'returns the auditable inputs to their original state' do
orig = @orig.auditable.dup
@orig.update( orig.keys.first => 'value' )
(@orig.auditable != orig).should be_true
@orig.reset
@orig.auditable.should == orig
end
end
describe '#remove_auditor' do
- it 'should remove the auditor' do
+ it 'removes the auditor' do
@orig.auditor = :some_auditor
@orig.auditor.should == :some_auditor
@orig.remove_auditor
@orig.auditor.should be_nil
end
end
describe '#orphan?' do
context 'when it has no auditor' do
- it 'should return true' do
+ it 'returns true' do
@orphan.orphan?.should be_true
end
end
context 'when it has an auditor' do
- it 'should return true' do
+ it 'returns true' do
@auditable.orphan?.should be_false
end
end
end
describe '#submit' do
- it 'should submit the element along with its auditable inputs' do
+ it 'submits the element using its auditable inputs as params' do
submitted = nil
@auditable.submit do |res|
submitted = load( res.body )
end
@@ -295,29 +309,34 @@
@auditor.http.run
@auditable.auditable.should == submitted
end
context 'when it has no auditor' do
- it 'should revert to the HTTP interface singleton' do
- submitted = nil
+ it 'falls back to using the anonymous auditor' do
+ submitted = nil
- @orphan.submit do |res|
+ elem = auditable.new( @url + '/submit', 'param' => 'val' )
+ elem.auditor.should be_nil
+
+ elem.submit do |res|
submitted = load( res.body )
end
+ elem.auditor.should be_true
- @orphan.http.run
- @orphan.auditable.should == submitted
+ elem.http.run
+
+ elem.auditable.should == submitted
end
end
end
describe '#audit' do
before( :each ) { Arachni::Element::Capabilities::Auditable.reset }
context 'when the exclude_vectors option is set' do
- it 'should skip those vectors by name' do
+ it 'skips those vectors by name' do
e = auditable.new( @url + '/submit', 'include_this' => 'param', 'exclude_this' => 'param' )
Arachni::Options.exclude_vectors << 'exclude_this'
Arachni::Options.exclude_vectors << Arachni::Element::Form::ORIGINAL_VALUES
@@ -327,29 +346,46 @@
audited.uniq.should == %w(include_this)
end
end
context 'when called with no opts' do
- it 'should use the defaults' do
+ it 'uses the defaults' do
cnt = 0
@auditable.audit( @seed ) { cnt += 1 }
@auditor.http.run
cnt.should == 4
end
end
context 'when it has no auditor' do
- it 'should revert to the HTTP interface singleton' do
- cnt = 0
- @orphan.audit( @seed ) { cnt += 1 }
- @orphan.http.run
- cnt.should == 4
+ it 'falls back to using the anonymous auditor' do
+ elem = auditable.new( @url, 'param' => 'val' )
+ elem.auditor.should be_nil
+
+ elem.taint_analysis( 'test' )
+ elem.auditor.should be_true
+ elem.http.run
+
+ elem.auditor.issues.size.should == 1
+ elem.auditor.raw_issues.size.should == 1
+ issue = elem.auditor.raw_issues.first
+ issue.elem.should == elem.type
+ issue.id.should == 'test'
+ issue.method.to_s.downcase.should == 'get'
+ issue.name.should == 'Anonymous auditor'
+ issue.var.should == 'param'
+
+ elem.auditor.raw_issues.should == Arachni::Module::Manager.results
+ elem.auditor.issues.should == elem.auditor.auditstore.issues
+ elem.auditor.auditstore.should == Arachni::AuditStore.new(
+ options: Arachni::Options.instance.to_h,
+ issues: issues )
end
end
context 'when the action matches a #skip_path? rule' do
- it 'should return immediately' do
+ it 'returns immediately' do
ran = false
@auditable.audit( @seed ) { ran = true }
@auditor.http.run
ran.should be_true
@@ -373,11 +409,11 @@
ran.should be_true
end
end
context 'when the element has no auditable inputs' do
- it 'should return immediately' do
+ it 'returns immediately' do
e = auditable.new( @url + '/submit' )
ran = false
e.audit( @seed ) { ran = true }.should be_false
e.http.run
@@ -385,11 +421,11 @@
ran.should be_false
end
end
context 'when the auditor\'s #skip? method returns true for a mutation' do
- it 'should be skipped' do
+ it 'is skipped' do
ran = false
@auditable.audit( @seed ) { ran = true }.should be_true
@auditor.http.run
ran.should be_true
@@ -417,11 +453,11 @@
ran.should be_true
end
end
context 'when the element\'s #skip? method returns true for a mutation' do
- it 'should be skipped' do
+ it 'is skipped' do
ran = false
@auditable.audit( @seed ) { ran = true }.should be_true
@auditor.http.run
ran.should be_true
@@ -452,11 +488,11 @@
describe '.restrict_to_elements' do
after { Arachni::Element::Capabilities::Auditable.reset_instance_scope }
context 'when set' do
- it 'should restrict the audit to the provided elements' do
+ it 'restricts the audit to the provided elements' do
scope_id_arr = [ @auditable.scope_audit_id ]
Arachni::Element::Capabilities::Auditable.restrict_to_elements( scope_id_arr )
performed = false
@sleep.audit( '' ){ performed = true }
@sleep.http.run
@@ -471,11 +507,11 @@
describe '#override_instance_scope' do
after { @sleep.reset_scope_override }
context 'when called' do
- it 'should override scope restrictions' do
+ it 'overrides scope restrictions' do
scope_id_arr = [ @auditable.scope_audit_id ]
Arachni::Element::Capabilities::Auditable.restrict_to_elements( scope_id_arr )
performed = false
@sleep.audit( '' ){ performed = true }
@sleep.http.run
@@ -487,29 +523,29 @@
@sleep.http.run
performed.should be_true
end
describe '#override_instance_scope?' do
- it 'should return true' do
+ it 'returns true' do
@sleep.override_instance_scope
@sleep.override_instance_scope?.should be_true
end
end
end
context 'when not called' do
describe '#override_instance_scope?' do
- it 'should return false' do
+ it 'returns false' do
@sleep.override_instance_scope?.should be_false
end
end
end
end
end
context 'when not set' do
- it 'should not impose audit restrictions' do
+ it 'does not impose audit restrictions' do
performed = false
@sleep.audit( '' ){ performed = true }
@sleep.http.run
performed.should be_true
@@ -522,30 +558,45 @@
end
context 'when called with option' do
describe :each_mutation do
- it 'should be able to modify the element on the fly' do
+ it 'is passed each generated mutation' do
submitted = nil
cnt = 0
- each_mutation = proc do |mutation|
- mutation.altered_value = 'houa!'
- end
+ each_mutation = proc { |_| cnt += 1 }
@auditable.audit( @seed, each_mutation: each_mutation,
format: [ Arachni::Module::Auditor::Format::STRAIGHT ] ) do |res, opts|
submitted = load( res.body )
- cnt += 1
end
@auditor.http.run
cnt.should == 1
@auditable.auditable == submitted
end
+
+ it 'is able to modify mutations on the fly' do
+ submitted = nil
+
+ modified_seed = 'houa!'
+ each_mutation = proc do |mutation|
+ mutation.altered_value = modified_seed
+ end
+
+ @auditable.audit( @seed, each_mutation: each_mutation,
+ format: [ Arachni::Module::Auditor::Format::STRAIGHT ] ) do |res, opts|
+ submitted = load( res.body )
+ end
+
+ @auditor.http.run
+ submitted.values.first.should == modified_seed
+ end
+
context 'when it returns one or more elements of the same type' do
- it 'should audit those elements too' do
+ it 'audits those elements too' do
injected = []
cnt = 0
each_mutation = proc do |mutation|
m = mutation.dup
@@ -572,61 +623,63 @@
end
describe :format do
describe 'Arachni::Module::Auditor::Format::STRAIGHT' do
- it 'should inject the seed as is' do
+ it 'injects the seed as is' do
injected = nil
cnt = 0
+
@auditable.audit( @seed,
- format: [ Arachni::Module::Auditor::Format::STRAIGHT ] ){
- |res, opts|
+ format: [ Arachni::Module::Auditor::Format::STRAIGHT ] ) do |res, opts|
injected = load( res.body )[opts[:altered]]
cnt += 1
- }
+ end
+
@auditor.http.run
cnt.should == 1
injected.should == @seed
end
end
describe 'Arachni::Module::Auditor::Format::APPEND' do
- it 'should append the seed to the existing value of the input' do
+ it 'appends the seed to the existing value of the input' do
injected = nil
cnt = 0
+
@auditable.audit( @seed,
- format: [ Arachni::Module::Auditor::Format::APPEND ] ){
- |res, opts|
+ format: [ Arachni::Module::Auditor::Format::APPEND ] ) do |res, opts|
injected = load( res.body )[opts[:altered]]
cnt += 1
- }
+ end
+
@auditor.http.run
cnt.should == 1
injected.should == @default_input_value + @seed
end
end
describe 'Arachni::Module::Auditor::Format::NULL' do
- it 'should terminate the seed with a null character',
+ it 'terminates the seed with a null character',
if: described_class != Arachni::Element::Header do
injected = nil
cnt = 0
@auditable.audit( @seed,
- format: [ Arachni::Module::Auditor::Format::NULL ] ){
- |res, opts|
+ format: [ Arachni::Module::Auditor::Format::NULL ] ) do |res, opts|
injected = load( res.body )[opts[:altered]]
cnt += 1
- }
+ end
+
@auditor.http.run
cnt.should == 1
auditable.decode( injected ).should == @seed + "\0"
end
end
describe 'Arachni::Module::Auditor::Format::SEMICOLON' do
- it 'should prepend the seed with a semicolon' do
+ it 'prepends the seed with a semicolon' do
injected = nil
cnt = 0
format = [ Arachni::Module::Auditor::Format::SEMICOLON ]
@auditable.audit( @seed, format: format ) do |res, opts|
@@ -647,37 +700,33 @@
format: [ Arachni::Module::Auditor::Format::STRAIGHT ]
}
end
context true do
- it 'should allow redundant audits' do
+ it 'allows redundant audits' do
cnt = 0
5.times do |i|
- @auditable.audit( @seed, @audit_opts.merge( redundant: true )){
- cnt += 1
- }
+ @auditable.audit( @seed, @audit_opts.merge( redundant: true )){ cnt += 1 }
end
@auditor.http.run
cnt.should == 5
end
end
context false do
- it 'should not allow redundant requests/audits' do
+ it 'does not allow redundant requests/audits' do
cnt = 0
5.times do |i|
- @auditable.audit( @seed, @audit_opts.merge( redundant: false )){
- cnt += 1
- }
+ @auditable.audit( @seed, @audit_opts.merge( redundant: false )){ cnt += 1 }
end
@auditor.http.run
cnt.should == 1
end
end
context 'default' do
- it 'should not allow redundant requests/audits' do
+ it 'does not allow redundant requests/audits' do
cnt = 0
5.times do |i|
@auditable.audit( @seed, @audit_opts ){ cnt += 1 }
end
@auditor.http.run
@@ -687,11 +736,11 @@
end
describe :async do
context true do
- it 'should perform all HTTP requests asynchronously' do
+ it 'performs all HTTP requests asynchronously' do
before = Time.now
@sleep.audit( @seed, async: true ){}
@auditor.http.run
# should take as long as the longest request
@@ -702,20 +751,20 @@
(Time.now - before).to_i.should == 2
end
end
context false do
- it 'should perform all HTTP requests synchronously' do
+ it 'performs all HTTP requests synchronously' do
before = Time.now
@sleep.audit( @seed, async: false ){}
@auditor.http.run
(Time.now - before).should > 4.0
end
end
context 'default' do
- it 'should perform all HTTP requests asynchronously' do
+ it 'performs all HTTP requests asynchronously' do
before = Time.now
@sleep.audit( @seed ){}
@auditor.http.run
(Time.now - before).to_i.should == 2