panmind-tarantula 0.3.3

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.
Files changed (67) hide show
  1. data/CHANGELOG +49 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +171 -0
  4. data/Rakefile +83 -0
  5. data/VERSION.yml +4 -0
  6. data/examples/example_helper.rb +57 -0
  7. data/examples/relevance/core_extensions/ellipsize_example.rb +19 -0
  8. data/examples/relevance/core_extensions/file_example.rb +8 -0
  9. data/examples/relevance/core_extensions/response_example.rb +29 -0
  10. data/examples/relevance/core_extensions/test_case_example.rb +20 -0
  11. data/examples/relevance/tarantula/attack_handler_example.rb +29 -0
  12. data/examples/relevance/tarantula/basic_attack_example.rb +12 -0
  13. data/examples/relevance/tarantula/crawler_example.rb +375 -0
  14. data/examples/relevance/tarantula/form_example.rb +50 -0
  15. data/examples/relevance/tarantula/form_submission_example.rb +171 -0
  16. data/examples/relevance/tarantula/html_document_handler_example.rb +43 -0
  17. data/examples/relevance/tarantula/html_report_helper_example.rb +46 -0
  18. data/examples/relevance/tarantula/html_reporter_example.rb +82 -0
  19. data/examples/relevance/tarantula/invalid_html_handler_example.rb +33 -0
  20. data/examples/relevance/tarantula/io_reporter_example.rb +11 -0
  21. data/examples/relevance/tarantula/link_example.rb +84 -0
  22. data/examples/relevance/tarantula/log_grabber_example.rb +26 -0
  23. data/examples/relevance/tarantula/rails_integration_proxy_example.rb +101 -0
  24. data/examples/relevance/tarantula/result_example.rb +85 -0
  25. data/examples/relevance/tarantula/tidy_handler_example.rb +58 -0
  26. data/examples/relevance/tarantula/transform_example.rb +20 -0
  27. data/examples/relevance/tarantula_example.rb +23 -0
  28. data/laf/images/header_bg.jpg +0 -0
  29. data/laf/images/logo.png +0 -0
  30. data/laf/images/tagline.png +0 -0
  31. data/laf/javascripts/jquery-1.2.3.js +3408 -0
  32. data/laf/javascripts/jquery-ui-tabs.js +890 -0
  33. data/laf/javascripts/jquery.tablesorter.js +861 -0
  34. data/laf/javascripts/tarantula.js +10 -0
  35. data/laf/stylesheets/tarantula.css +346 -0
  36. data/lib/relevance/core_extensions/ellipsize.rb +34 -0
  37. data/lib/relevance/core_extensions/file.rb +9 -0
  38. data/lib/relevance/core_extensions/metaclass.rb +78 -0
  39. data/lib/relevance/core_extensions/response.rb +9 -0
  40. data/lib/relevance/core_extensions/string_chars_fix.rb +11 -0
  41. data/lib/relevance/core_extensions/test_case.rb +19 -0
  42. data/lib/relevance/tarantula.rb +59 -0
  43. data/lib/relevance/tarantula/attack.rb +18 -0
  44. data/lib/relevance/tarantula/attack_handler.rb +37 -0
  45. data/lib/relevance/tarantula/basic_attack.rb +40 -0
  46. data/lib/relevance/tarantula/crawler.rb +254 -0
  47. data/lib/relevance/tarantula/detail.html.erb +81 -0
  48. data/lib/relevance/tarantula/form.rb +23 -0
  49. data/lib/relevance/tarantula/form_submission.rb +88 -0
  50. data/lib/relevance/tarantula/html_document_handler.rb +36 -0
  51. data/lib/relevance/tarantula/html_report_helper.rb +39 -0
  52. data/lib/relevance/tarantula/html_reporter.rb +105 -0
  53. data/lib/relevance/tarantula/index.html.erb +37 -0
  54. data/lib/relevance/tarantula/invalid_html_handler.rb +18 -0
  55. data/lib/relevance/tarantula/io_reporter.rb +34 -0
  56. data/lib/relevance/tarantula/link.rb +76 -0
  57. data/lib/relevance/tarantula/log_grabber.rb +16 -0
  58. data/lib/relevance/tarantula/rails_integration_proxy.rb +87 -0
  59. data/lib/relevance/tarantula/recording.rb +12 -0
  60. data/lib/relevance/tarantula/response.rb +13 -0
  61. data/lib/relevance/tarantula/result.rb +77 -0
  62. data/lib/relevance/tarantula/test_report.html.erb +32 -0
  63. data/lib/relevance/tarantula/tidy_handler.rb +32 -0
  64. data/lib/relevance/tarantula/transform.rb +17 -0
  65. data/tasks/tarantula_tasks.rake +42 -0
  66. data/template/tarantula_test.rb +22 -0
  67. metadata +213 -0
