lib/relevance/tarantula/form_submission.rb in tarantula-0.2.0 vs lib/relevance/tarantula/form_submission.rb in tarantula-0.3.3

- old
+ new

@@ -1,27 +1,60 @@ class Relevance::Tarantula::FormSubmission - attr_accessor :method, :action, :data - def initialize(form) + include Relevance::Tarantula + attr_accessor :method, :action, :data, :attack, :form + + class << self + def attacks + # normalize from hash input to Attack + @attacks = @attacks.map do |val| + Hash === val ? Relevance::Tarantula::Attack.new(val) : val + end + @attacks + end + def attacks=(atts) + # normalize from hash input to Attack + @attacks = atts.map do |val| + Hash === val ? Relevance::Tarantula::Attack.new(val) : val + end + end + end + @attacks = [Relevance::Tarantula::BasicAttack.new] + + def initialize(form, attack = Relevance::Tarantula::BasicAttack.new) + @form = form @method = form.method @action = form.action + @attack = attack @data = mutate_selects(form).merge(mutate_text_areas(form)).merge(mutate_inputs(form)) end + def crawl + begin + response = form.crawler.submit(method, action, data) + log "Response #{response.code} for #{self}" + rescue ActiveRecord::RecordNotFound => e + log "Skipping #{action}, presumed ok that record is missing" + response = Relevance::Tarantula::Response.new(:code => "404", :body => e.message, :content_type => "text/plain") + end + form.crawler.handle_form_results(self, response) + response + end + def self.mutate(form) - [self.new(form)] + attacks.map{|attack| new(form, attack)} if attacks end - + def to_s - "#{action} #{method} #{data.inspect}" + "#{action} #{method} #{data.inspect} #{attack.inspect}" end - + # a form's signature is what makes it unique (e.g. action + fields) # used to keep track of which forms we have submitted already def signature - [action, data.keys.sort] + [action, data.keys.sort, attack.name] end - + def create_random_data_for(form, tag_selector) form.search(tag_selector).inject({}) do |form_args, input| # TODO: test form_args[input['name']] = random_data(input) if input['name'] form_args @@ -33,38 +66,23 @@ end def mutate_text_areas(form) create_random_data_for(form, 'textarea') end - + def mutate_selects(form) form.search('select').inject({}) do |form_args, select| options = select.search('option') option = options.rand - form_args[select['name']] = option['value'] + form_args[select['name']] = option['value'] form_args end end - + def random_data(input) case input['name'] - when /amount/ : random_int - when /_id$/ : random_whole_number - when /uploaded_data/ : nil - when /^_method$/ : input['value'] - when nil : input['value'] - else random_int + when /^_method$/ then input['value'] + else + attack.input(input) end - end - - def big_number - 10000 # arbitrary - end - - def random_int - rand(big_number) - (big_number/2) - end - - def random_whole_number - rand(big_number) end end