tarantula 0.3.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.autotest +14 -0
- data/.gitignore +9 -0
- data/.rvmrc +1 -0
- data/DSL_EXAMPLES.md +120 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +108 -0
- data/{MIT-LICENSE → LICENSE} +0 -0
- data/README.rdoc +3 -28
- data/Rakefile +27 -59
- data/lib/relevance/core_extensions/ellipsize.rb +23 -19
- data/lib/relevance/core_extensions/file.rb +10 -4
- data/lib/relevance/core_extensions/response.rb +9 -6
- data/lib/relevance/core_extensions/test_case.rb +14 -12
- data/lib/relevance/tarantula.rb +24 -25
- data/lib/relevance/tarantula/attack.rb +19 -15
- data/lib/relevance/tarantula/attack_handler.rb +32 -26
- data/lib/relevance/tarantula/basic_attack.rb +36 -32
- data/lib/relevance/tarantula/crawler.rb +222 -216
- data/lib/relevance/tarantula/form.rb +27 -21
- data/lib/relevance/tarantula/form_submission.rb +79 -73
- data/lib/relevance/tarantula/html_document_handler.rb +37 -31
- data/lib/relevance/tarantula/html_report_helper.rb +36 -29
- data/lib/relevance/tarantula/html_reporter.rb +105 -99
- data/lib/relevance/tarantula/invalid_html_handler.rb +21 -15
- data/lib/relevance/tarantula/io_reporter.rb +37 -31
- data/lib/relevance/tarantula/link.rb +97 -73
- data/lib/relevance/tarantula/log_grabber.rb +20 -14
- data/lib/relevance/tarantula/rails_integration_proxy.rb +64 -58
- data/lib/relevance/tarantula/response.rb +16 -10
- data/lib/relevance/tarantula/result.rb +69 -63
- data/lib/relevance/tarantula/tidy_handler.rb +22 -17
- data/lib/relevance/tarantula/transform.rb +18 -14
- data/lib/relevance/tarantula/version.rb +5 -0
- data/{tasks → lib/relevance/tasks}/tarantula_tasks.rake +1 -1
- data/lib/tarantula-rails3.rb +9 -0
- data/{examples/relevance/core_extensions/ellipsize_example.rb → spec/relevance/core_extensions/ellipsize_spec.rb} +2 -2
- data/{examples/relevance/core_extensions/file_example.rb → spec/relevance/core_extensions/file_spec.rb} +2 -2
- data/{examples/relevance/core_extensions/response_example.rb → spec/relevance/core_extensions/response_spec.rb} +2 -2
- data/{examples/relevance/core_extensions/test_case_example.rb → spec/relevance/core_extensions/test_case_spec.rb} +1 -1
- data/{examples/relevance/tarantula/attack_handler_example.rb → spec/relevance/tarantula/attack_handler_spec.rb} +1 -1
- data/{examples/relevance/tarantula/basic_attack_example.rb → spec/relevance/tarantula/basic_attack_spec.rb} +2 -2
- data/{examples/relevance/tarantula/crawler_example.rb → spec/relevance/tarantula/crawler_spec.rb} +2 -2
- data/{examples/relevance/tarantula/form_example.rb → spec/relevance/tarantula/form_spec.rb} +2 -2
- data/{examples/relevance/tarantula/form_submission_example.rb → spec/relevance/tarantula/form_submission_spec.rb} +3 -3
- data/{examples/relevance/tarantula/html_document_handler_example.rb → spec/relevance/tarantula/html_document_handler_spec.rb} +1 -1
- data/{examples/relevance/tarantula/html_report_helper_example.rb → spec/relevance/tarantula/html_report_helper_spec.rb} +1 -1
- data/{examples/relevance/tarantula/html_reporter_example.rb → spec/relevance/tarantula/html_reporter_spec.rb} +1 -1
- data/{examples/relevance/tarantula/invalid_html_handler_example.rb → spec/relevance/tarantula/invalid_html_handler_spec.rb} +1 -1
- data/{examples/relevance/tarantula/io_reporter_example.rb → spec/relevance/tarantula/io_reporter_spec.rb} +1 -1
- data/{examples/relevance/tarantula/link_example.rb → spec/relevance/tarantula/link_spec.rb} +5 -5
- data/{examples/relevance/tarantula/log_grabber_example.rb → spec/relevance/tarantula/log_grabber_spec.rb} +1 -1
- data/{examples/relevance/tarantula/rails_integration_proxy_example.rb → spec/relevance/tarantula/rails_integration_proxy_spec.rb} +1 -1
- data/{examples/relevance/tarantula/result_example.rb → spec/relevance/tarantula/result_spec.rb} +1 -1
- data/{examples/relevance/tarantula/tidy_handler_example.rb → spec/relevance/tarantula/tidy_handler_spec.rb} +1 -1
- data/{examples/relevance/tarantula/transform_example.rb → spec/relevance/tarantula/transform_spec.rb} +2 -2
- data/{examples/relevance/tarantula_example.rb → spec/relevance/tarantula_spec.rb} +1 -1
- data/{examples/example_helper.rb → spec/spec_helper.rb} +6 -14
- data/tarantula.gemspec +31 -0
- data/template/tarantula_test.rb +1 -1
- data/vendor/xss-shield/MIT-LICENSE +20 -0
- data/vendor/xss-shield/README +76 -0
- data/vendor/xss-shield/init.rb +16 -0
- data/vendor/xss-shield/lib/xss_shield.rb +6 -0
- data/vendor/xss-shield/lib/xss_shield/erb_hacks.rb +111 -0
- data/vendor/xss-shield/lib/xss_shield/haml_hacks.rb +42 -0
- data/vendor/xss-shield/lib/xss_shield/safe_string.rb +47 -0
- data/vendor/xss-shield/lib/xss_shield/secure_helpers.rb +40 -0
- data/vendor/xss-shield/test/test_actionview_integration.rb +40 -0
- data/vendor/xss-shield/test/test_erb.rb +44 -0
- data/vendor/xss-shield/test/test_haml.rb +43 -0
- data/vendor/xss-shield/test/test_helpers.rb +25 -0
- data/vendor/xss-shield/test/test_safe_string.rb +55 -0
- metadata +170 -99
- data/VERSION.yml +0 -4
@@ -1,13 +1,19 @@
|
|
1
1
|
# Used to create a stub response when we didn't get back a real response
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
2
|
+
module Relevance
|
3
|
+
module Tarantula
|
4
|
+
|
5
|
+
class Response
|
6
|
+
HASHABLE_ATTRS = [:code, :body, :content_type]
|
7
|
+
attr_accessor *HASHABLE_ATTRS
|
8
|
+
|
9
|
+
def initialize(hash)
|
10
|
+
hash.each do |k,v|
|
11
|
+
raise ArgumentError, k unless HASHABLE_ATTRS.member?(k)
|
12
|
+
self.instance_variable_set("@#{k}", v)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
10
16
|
end
|
17
|
+
|
11
18
|
end
|
12
|
-
|
13
|
-
end
|
19
|
+
end
|
@@ -1,77 +1,83 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
DEFAULT_LOCALHOST = "http://localhost:3000"
|
4
|
-
attr_accessor *HASHABLE_ATTRS
|
5
|
-
include Relevance::Tarantula
|
6
|
-
include Relevance::Tarantula::HtmlReportHelper
|
7
|
-
|
8
|
-
def initialize(hash)
|
9
|
-
hash.each do |k,v|
|
10
|
-
raise ArgumentError, k unless HASHABLE_ATTRS.member?(k)
|
11
|
-
self.instance_variable_set("@#{k}", v)
|
12
|
-
end
|
13
|
-
end
|
1
|
+
module Relevance
|
2
|
+
module Tarantula
|
14
3
|
|
15
|
-
|
16
|
-
|
17
|
-
|
4
|
+
class Result
|
5
|
+
HASHABLE_ATTRS = [:success, :method, :url, :response, :referrer, :data, :description, :log, :test_name]
|
6
|
+
DEFAULT_LOCALHOST = "http://localhost:3000"
|
7
|
+
attr_accessor *HASHABLE_ATTRS
|
8
|
+
include Relevance::Tarantula
|
9
|
+
include Relevance::Tarantula::HtmlReportHelper
|
18
10
|
|
19
|
-
|
20
|
-
|
21
|
-
|
11
|
+
def initialize(hash)
|
12
|
+
hash.each do |k,v|
|
13
|
+
raise ArgumentError, k unless HASHABLE_ATTRS.member?(k)
|
14
|
+
self.instance_variable_set("@#{k}", v)
|
15
|
+
end
|
16
|
+
end
|
22
17
|
|
23
|
-
|
24
|
-
|
25
|
-
|
18
|
+
def short_description
|
19
|
+
[method,url].join(" ")
|
20
|
+
end
|
26
21
|
|
27
|
-
|
28
|
-
|
29
|
-
|
22
|
+
def sequence_number
|
23
|
+
@sequence_number ||= (self.class.next_number += 1)
|
24
|
+
end
|
30
25
|
|
31
|
-
|
32
|
-
|
33
|
-
|
26
|
+
def file_name
|
27
|
+
"#{sequence_number}.html"
|
28
|
+
end
|
34
29
|
|
35
|
-
|
36
|
-
|
37
|
-
|
30
|
+
def code
|
31
|
+
response && response.code
|
32
|
+
end
|
38
33
|
|
39
|
-
|
34
|
+
def body
|
35
|
+
response && response.body
|
36
|
+
end
|
40
37
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
def handle(result)
|
45
|
-
retval = result.dup
|
46
|
-
retval.success = successful?(result.response) || can_skip_error?(result)
|
47
|
-
retval.description = "Bad HTTP Response" unless retval.success
|
48
|
-
retval
|
49
|
-
end
|
38
|
+
def full_url
|
39
|
+
"#{DEFAULT_LOCALHOST}#{url}"
|
40
|
+
end
|
50
41
|
|
51
|
-
|
52
|
-
%w{200 201 302 401}
|
53
|
-
end
|
54
|
-
|
55
|
-
# allow_errors_for is a hash
|
56
|
-
# k=error code,
|
57
|
-
# v=array of matchers for urls that can skip said error
|
58
|
-
attr_accessor :allow_errors_for
|
59
|
-
def can_skip_error?(result)
|
60
|
-
coll = allow_errors_for[result.code]
|
61
|
-
return false unless coll
|
62
|
-
coll.any? {|item| item === result.url}
|
63
|
-
end
|
42
|
+
ALLOW_NNN_FOR = /^allow_(\d\d\d)_for$/
|
64
43
|
|
65
|
-
|
66
|
-
|
67
|
-
|
44
|
+
class << self
|
45
|
+
attr_accessor :next_number
|
46
|
+
|
47
|
+
def handle(result)
|
48
|
+
retval = result.dup
|
49
|
+
retval.success = successful?(result.response) || can_skip_error?(result)
|
50
|
+
retval.description = "Bad HTTP Response" unless retval.success
|
51
|
+
retval
|
52
|
+
end
|
53
|
+
|
54
|
+
def success_codes
|
55
|
+
%w{200 201 302 401}
|
56
|
+
end
|
57
|
+
|
58
|
+
# allow_errors_for is a hash
|
59
|
+
# k=error code,
|
60
|
+
# v=array of matchers for urls that can skip said error
|
61
|
+
attr_accessor :allow_errors_for
|
62
|
+
def can_skip_error?(result)
|
63
|
+
coll = allow_errors_for[result.code]
|
64
|
+
return false unless coll
|
65
|
+
coll.any? {|item| item === result.url}
|
66
|
+
end
|
68
67
|
|
69
|
-
|
70
|
-
|
71
|
-
|
68
|
+
def successful?(response)
|
69
|
+
success_codes.member?(response.code)
|
70
|
+
end
|
71
|
+
|
72
|
+
def method_missing(meth, *args)
|
73
|
+
super unless ALLOW_NNN_FOR =~ meth.to_s
|
74
|
+
(allow_errors_for[$1] ||= []).push(*args)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
self.allow_errors_for = {}
|
79
|
+
self.next_number = 0
|
72
80
|
end
|
73
|
-
end
|
74
81
|
|
75
|
-
|
76
|
-
self.next_number = 0
|
82
|
+
end
|
77
83
|
end
|
@@ -9,23 +9,28 @@ end
|
|
9
9
|
if defined? Tidy
|
10
10
|
Tidy.path = ENV['TIDY_PATH'] if ENV['TIDY_PATH']
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
12
|
+
module Relevance
|
13
|
+
module Tarantula
|
14
|
+
|
15
|
+
class TidyHandler
|
16
|
+
include Relevance::Tarantula
|
17
|
+
def initialize(options = {})
|
18
|
+
@options = {:show_warnings=>true}.merge(options)
|
19
|
+
end
|
20
|
+
def handle(result)
|
21
|
+
response = result.response
|
22
|
+
return unless response.html?
|
23
|
+
tidy = Tidy.open(@options) do |tidy|
|
24
|
+
xml = tidy.clean(response.body)
|
25
|
+
tidy
|
26
|
+
end
|
27
|
+
unless tidy.errors.blank?
|
28
|
+
error_result = result.dup
|
29
|
+
error_result.description = "Bad HTML (Tidy)"
|
30
|
+
error_result.data = tidy.errors.inspect
|
31
|
+
error_result
|
32
|
+
end
|
33
|
+
end
|
29
34
|
end
|
30
35
|
end
|
31
36
|
end
|
@@ -1,17 +1,21 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
string
|
11
|
-
|
12
|
-
|
1
|
+
module Relevance
|
2
|
+
module Tarantula
|
3
|
+
|
4
|
+
class Transform
|
5
|
+
attr_accessor :from, :to
|
6
|
+
def initialize(from, to)
|
7
|
+
@from = from
|
8
|
+
@to = to
|
9
|
+
end
|
10
|
+
def [](string)
|
11
|
+
case to
|
12
|
+
when Proc
|
13
|
+
string.gsub(from, &to)
|
14
|
+
else
|
15
|
+
string.gsub(from, to)
|
16
|
+
end
|
17
|
+
end
|
13
18
|
end
|
19
|
+
|
14
20
|
end
|
15
21
|
end
|
16
|
-
|
17
|
-
|
@@ -36,7 +36,7 @@ namespace :tarantula do
|
|
36
36
|
desc 'Generate a default tarantula test'
|
37
37
|
task :setup do
|
38
38
|
mkdir_p "test/tarantula"
|
39
|
-
template_path = File.expand_path(File.join(File.dirname(__FILE__), "
|
39
|
+
template_path = File.expand_path(File.join(File.dirname(__FILE__), "../../..", "template", "tarantula_test.rb"))
|
40
40
|
cp template_path, "test/tarantula/"
|
41
41
|
end
|
42
42
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe "Relevance::CoreExtensions::Object#ellipsize" do
|
4
4
|
it "converts nil to empty string" do
|
@@ -16,4 +16,4 @@ describe "Relevance::CoreExtensions::Object#ellipsize" do
|
|
16
16
|
it "shortens long strings and adds ..." do
|
17
17
|
"long-string".ellipsize(5).should == "long-..."
|
18
18
|
end
|
19
|
-
end
|
19
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
require 'relevance/core_extensions/file'
|
3
3
|
|
4
4
|
describe "Relevance::CoreExtensions::File#extension" do
|
5
5
|
it "should return the extension without the leading dot" do
|
6
6
|
File.extension("foo.bar").should == "bar"
|
7
7
|
end
|
8
|
-
end
|
8
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
require 'relevance/core_extensions/file'
|
3
3
|
|
4
4
|
describe "Relevance::CoreExtensions::Response#html?" do
|
@@ -26,4 +26,4 @@ describe "Relevance::CoreExtensions::Response#html?" do
|
|
26
26
|
@response.should be_html
|
27
27
|
end
|
28
28
|
|
29
|
-
end
|
29
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Relevance::Tarantula::BasicAttack do
|
4
4
|
before do
|
@@ -9,4 +9,4 @@ describe Relevance::Tarantula::BasicAttack do
|
|
9
9
|
@attack.random_whole_number.should >= 0
|
10
10
|
Fixnum.should === @attack.random_whole_number
|
11
11
|
end
|
12
|
-
end
|
12
|
+
end
|
data/{examples/relevance/tarantula/crawler_example.rb → spec/relevance/tarantula/crawler_spec.rb}
RENAMED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Relevance::Tarantula::Crawler do
|
4
4
|
|
@@ -372,4 +372,4 @@ describe Relevance::Tarantula::Crawler do
|
|
372
372
|
|
373
373
|
end
|
374
374
|
|
375
|
-
end
|
375
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe "Relevance::Tarantula::Form large example" do
|
4
4
|
before do
|
@@ -47,4 +47,4 @@ END
|
|
47
47
|
@form.method.should == "put"
|
48
48
|
end
|
49
49
|
|
50
|
-
end
|
50
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe Relevance::Tarantula::FormSubmission do
|
4
4
|
|
@@ -53,7 +53,7 @@ describe Relevance::Tarantula::FormSubmission do
|
|
53
53
|
end
|
54
54
|
|
55
55
|
it "can mutate selects" do
|
56
|
-
Hpricot::Elements.any_instance.stubs(:
|
56
|
+
Hpricot::Elements.any_instance.stubs(:sample).returns(stub(:[] => "2006-stub"))
|
57
57
|
@fs.mutate_selects(@form).should == {"foo[opened_on(1i)]" => "2006-stub"}
|
58
58
|
end
|
59
59
|
|
@@ -91,7 +91,7 @@ describe Relevance::Tarantula::FormSubmission do
|
|
91
91
|
end
|
92
92
|
|
93
93
|
it "can mutate selects" do
|
94
|
-
Hpricot::Elements.any_instance.stubs(:
|
94
|
+
Hpricot::Elements.any_instance.stubs(:sample).returns(stub(:[] => "2006-stub"))
|
95
95
|
@fs.mutate_selects(@form).should == {"foo[opened_on(1i)]" => "2006-stub"}
|
96
96
|
end
|
97
97
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe "Relevance::Tarantula::Link" do
|
4
4
|
include ActionView::Helpers::UrlHelper
|
@@ -16,19 +16,19 @@ describe "Relevance::Tarantula::Link" do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
it "parses anchor tags with POST 'method'" do
|
19
|
-
link = make_link(Hpricot(%Q{<a href="/foo" onclick="#{method_javascript_function(:post)}">foo</a>}).at('a'))
|
19
|
+
link = make_link(Hpricot(%Q{<a href="/foo" onclick="#{Relevance::Tarantula::Link.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 = make_link(Hpricot(%Q{<a href="/foo" onclick="#{method_javascript_function(:put)}">foo</a>}).at('a'))
|
25
|
+
link = make_link(Hpricot(%Q{<a href="/foo" onclick="#{Relevance::Tarantula::Link.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 = make_link(Hpricot(%Q{<a href="/foo" onclick="#{method_javascript_function(:delete)}">foo</a>}).at('a'))
|
31
|
+
link = make_link(Hpricot(%Q{<a href="/foo" onclick="#{Relevance::Tarantula::Link.method_javascript_function(:delete)}">foo</a>}).at('a'))
|
32
32
|
link.href.should == '/foo'
|
33
33
|
link.method.should == :delete
|
34
34
|
end
|
@@ -81,4 +81,4 @@ describe "possible conflict when user has an AR model named Link" do
|
|
81
81
|
}.should_not raise_error
|
82
82
|
end
|
83
83
|
|
84
|
-
end
|
84
|
+
end
|