data/CHANGELOG ADDED
@@ -0,0 +1,49 @@
1
+ v0.2.0 Implementation of updated look-and-feel [Jason Rudolph]
2
+
3
+ v0.1.8 Add timeouts for crawls to help really long builds [Rob Sanheim]
4
+
5
+ v0.1.7 Minor clean up [Rob Sanheim]
6
+
7
+ v0.1.6
8
+ * add testing for all Rails versions 2.0.2 and up
9
+ * various clean up and housekeeping tasks;
10
+ * start Ruby 1.9 work (but we need Hpricot)
11
+ * show 50 chars of URL, not 30
12
+ * ensure that ActiveRecord gets loaded correctly for the crawler, so that it can rescue RecordNotFound exceptions
13
+ [Rob Sanheim]
14
+
15
+ v0.1.5 Initial implementation of updated look-and-feel [Erik Yowell] [Jason Rudolph]
16
+
17
+ v0.1.4 Bugfix: Include look-and-feel files when building the gem #16 [Jason Rudolph]
18
+
19
+ v0.1.3 Update list of known static file types (e.g., PDFs) to prevent false reports of 404s for links to files that exist in RAILS_ROOT/public [Aaron Bedra]
20
+
21
+ v0.1.2 Remove dependency on Facets gem [Aaron Bedra]
22
+
23
+ v0.1.1 Bugfix: Add ability to handle anchor tags that lack an href attribute #13 [Kevin Gisi]
24
+
25
+ v0.1.0
26
+ * Improve the generated test template to include inline documentation and make the simple case simple [Jason Rudolph]
27
+ * Update README to better serve first-time users [Jason Rudolph]
28
+ * Update development dependencies declarations [Jason Rudolph]
29
+ * Internal refactorings [Aaron Bedra]
30
+ ** Convert test suite to micronaut
31
+ ** Replace Echoe with Jeweler for gem management
32
+ ** Remove unused code
33
+
34
+ v0.0.8.1
35
+ * Fix numerous installation and initial setup issues
36
+ * Enhance rake tasks to support use of Tarantula in a continuous integration environment
37
+ ** Use "rake tarantula:test" to run headless with build-friendly exit codes
38
+ ** Use "rake tarantula:report" to open the Tarantula report in your browser
39
+ * Update README
40
+ ** Provide better installation and setup documentation
41
+ ** Include example of adding a custom attack handler
42
+ * Simplify design to address concerns about hard-to-read fonts
43
+
44
+ v0.0.5
45
+ * Make sure we don't include Relevance::Tarantula into Object - will cause issues with Rails dependencies and is a bad idea in general
46
+ * Update Rakefile for development dependencies
47
+ * Other small clean up tasks
48
+
49
+ v0.0.1 Tarantula becomes a gem. [Aaron Bedra]
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008-2009 Relevance, Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,171 @@
1
+ = Tarantula
2
+
3
+ == Purpose of this fork
4
+
5
+ * Add panmind/ssl_helper interaction support - if the crawler receives
6
+ a `302` response redirecting to the very same requested URL, assume
7
+ it is a SSL requirement and use `https!` to set the SSL request hdrs;
8
+
9
+ * Add panmind/jquery-ajax-nav support - if the crawler receives a `302`
10
+ response with a `#` or `#!` in it, assume it is an XHR requirement
11
+ thus use `xhr` to re-send the request.
12
+
13
+ == DESCRIPTION
14
+
15
+ Tarantula is a big fuzzy spider. It crawls your Rails application, fuzzing data to see what breaks.
16
+
17
+ == Usage
18
+
19
+ === Installation
20
+
21
+ The latest and greatest version is always available on GitHub. (See the rakefile for dependencies, or
22
+ just let RubyGems handle it.)
23
+
24
+ gem install tarantula
25
+
26
+ You can also grab it from RubyForge, where we will push stable releases but may not be as bleeding edge
27
+ as the GitHub gem.
28
+
29
+ gem install tarantula
30
+
31
+ === Project Setup
32
+
33
+ To set up Tarantula into your application, add the following line into either config/environment.rb or
34
+ config/environments/test.rb (preferred). This assumes that you have Rails 2.1 or higher installed.
35
+
36
+ config.gem 'tarantula', :lib => 'relevance/tarantula'
37
+
38
+ Since Rails doesn't (yet) support automatically loading rake tasks that live inside gems, you will need
39
+ to update your Rakefile to load Tarantula's rake tasks. The simplest approach is to start by vendoring
40
+ Tarantula into your Rails app.
41
+
42
+ mkdir -p vendor/gems
43
+ cd vendor/gems
44
+ gem unpack tarantula
45
+
46
+ You can then add the following line into your Rakefile, which will allow your application to discover
47
+ Tarantula's rake tasks.
48
+
49
+ load File.join(RAILS_ROOT, Dir["vendor/gems/tarantula-*/tasks/*.rake"])
50
+
51
+ === Crawling Your App
52
+
53
+ Use the included rake task to create a Rails integration test that will allow Tarantula to crawl your
54
+ app.
55
+
56
+ #!sh
57
+ rake tarantula:setup
58
+
59
+ Take a moment to familiarize yourself with the generated test. If parts of your application require
60
+ login, update the test to make sure Tarantula can access those parts of your app.
61
+
62
+ require "relevance/tarantula"
63
+
64
+ class TarantulaTest < ActionController::IntegrationTest
65
+ # Load enough test data to ensure that there's a link to every page in your
66
+ # application. Doing so allows Tarantula to follow those links and crawl
67
+ # every page. For many applications, you can load a decent data set by
68
+ # loading all fixtures.
69
+ fixtures :all
70
+
71
+ def test_tarantula
72
+ # If your application requires users to log in before accessing certain
73
+ # pages, uncomment the lines below and update them to allow this test to
74
+ # log in to your application. Doing so allows Tarantula to crawl the
75
+ # pages that are only accessible to logged-in users.
76
+ #
77
+ # post '/session', :login => 'quentin', :password => 'monkey'
78
+ # follow_redirect!
79
+
80
+ tarantula_crawl(self)
81
+ end
82
+ end
83
+
84
+ If you want to set custom options, you can get access to the crawler and set properties before running
85
+ it. For example, this would turn on HTMLTidy.
86
+
87
+ def test_tarantula
88
+ post '/session', :login => 'kilgore', :password => 'trout'
89
+ assert_response :redirect
90
+ assert_redirected_to '/'
91
+ follow_redirect!
92
+
93
+ t = tarantula_crawler(self)
94
+ t.handlers << Relevance::Tarantula::TidyHandler.new
95
+ t.crawl '/'
96
+ end
97
+
98
+ Now it's time to turn Tarantula loose on your app. Assuming your project is at /work/project/:
99
+
100
+ #!sh
101
+ cd /work/project
102
+ rake tarantula:test
103
+
104
+ == Verbose Mode
105
+
106
+ If you run the test using the steps shown above, Tarantula will produce a report in tmp/tarantula. You
107
+ can also set VERBOSE=true to see more detail as the test runs.
108
+
109
+ For more options, please see the test suite.
110
+
111
+ == Allowed Errors
112
+
113
+ If, for example, a 404 is an appropriate response for some URLs, you can tell Tarantula to allow 404s
114
+ for URLs matching a given regex:
115
+
116
+ t = tarantula_crawler(self)
117
+ t.allow_404_for %r{/users/\d+/}
118
+
119
+ == Testing for Common Attacks
120
+
121
+ You can specify the attack strings that Tarantula throws at your application.
122
+
123
+ def test_tarantula
124
+ t = tarantula_crawler(self)
125
+
126
+ Relevance::Tarantula::FormSubmission.attacks << {
127
+ :name => :xss,
128
+ :input => "<script>gotcha!</script>",
129
+ :output => "<script>gotcha!</script>",
130
+ }
131
+
132
+ Relevance::Tarantula::FormSubmission.attacks << {
133
+ :name => :sql_injection,
134
+ :input => "a'; DROP TABLE posts;",
135
+ }
136
+
137
+ t.handlers << Relevance::Tarantula::AttackHandler.new
138
+ t.times_to_crawl = 2
139
+ t.crawl "/posts"
140
+ end
141
+
142
+ This example adds custom attacks for both SQL injection and XSS. It also tells Tarantula to crawl the
143
+ app 2 times. This is important for XSS attacks because the results won't appear until the second time
144
+ Tarantula performs the crawl.
145
+
146
+ == Timeout
147
+
148
+ You can specify a timeout for each specific crawl that Tarantula runs. For example:
149
+
150
+ def test_tarantula
151
+ t = tarantula_crawler(self)
152
+ t.times_to_crawl = 2
153
+ t.crawl_timeout = 5.minutes
154
+ t.crawl "/"
155
+ end
156
+
157
+ The above will crawl your app twice, and each specific crawl will timeout if it takes longer then 5 minutes. You may need a timeout to keep the tarantula test time reasonable if your app is large or just happens to have a large amount of 'never-ending' links, such as with an any sort of "auto-admin" interface.
158
+
159
+ == Bugs/Requests
160
+
161
+ Please submit your bug reports, patches, or feature requests at Lighthouse:
162
+
163
+ http://relevance.lighthouseapp.com/projects/17868-tarantula/overview
164
+
165
+ You can view the continuous integration results for Tarantula, including results against all supported versions of Rails, on RunCodeRun here:
166
+
167
+ http://runcoderun.com/relevance/tarantula
168
+
169
+ == License
170
+
171
+ Tarantula is released under the MIT license.
data/Rakefile ADDED
@@ -0,0 +1,83 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+ require 'micronaut'
5
+ require 'micronaut/rake_task'
6
+
7
+ begin
8
+ require 'jeweler'
9
+ files = ["CHANGELOG", "MIT-LICENSE", "Rakefile", "README.rdoc", "VERSION.yml"]
10
+ files << Dir["examples/**/*", "laf/**/*", "lib/**/*", "tasks/**/*", "template/**/*"]
11
+
12
+ Jeweler::Tasks.new do |s|
13
+ s.name = "panmind-tarantula"
14
+ s.summary = "A big hairy fuzzy spider that crawls your site, wreaking havoc"
15
+ s.description = "A big hairy fuzzy spider that crawls your site, wreaking havoc"
16
+ s.homepage = "http://github.com/Panmind/tarantula"
17
+ s.email = "opensource@thinkrelevance.com"
18
+ s.authors = ["Relevance, Inc."]
19
+ s.require_paths = ["lib"]
20
+ s.files = files.flatten
21
+ s.add_dependency 'htmlentities', '>= 4.2.0'
22
+ s.add_dependency 'hpricot', '>= 0.8.1'
23
+ s.add_development_dependency 'micronaut'
24
+ s.add_development_dependency 'log_buddy'
25
+ end
26
+ Jeweler::GemcutterTasks.new
27
+ rescue LoadError
28
+ puts "Jeweler not available. Install it with: gem install jeweler"
29
+ end
30
+
31
+ desc "Run all micronaut examples"
32
+ Micronaut::RakeTask.new :examples do |t|
33
+ t.pattern = "examples/**/*_example.rb"
34
+ end
35
+
36
+ desc "Run all micronaut examples using rcov"
37
+ Micronaut::RakeTask.new :rcov do |t|
38
+ t.pattern = "examples/**/*_example.rb"
39
+ t.rcov = true
40
+ t.rcov_opts = %[--exclude "gems/*,/Library/Ruby/*,config/*" --text-summary --sort coverage]
41
+ end
42
+
43
+ namespace :examples do
44
+
45
+ RAILS_VERSIONS = %w[2.3.2 2.3.4]
46
+
47
+ unless RUBY_VERSION =~ /^1\.9\./
48
+ RAILS_VERSIONS.unshift(*%w[2.0.2 2.1.0 2.1.1 2.2.2 2.3.3])
49
+ RAILS_VERSIONS.sort!
50
+ end
51
+
52
+ desc "Run examples with multiple versions of rails"
53
+ task :multi_rails do
54
+ RAILS_VERSIONS.each do |rails_version|
55
+ puts
56
+ sh "RAILS_VERSION='#{rails_version}' rake examples"
57
+ end
58
+ end
59
+
60
+ end
61
+
62
+ if ENV["RUN_CODE_RUN"]
63
+ task :default => [:check_dependencies, "examples:multi_rails"]
64
+ else
65
+ task :default => [:check_dependencies, :examples]
66
+ end
67
+
68
+ begin
69
+ %w{sdoc sdoc-helpers rdiscount}.each { |name| gem name }
70
+ require 'sdoc_helpers'
71
+ rescue LoadError => ex
72
+ puts "sdoc support not enabled:"
73
+ puts ex.inspect
74
+ end
75
+
76
+ require 'rake/rdoctask'
77
+ Rake::RDocTask.new do |rdoc|
78
+ version = File.exist?('VERSION') ? File.read('VERSION') : ''
79
+ rdoc.rdoc_dir = 'rdoc'
80
+ rdoc.title = "panmind-tarantula #{version}"
81
+ rdoc.rdoc_files.include('README*')
82
+ rdoc.rdoc_files.include('lib/**/*.rb')
83
+ end
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :major: 0
3
+ :minor: 3
4
+ :patch: 3
@@ -0,0 +1,57 @@
1
+ require 'rubygems'
2
+ lib_path = File.expand_path(File.dirname(__FILE__) + "/../lib")
3
+ $LOAD_PATH.unshift lib_path unless $LOAD_PATH.include?(lib_path)
4
+ require 'rubygems'
5
+ gem "micronaut", ">= 0.2.4"
6
+ gem "log_buddy"
7
+ gem "mocha"
8
+ if rails_version = ENV['RAILS_VERSION']
9
+ gem "rails", rails_version
10
+ end
11
+ require "rails/version"
12
+ if Rails::VERSION::STRING < "2.3.1" && RUBY_VERSION >= "1.9.1"
13
+ puts "Tarantula requires Rails 2.3.1 or higher for Ruby 1.9 support"
14
+ exit(1)
15
+ end
16
+ puts "==== Testing with Rails #{Rails::VERSION::STRING} ===="
17
+ gem 'actionpack'
18
+ gem 'activerecord'
19
+ gem 'activesupport'
20
+
21
+ require 'ostruct'
22
+ require 'active_support'
23
+ require 'action_controller'
24
+ require 'active_record'
25
+ require 'relevance/tarantula'
26
+ require 'micronaut'
27
+ require 'mocha'
28
+
29
+ def test_output_dir
30
+ File.join(File.dirname(__FILE__), "..", "tmp", "test_output")
31
+ end
32
+
33
+ # TODO change puts/print to use a single method for logging, which will then make the stubbing cleaner
34
+ def stub_puts_and_print(obj)
35
+ obj.stubs(:puts)
36
+ obj.stubs(:print)
37
+ end
38
+
39
+ def make_link(link, crawler=Relevance::Tarantula::Crawler.new, referrer=nil)
40
+ Relevance::Tarantula::Link.new(link, crawler, referrer)
41
+ end
42
+
43
+ def make_form(form, crawler=Relevance::Tarantula::Crawler.new, referrer=nil)
44
+ Relevance::Tarantula::Form.new(form, crawler, referrer)
45
+ end
46
+
47
+ def not_in_editor?
48
+ ['TM_MODE', 'EMACS', 'VIM'].all? { |k| !ENV.has_key?(k) }
49
+ end
50
+
51
+ Micronaut.configure do |c|
52
+ c.alias_example_to :fit, :focused => true
53
+ c.alias_example_to :xit, :disabled => true
54
+ c.mock_with :mocha
55
+ c.color_enabled = not_in_editor?
56
+ c.filter_run :focused => true
57
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "../..", "example_helper.rb"))
2
+
3
+ describe "Relevance::CoreExtensions::Object#ellipsize" do
4
+ it "converts nil to empty string" do
5
+ nil.ellipsize.should == ""
6
+ end
7
+
8
+ it "doesn't touch short strings" do
9
+ "hello".ellipsize.should == "hello"
10
+ end
11
+
12
+ it "calls inspect on non-strings" do
13
+ [1,2,3].ellipsize.should == "[1, 2, 3]"
14
+ end
15
+
16
+ it "shortens long strings and adds ..." do
17
+ "long-string".ellipsize(5).should == "long-..."
18
+ end
19
+ end
@@ -0,0 +1,8 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "../..", "example_helper.rb"))
2
+ require 'relevance/core_extensions/file'
3
+
4
+ describe "Relevance::CoreExtensions::File#extension" do
5
+ it "should return the extension without the leading dot" do
6
+ File.extension("foo.bar").should == "bar"
7
+ end
8
+ end
@@ -0,0 +1,29 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "../..", "example_helper.rb"))
2
+ require 'relevance/core_extensions/file'
3
+
4
+ describe "Relevance::CoreExtensions::Response#html?" do
5
+ before do
6
+ @response = OpenStruct.new
7
+ @response.extend(Relevance::CoreExtensions::Response)
8
+ end
9
+
10
+ it "should be html if the content-type is 'text/html'" do
11
+ @response.content_type = "text/html"
12
+ @response.should be_html
13
+ @response.content_type = "text/html;charset=iso-8859-2"
14
+ @response.should be_html
15
+ end
16
+
17
+ it "should not be html if the content-type isn't an html type" do
18
+ @response.content_type = "text/plain"
19
+ @response.should_not be_html
20
+ end
21
+
22
+ # better ideas welcome, but be careful not to
23
+ # castrate tarantula for proxies that don't set the content-type
24
+ it "should pretend we have html if the content-type is nil" do
25
+ @response.content_type = nil
26
+ @response.should be_html
27
+ end
28
+
29
+ end