relevance-tarantula 0.2.1 → 0.3.2
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.
- data/README.rdoc +3 -4
- data/Rakefile +8 -4
- data/VERSION.yml +2 -2
- data/examples/example_helper.rb +9 -0
- data/examples/relevance/tarantula/attack_handler_example.rb +1 -1
- data/examples/relevance/tarantula/basic_attack_example.rb +12 -0
- data/examples/relevance/tarantula/crawler_example.rb +66 -77
- data/examples/relevance/tarantula/form_example.rb +3 -3
- data/examples/relevance/tarantula/form_submission_example.rb +157 -57
- data/examples/relevance/tarantula/link_example.rb +24 -7
- data/lib/relevance/tarantula/attack.rb +3 -0
- data/lib/relevance/tarantula/attack_handler.rb +1 -1
- data/lib/relevance/tarantula/basic_attack.rb +40 -0
- data/lib/relevance/tarantula/crawler.rb +33 -46
- data/lib/relevance/tarantula/form.rb +4 -2
- data/lib/relevance/tarantula/form_submission.rb +47 -30
- data/lib/relevance/tarantula/link.rb +24 -4
- data/lib/relevance/tarantula/rails_integration_proxy.rb +1 -1
- data/lib/relevance/tarantula.rb +1 -1
- metadata +7 -7
- data/examples/relevance/tarantula/attack_form_submission_example.rb +0 -79
- data/lib/relevance/tarantula/attack_form_submission.rb +0 -76
@@ -4,47 +4,64 @@ describe "Relevance::Tarantula::Link" do
|
|
4
4
|
include ActionView::Helpers::UrlHelper
|
5
5
|
|
6
6
|
it "does not raise an error when initializing without href attribtue" do
|
7
|
-
link =
|
7
|
+
link = make_link(Hpricot('<a="/foo">foo</a>').at('a'))
|
8
8
|
link.href.should == nil
|
9
9
|
link.method.should == :get
|
10
10
|
end
|
11
11
|
|
12
12
|
it "parses anchor tags" do
|
13
|
-
link =
|
13
|
+
link = make_link(Hpricot('<a href="/foo">foo</a>').at('a'))
|
14
14
|
link.href.should == '/foo'
|
15
15
|
link.method.should == :get
|
16
16
|
end
|
17
17
|
|
18
18
|
it "parses anchor tags with POST 'method'" do
|
19
|
-
link =
|
19
|
+
link = make_link(Hpricot(%Q{<a href="/foo" onclick="#{method_javascript_function(:post)}">foo</a>}).at('a'))
|
20
20
|
link.href.should == '/foo'
|
21
21
|
link.method.should == :post
|
22
22
|
end
|
23
23
|
|
24
24
|
it "parses anchor tags with PUT 'method'" do
|
25
|
-
link =
|
25
|
+
link = make_link(Hpricot(%Q{<a href="/foo" onclick="#{method_javascript_function(:put)}">foo</a>}).at('a'))
|
26
26
|
link.href.should == '/foo'
|
27
27
|
link.method.should == :put
|
28
28
|
end
|
29
29
|
|
30
30
|
it "parses anchor tags with DELETE 'method'" do
|
31
|
-
link =
|
31
|
+
link = make_link(Hpricot(%Q{<a href="/foo" onclick="#{method_javascript_function(:delete)}">foo</a>}).at('a'))
|
32
32
|
link.href.should == '/foo'
|
33
33
|
link.method.should == :delete
|
34
34
|
end
|
35
35
|
|
36
36
|
it "parses link tags with text" do
|
37
|
-
link =
|
37
|
+
link = make_link(Hpricot('<link href="/bar">bar</a>').at('link'))
|
38
38
|
link.href.should == '/bar'
|
39
39
|
link.method.should == :get
|
40
40
|
end
|
41
41
|
|
42
42
|
it "parses link tags without text" do
|
43
|
-
link =
|
43
|
+
link = make_link(Hpricot('<link href="/bar" />').at('link'))
|
44
44
|
link.href.should == '/bar'
|
45
45
|
link.method.should == :get
|
46
46
|
end
|
47
47
|
|
48
|
+
it 'remembers link referrer if there is one' do
|
49
|
+
link = make_link('/url', stub_everything, '/some-referrer')
|
50
|
+
link.referrer.should == '/some-referrer'
|
51
|
+
end
|
52
|
+
|
53
|
+
it "does two things when crawled: follow, log, and handle" do
|
54
|
+
crawler = Relevance::Tarantula::Crawler.new
|
55
|
+
link = make_link('/foo', crawler)
|
56
|
+
|
57
|
+
response = stub(:code => "200")
|
58
|
+
crawler.expects(:follow).returns(response)
|
59
|
+
link.expects(:log)
|
60
|
+
crawler.expects(:handle_link_results)
|
61
|
+
|
62
|
+
link.crawl
|
63
|
+
end
|
64
|
+
|
48
65
|
# method_javascript_function needs this method
|
49
66
|
def protect_against_forgery?
|
50
67
|
false
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class Relevance::Tarantula::BasicAttack
|
2
|
+
ATTRS = [:name, :output, :description]
|
3
|
+
|
4
|
+
attr_reader *ATTRS
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@name = "Tarantula Basic Fuzzer"
|
8
|
+
@output = nil
|
9
|
+
@description = "Supplies purely random but simplistically generated form input."
|
10
|
+
end
|
11
|
+
|
12
|
+
def ==(other)
|
13
|
+
Relevance::Tarantula::BasicAttack === other && ATTRS.all? { |attr| send(attr) == other.send(attr)}
|
14
|
+
end
|
15
|
+
|
16
|
+
def input(input_field)
|
17
|
+
case input_field['name']
|
18
|
+
when /amount/ then random_int
|
19
|
+
when /_id$/ then random_whole_number
|
20
|
+
when /uploaded_data/ then nil
|
21
|
+
when nil then input['value']
|
22
|
+
else
|
23
|
+
random_int
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def big_number
|
28
|
+
10000 # arbitrary
|
29
|
+
end
|
30
|
+
|
31
|
+
def random_int
|
32
|
+
rand(big_number) - (big_number/2)
|
33
|
+
end
|
34
|
+
|
35
|
+
def random_whole_number
|
36
|
+
rand(big_number)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
@@ -10,7 +10,7 @@ class Relevance::Tarantula::Crawler
|
|
10
10
|
class CrawlTimeout < RuntimeError; end
|
11
11
|
|
12
12
|
attr_accessor :proxy, :handlers, :skip_uri_patterns, :log_grabber,
|
13
|
-
:reporters, :
|
13
|
+
:reporters, :crawl_queue, :links_queued,
|
14
14
|
:form_signatures_queued, :max_url_length, :response_code_handler,
|
15
15
|
:times_to_crawl, :fuzzers, :test_name, :crawl_timeout
|
16
16
|
attr_reader :transform_url_patterns, :referrers, :failures, :successes, :crawl_start_times, :crawl_end_times
|
@@ -22,8 +22,7 @@ class Relevance::Tarantula::Crawler
|
|
22
22
|
@handlers = [@response_code_handler = Result]
|
23
23
|
@links_queued = Set.new
|
24
24
|
@form_signatures_queued = Set.new
|
25
|
-
@
|
26
|
-
@forms_to_crawl = []
|
25
|
+
@crawl_queue = []
|
27
26
|
@crawl_start_times, @crawl_end_times = [], []
|
28
27
|
@crawl_timeout = 20.minutes
|
29
28
|
@referrers = {}
|
@@ -55,8 +54,7 @@ class Relevance::Tarantula::Crawler
|
|
55
54
|
def crawl(url = "/")
|
56
55
|
orig_links_queued = @links_queued.dup
|
57
56
|
orig_form_signatures_queued = @form_signatures_queued.dup
|
58
|
-
|
59
|
-
orig_forms_to_crawl = @forms_to_crawl.dup
|
57
|
+
orig_crawl_queue = @crawl_queue.dup
|
60
58
|
@times_to_crawl.times do |num|
|
61
59
|
queue_link url
|
62
60
|
|
@@ -71,8 +69,7 @@ class Relevance::Tarantula::Crawler
|
|
71
69
|
if num + 1 < @times_to_crawl
|
72
70
|
@links_queued = orig_links_queued
|
73
71
|
@form_signatures_queued = orig_form_signatures_queued
|
74
|
-
@
|
75
|
-
@forms_to_crawl = orig_forms_to_crawl
|
72
|
+
@crawl_queue = orig_crawl_queue
|
76
73
|
@referrers = {}
|
77
74
|
end
|
78
75
|
end
|
@@ -83,23 +80,20 @@ class Relevance::Tarantula::Crawler
|
|
83
80
|
end
|
84
81
|
|
85
82
|
def finished?
|
86
|
-
@
|
83
|
+
@crawl_queue.empty?
|
87
84
|
end
|
88
85
|
|
89
86
|
def do_crawl(number)
|
90
87
|
while (!finished?)
|
91
88
|
@crawl_start_times << Time.now
|
92
|
-
|
93
|
-
crawl_queued_forms(number)
|
89
|
+
crawl_the_queue(number)
|
94
90
|
@crawl_end_times << Time.now
|
95
91
|
end
|
96
92
|
end
|
97
93
|
|
98
|
-
def
|
99
|
-
while (
|
100
|
-
|
101
|
-
log "Response #{response.code} for #{link}"
|
102
|
-
handle_link_results(link, response)
|
94
|
+
def crawl_the_queue(number = 0)
|
95
|
+
while (request = @crawl_queue.pop)
|
96
|
+
request.crawl
|
103
97
|
blip(number)
|
104
98
|
end
|
105
99
|
end
|
@@ -110,15 +104,10 @@ class Relevance::Tarantula::Crawler
|
|
110
104
|
end
|
111
105
|
end
|
112
106
|
|
113
|
-
def handle_link_results(link,
|
107
|
+
def handle_link_results(link, result)
|
114
108
|
handlers.each do |h|
|
115
109
|
begin
|
116
|
-
save_result h.handle(
|
117
|
-
:url => link.href,
|
118
|
-
:response => response,
|
119
|
-
:log => grab_log!,
|
120
|
-
:referrer => referrers[link],
|
121
|
-
:test_name => test_name).freeze)
|
110
|
+
save_result h.handle(result)
|
122
111
|
rescue Exception => e
|
123
112
|
log "error handling #{link} #{e.message}"
|
124
113
|
# TODO: pass to results
|
@@ -126,23 +115,14 @@ class Relevance::Tarantula::Crawler
|
|
126
115
|
end
|
127
116
|
end
|
128
117
|
|
129
|
-
def
|
130
|
-
|
131
|
-
log "Response #{response.code} for #{form}"
|
132
|
-
response
|
133
|
-
rescue ActiveRecord::RecordNotFound => e
|
134
|
-
log "Skipping #{form.action}, presumed ok that record is missing"
|
135
|
-
Relevance::Tarantula::Response.new(:code => "404", :body => e.message, :content_type => "text/plain")
|
136
|
-
end
|
137
|
-
|
138
|
-
def crawl_queued_forms(number = 0)
|
139
|
-
while (form = @forms_to_crawl.pop)
|
140
|
-
response = crawl_form(form)
|
141
|
-
handle_form_results(form, response)
|
142
|
-
blip(number)
|
143
|
-
end
|
118
|
+
def follow(method, url, data=nil)
|
119
|
+
proxy.send(method, url, data)
|
144
120
|
end
|
145
121
|
|
122
|
+
def submit(method, action, data)
|
123
|
+
proxy.send(method, action, data)
|
124
|
+
end
|
125
|
+
|
146
126
|
def elasped_time_for_pass(num)
|
147
127
|
Time.now - crawl_start_times[num]
|
148
128
|
end
|
@@ -150,6 +130,14 @@ class Relevance::Tarantula::Crawler
|
|
150
130
|
def grab_log!
|
151
131
|
@log_grabber && @log_grabber.grab!
|
152
132
|
end
|
133
|
+
|
134
|
+
def make_result(options)
|
135
|
+
defaults = {
|
136
|
+
:log => grab_log!,
|
137
|
+
:test_name => test_name
|
138
|
+
}
|
139
|
+
Result.new(defaults.merge(options)).freeze
|
140
|
+
end
|
153
141
|
|
154
142
|
def handle_form_results(form, response)
|
155
143
|
handlers.each do |h|
|
@@ -193,23 +181,21 @@ class Relevance::Tarantula::Crawler
|
|
193
181
|
end
|
194
182
|
|
195
183
|
def queue_link(dest, referrer = nil)
|
196
|
-
dest = Link.new(dest)
|
197
|
-
dest.href = transform_url(dest.href)
|
184
|
+
dest = Link.new(dest, self, referrer)
|
198
185
|
return if should_skip_link?(dest)
|
199
|
-
@
|
200
|
-
@links_to_crawl << dest
|
186
|
+
@crawl_queue << dest
|
201
187
|
@links_queued << dest
|
202
188
|
dest
|
203
189
|
end
|
204
190
|
|
205
191
|
def queue_form(form, referrer = nil)
|
206
192
|
fuzzers.each do |fuzzer|
|
207
|
-
fuzzer.mutate(Form.new(form)).each do |fs|
|
208
|
-
# fs = fuzzer.new(Form.new(form))
|
193
|
+
fuzzer.mutate(Form.new(form, self, referrer)).each do |fs|
|
194
|
+
# fs = fuzzer.new(Form.new(form, self, referrer))
|
209
195
|
fs.action = transform_url(fs.action)
|
210
196
|
return if should_skip_form_submission?(fs)
|
211
197
|
@referrers[fs.action] = referrer if referrer
|
212
|
-
@
|
198
|
+
@crawl_queue << fs
|
213
199
|
@form_signatures_queued << fs.signature
|
214
200
|
end
|
215
201
|
end
|
@@ -234,6 +220,7 @@ class Relevance::Tarantula::Crawler
|
|
234
220
|
end
|
235
221
|
|
236
222
|
def report_results
|
223
|
+
puts "Crawled #{total_links_count} links and forms."
|
237
224
|
generate_reports
|
238
225
|
end
|
239
226
|
|
@@ -242,7 +229,7 @@ class Relevance::Tarantula::Crawler
|
|
242
229
|
end
|
243
230
|
|
244
231
|
def links_remaining_count
|
245
|
-
@
|
232
|
+
@crawl_queue.size
|
246
233
|
end
|
247
234
|
|
248
235
|
def links_completed_count
|
@@ -251,7 +238,7 @@ class Relevance::Tarantula::Crawler
|
|
251
238
|
|
252
239
|
def blip(number = 0)
|
253
240
|
unless verbose
|
254
|
-
print "\r #{links_completed_count} of #{total_links_count} links completed "
|
241
|
+
print "\r #{links_completed_count} of #{total_links_count} links completed " if $stdout.tty?
|
255
242
|
timeout_if_too_long(number)
|
256
243
|
end
|
257
244
|
end
|
@@ -2,8 +2,10 @@ class Relevance::Tarantula::Form
|
|
2
2
|
extend Forwardable
|
3
3
|
def_delegators("@tag", :search)
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
attr_accessor :crawler, :referrer
|
6
|
+
|
7
|
+
def initialize(tag, crawler, referrer)
|
8
|
+
@tag, @crawler, @referrer = tag, crawler, referrer
|
7
9
|
end
|
8
10
|
|
9
11
|
def action
|
@@ -1,25 +1,58 @@
|
|
1
1
|
class Relevance::Tarantula::FormSubmission
|
2
|
-
|
3
|
-
|
2
|
+
include Relevance::Tarantula
|
3
|
+
attr_accessor :method, :action, :data, :attack, :form
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def attacks
|
7
|
+
# normalize from hash input to Attack
|
8
|
+
@attacks = @attacks.map do |val|
|
9
|
+
Hash === val ? Relevance::Tarantula::Attack.new(val) : val
|
10
|
+
end
|
11
|
+
@attacks
|
12
|
+
end
|
13
|
+
def attacks=(atts)
|
14
|
+
# normalize from hash input to Attack
|
15
|
+
@attacks = atts.map do |val|
|
16
|
+
Hash === val ? Relevance::Tarantula::Attack.new(val) : val
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
@attacks = [Relevance::Tarantula::BasicAttack.new]
|
21
|
+
|
22
|
+
def initialize(form, attack = Relevance::Tarantula::BasicAttack.new)
|
23
|
+
@form = form
|
4
24
|
@method = form.method
|
5
25
|
@action = form.action
|
26
|
+
@attack = attack
|
6
27
|
@data = mutate_selects(form).merge(mutate_text_areas(form)).merge(mutate_inputs(form))
|
7
28
|
end
|
8
29
|
|
30
|
+
def crawl
|
31
|
+
begin
|
32
|
+
response = form.crawler.submit(method, action, data)
|
33
|
+
log "Response #{response.code} for #{self}"
|
34
|
+
rescue ActiveRecord::RecordNotFound => e
|
35
|
+
log "Skipping #{action}, presumed ok that record is missing"
|
36
|
+
response = Relevance::Tarantula::Response.new(:code => "404", :body => e.message, :content_type => "text/plain")
|
37
|
+
end
|
38
|
+
form.crawler.handle_form_results(self, response)
|
39
|
+
response
|
40
|
+
end
|
41
|
+
|
9
42
|
def self.mutate(form)
|
10
|
-
|
43
|
+
attacks.map{|attack| new(form, attack)} if attacks
|
11
44
|
end
|
12
|
-
|
45
|
+
|
13
46
|
def to_s
|
14
|
-
"#{action} #{method} #{data.inspect}"
|
47
|
+
"#{action} #{method} #{data.inspect} #{attack.inspect}"
|
15
48
|
end
|
16
|
-
|
49
|
+
|
17
50
|
# a form's signature is what makes it unique (e.g. action + fields)
|
18
51
|
# used to keep track of which forms we have submitted already
|
19
52
|
def signature
|
20
|
-
[action, data.keys.sort]
|
53
|
+
[action, data.keys.sort, attack.name]
|
21
54
|
end
|
22
|
-
|
55
|
+
|
23
56
|
def create_random_data_for(form, tag_selector)
|
24
57
|
form.search(tag_selector).inject({}) do |form_args, input|
|
25
58
|
# TODO: test
|
@@ -35,37 +68,21 @@ class Relevance::Tarantula::FormSubmission
|
|
35
68
|
def mutate_text_areas(form)
|
36
69
|
create_random_data_for(form, 'textarea')
|
37
70
|
end
|
38
|
-
|
71
|
+
|
39
72
|
def mutate_selects(form)
|
40
73
|
form.search('select').inject({}) do |form_args, select|
|
41
74
|
options = select.search('option')
|
42
75
|
option = options.rand
|
43
|
-
form_args[select['name']] = option['value']
|
76
|
+
form_args[select['name']] = option['value']
|
44
77
|
form_args
|
45
78
|
end
|
46
79
|
end
|
47
|
-
|
80
|
+
|
48
81
|
def random_data(input)
|
49
82
|
case input['name']
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
when /^_method$/ then input['value']
|
54
|
-
when nil then input['value']
|
55
|
-
else
|
56
|
-
random_int
|
83
|
+
when /^_method$/ then input['value']
|
84
|
+
else
|
85
|
+
attack.input(input)
|
57
86
|
end
|
58
87
|
end
|
59
|
-
|
60
|
-
def big_number
|
61
|
-
10000 # arbitrary
|
62
|
-
end
|
63
|
-
|
64
|
-
def random_int
|
65
|
-
rand(big_number) - (big_number/2)
|
66
|
-
end
|
67
|
-
|
68
|
-
def random_whole_number
|
69
|
-
rand(big_number)
|
70
|
-
end
|
71
88
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
class Relevance::Tarantula::Link
|
2
|
+
include Relevance::Tarantula
|
2
3
|
|
3
4
|
class << self
|
4
5
|
include ActionView::Helpers::UrlHelper
|
@@ -17,18 +18,33 @@ class Relevance::Tarantula::Link
|
|
17
18
|
METHOD_REGEXPS[m] = /#{s}/
|
18
19
|
end
|
19
20
|
|
20
|
-
attr_accessor :href
|
21
|
+
attr_accessor :href, :crawler, :referrer
|
21
22
|
|
22
|
-
def initialize(link)
|
23
|
+
def initialize(link, crawler, referrer)
|
24
|
+
@crawler, @referrer = crawler, referrer
|
25
|
+
|
23
26
|
if String === link || link.nil?
|
24
|
-
@href = link
|
27
|
+
@href = transform_url(link)
|
25
28
|
@method = :get
|
26
29
|
else # should be a tag
|
27
|
-
@href = link['href'] ? link['href'].downcase : nil
|
30
|
+
@href = link['href'] ? transform_url(link['href'].downcase) : nil
|
28
31
|
@tag = link
|
29
32
|
end
|
30
33
|
end
|
31
34
|
|
35
|
+
def crawl
|
36
|
+
response = crawler.follow(method, href)
|
37
|
+
log "Response #{response.code} for #{self}"
|
38
|
+
crawler.handle_link_results(self, make_result(response))
|
39
|
+
end
|
40
|
+
|
41
|
+
def make_result(response)
|
42
|
+
crawler.make_result(:method => method,
|
43
|
+
:url => href,
|
44
|
+
:response => response,
|
45
|
+
:referrer => referrer)
|
46
|
+
end
|
47
|
+
|
32
48
|
def method
|
33
49
|
@method ||= begin
|
34
50
|
(@tag &&
|
@@ -39,6 +55,10 @@ class Relevance::Tarantula::Link
|
|
39
55
|
end
|
40
56
|
end
|
41
57
|
|
58
|
+
def transform_url(link)
|
59
|
+
crawler.transform_url(link)
|
60
|
+
end
|
61
|
+
|
42
62
|
def ==(obj)
|
43
63
|
obj.respond_to?(:href) && obj.respond_to?(:method) &&
|
44
64
|
self.href.to_s == obj.href.to_s && self.method.to_s == obj.method.to_s
|
@@ -41,7 +41,7 @@ class Relevance::Tarantula::RailsIntegrationProxy
|
|
41
41
|
if response.code == '404'
|
42
42
|
if File.exist?(static_content_path(url))
|
43
43
|
case ext = File.extension(url)
|
44
|
-
when /html|te?xt|css|js|jpe?g|gif|psd|png|eps|pdf/
|
44
|
+
when /html|te?xt|css|js|jpe?g|gif|psd|png|eps|pdf|ico/
|
45
45
|
response.body = static_content_file(url)
|
46
46
|
response.headers["type"] = "text/#{ext}" # readable as response.content_type
|
47
47
|
response.meta.attr_accessor :code
|
data/lib/relevance/tarantula.rb
CHANGED
@@ -49,10 +49,10 @@ require File.expand_path(File.join(File.dirname(__FILE__), "tarantula", "log_gra
|
|
49
49
|
require File.expand_path(File.join(File.dirname(__FILE__), "tarantula", "invalid_html_handler"))
|
50
50
|
require File.expand_path(File.join(File.dirname(__FILE__), "tarantula", "transform"))
|
51
51
|
require File.expand_path(File.join(File.dirname(__FILE__), "tarantula", "crawler"))
|
52
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "tarantula", "basic_attack"))
|
52
53
|
require File.expand_path(File.join(File.dirname(__FILE__), "tarantula", "form"))
|
53
54
|
require File.expand_path(File.join(File.dirname(__FILE__), "tarantula", "form_submission"))
|
54
55
|
require File.expand_path(File.join(File.dirname(__FILE__), "tarantula", "attack"))
|
55
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "tarantula", "attack_form_submission"))
|
56
56
|
require File.expand_path(File.join(File.dirname(__FILE__), "tarantula", "attack_handler"))
|
57
57
|
require File.expand_path(File.join(File.dirname(__FILE__), "tarantula", "link"))
|
58
58
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: relevance-tarantula
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Relevance, Inc.
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-09-24 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -51,8 +51,8 @@ files:
|
|
51
51
|
- examples/relevance/core_extensions/file_example.rb
|
52
52
|
- examples/relevance/core_extensions/response_example.rb
|
53
53
|
- examples/relevance/core_extensions/test_case_example.rb
|
54
|
-
- examples/relevance/tarantula/attack_form_submission_example.rb
|
55
54
|
- examples/relevance/tarantula/attack_handler_example.rb
|
55
|
+
- examples/relevance/tarantula/basic_attack_example.rb
|
56
56
|
- examples/relevance/tarantula/crawler_example.rb
|
57
57
|
- examples/relevance/tarantula/form_example.rb
|
58
58
|
- examples/relevance/tarantula/form_submission_example.rb
|
@@ -84,8 +84,8 @@ files:
|
|
84
84
|
- lib/relevance/core_extensions/test_case.rb
|
85
85
|
- lib/relevance/tarantula.rb
|
86
86
|
- lib/relevance/tarantula/attack.rb
|
87
|
-
- lib/relevance/tarantula/attack_form_submission.rb
|
88
87
|
- lib/relevance/tarantula/attack_handler.rb
|
88
|
+
- lib/relevance/tarantula/basic_attack.rb
|
89
89
|
- lib/relevance/tarantula/crawler.rb
|
90
90
|
- lib/relevance/tarantula/detail.html.erb
|
91
91
|
- lib/relevance/tarantula/form.rb
|
@@ -107,7 +107,7 @@ files:
|
|
107
107
|
- lib/relevance/tarantula/transform.rb
|
108
108
|
- tasks/tarantula_tasks.rake
|
109
109
|
- template/tarantula_test.rb
|
110
|
-
has_rdoc:
|
110
|
+
has_rdoc: false
|
111
111
|
homepage: http://github.com/relevance/tarantula
|
112
112
|
licenses:
|
113
113
|
post_install_message:
|
@@ -132,7 +132,7 @@ requirements: []
|
|
132
132
|
rubyforge_project: thinkrelevance
|
133
133
|
rubygems_version: 1.3.5
|
134
134
|
signing_key:
|
135
|
-
specification_version:
|
135
|
+
specification_version: 3
|
136
136
|
summary: A big hairy fuzzy spider that crawls your site, wreaking havoc
|
137
137
|
test_files:
|
138
138
|
- examples/example_helper.rb
|
@@ -140,8 +140,8 @@ test_files:
|
|
140
140
|
- examples/relevance/core_extensions/file_example.rb
|
141
141
|
- examples/relevance/core_extensions/response_example.rb
|
142
142
|
- examples/relevance/core_extensions/test_case_example.rb
|
143
|
-
- examples/relevance/tarantula/attack_form_submission_example.rb
|
144
143
|
- examples/relevance/tarantula/attack_handler_example.rb
|
144
|
+
- examples/relevance/tarantula/basic_attack_example.rb
|
145
145
|
- examples/relevance/tarantula/crawler_example.rb
|
146
146
|
- examples/relevance/tarantula/form_example.rb
|
147
147
|
- examples/relevance/tarantula/form_submission_example.rb
|
@@ -1,79 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "example_helper.rb"))
|
2
|
-
|
3
|
-
describe "Relevance::Tarantula::AttackFormSubmission" do
|
4
|
-
|
5
|
-
# TODO: add more from field types to this example form as needed
|
6
|
-
before do
|
7
|
-
@tag = Hpricot(<<END)
|
8
|
-
<form action="/session" method="post">
|
9
|
-
<input id="email" name="email" size="30" type="text" />
|
10
|
-
<textarea id="comment" name="comment"value="1" />
|
11
|
-
<input name="commit" type="submit" value="Postit" />
|
12
|
-
<input name="secret" type="hidden" value="secret" />
|
13
|
-
<select id="foo_opened_on_1i" name="foo[opened_on(1i)]">
|
14
|
-
<option value="2003">2003</option>
|
15
|
-
<option value="2004">2004</option>
|
16
|
-
</select>
|
17
|
-
</form>
|
18
|
-
END
|
19
|
-
@form = Relevance::Tarantula::Form.new(@tag.at('form'))
|
20
|
-
@fs = Relevance::Tarantula::AttackFormSubmission.new(@form, Relevance::Tarantula::Attack.new({:name => 'foo_name', :input => 'foo_code', :output => 'foo_code'}))
|
21
|
-
end
|
22
|
-
|
23
|
-
it "can mutate text areas" do
|
24
|
-
@fs.mutate_text_areas(@form).should == {"comment" => "foo_code"}
|
25
|
-
end
|
26
|
-
|
27
|
-
it "can mutate selects" do
|
28
|
-
Hpricot::Elements.any_instance.stubs(:rand).returns(stub(:[] => "2006-stub"))
|
29
|
-
@fs.mutate_selects(@form).should == {"foo[opened_on(1i)]" => "2006-stub"}
|
30
|
-
end
|
31
|
-
|
32
|
-
it "can mutate inputs" do
|
33
|
-
@fs.mutate_inputs(@form).should == {"commit"=>"foo_code", "secret"=>"foo_code", "email"=>"foo_code"}
|
34
|
-
end
|
35
|
-
|
36
|
-
it "has a signature based on action, fields, and attack name" do
|
37
|
-
@fs.signature.should == ['/session', [
|
38
|
-
"comment",
|
39
|
-
"commit",
|
40
|
-
"email",
|
41
|
-
"foo[opened_on(1i)]",
|
42
|
-
"secret"],
|
43
|
-
"foo_name"
|
44
|
-
]
|
45
|
-
end
|
46
|
-
|
47
|
-
it "has a friendly to_s" do
|
48
|
-
@fs.to_s.should =~ %r{^/session post}
|
49
|
-
end
|
50
|
-
|
51
|
-
it "processes all its attacks" do
|
52
|
-
Relevance::Tarantula::AttackFormSubmission.stubs(:attacks).returns([
|
53
|
-
Relevance::Tarantula::Attack.new({:name => 'foo_name1', :input => 'foo_input', :output => 'foo_output'}),
|
54
|
-
Relevance::Tarantula::Attack.new({:name => 'foo_name2', :input => 'foo_input', :output => 'foo_output'}),
|
55
|
-
])
|
56
|
-
Relevance::Tarantula::AttackFormSubmission.mutate(@form).size.should == 2
|
57
|
-
end
|
58
|
-
|
59
|
-
it "maps hash attacks to Attack instances" do
|
60
|
-
Relevance::Tarantula::AttackFormSubmission.instance_variable_set("@attacks", [{ :name => "attack name"}])
|
61
|
-
Relevance::Tarantula::AttackFormSubmission.attacks.should == [Relevance::Tarantula::Attack.new({:name => "attack name"})]
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
describe "Relevance::Tarantula::AttackFormSubmission for a crummy form" do
|
66
|
-
before do
|
67
|
-
@tag = Hpricot(<<END)
|
68
|
-
<form action="/session" method="post">
|
69
|
-
<input value="no_name" />
|
70
|
-
</form>
|
71
|
-
END
|
72
|
-
@form = Relevance::Tarantula::Form.new(@tag.at('form'))
|
73
|
-
@fs = Relevance::Tarantula::AttackFormSubmission.new(@form, {:name => 'foo_name', :input => 'foo_code', :output => 'foo_code'})
|
74
|
-
end
|
75
|
-
|
76
|
-
it "ignores unnamed inputs" do
|
77
|
-
@fs.mutate_inputs(@form).should == {}
|
78
|
-
end
|
79
|
-
end
|