Class: Arachni::Element::Form

Inherits:
Base show all
Includes:
Capabilities::Refreshable
Defined in:
lib/arachni/element/form.rb

Defined Under Namespace

Classes: Error

Constant Summary collapse

ORIGINAL_VALUES =
'__original_values__'
SAMPLE_VALUES =
'__sample_values__'

Constants included from Capabilities::Auditable

Capabilities::Auditable::OPTIONS

Constants included from Capabilities::Auditable::RDiff

Capabilities::Auditable::RDiff::RDIFF_OPTIONS

Constants included from Capabilities::Auditable::Taint

Capabilities::Auditable::Taint::REMARK, Capabilities::Auditable::Taint::TAINT_OPTIONS

Constants included from Capabilities::Mutable

Capabilities::Mutable::MUTATION_OPTIONS

Instance Attribute Summary collapse

Attributes inherited from Base

#raw

Attributes included from Capabilities::Auditable

#auditor, #opts, #orig

Attributes included from Capabilities::Mutable

#altered

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Capabilities::Refreshable

#refresh

Methods inherited from Base

#action, #action=, #method, #method=, #platforms, #url, #url=

Methods included from Utilities

#available_port, #cookie_encode, #cookies_from_document, #cookies_from_file, #cookies_from_response, #exception_jail, #exclude_path?, #extract_domain, #follow_protocol?, #form_decode, #form_encode, #form_parse_request_body, #forms_from_document, #forms_from_response, #generate_token, #get_path, #html_decode, #html_encode, #include_path?, #links_from_document, #links_from_response, #normalize_url, #page_from_response, #page_from_url, #parse_query, #parse_set_cookie, #parse_url_vars, #path_in_domain?, #path_too_deep?, #port_available?, #rand_port, #redundant_path?, #remove_constants, #seed, #skip_page?, #skip_path?, #skip_resource?, #to_absolute, #uri_decode, #uri_encode, #uri_parse, #uri_parser, #url_sanitize

Methods included from Capabilities::Auditable

#==, #[], #[]=, #audit, #auditable, #auditable=, #changes, #debug?, #has_inputs?, #hash, #http, #matches_skip_like_blocks?, #orphan?, #override_instance_scope, #override_instance_scope?, #print_bad, #print_debug, #print_debug_backtrace, #print_error, #print_error_backtrace, #print_info, #print_line, #print_ok, #print_status, #provisioned_issue_id, #remove_auditor, #reset, reset, reset_instance_scope, #reset_scope_override, restrict_to_elements, #scope_audit_id, skip_like, #status_string, #submit, #update, #use_anonymous_auditor

Methods included from Capabilities::Auditable::RDiff

#rdiff_analysis

Methods included from Capabilities::Auditable::Timeout

add_timeout_candidate, add_timeout_phase3_candidate, #call_on_timing_blocks, call_on_timing_blocks, current_timeout_audit_operations_cnt, deduplicate?, #deduplicate?, #disable_deduplication, disable_deduplication, enable_deduplication, #enable_deduplication, included, on_timing_attacks, reset, #responsive?, running_timeout_attacks?, #timeout_analysis, timeout_analysis_phase_2, timeout_analysis_phase_3, timeout_audit_operations_cnt, timeout_audit_run, timeout_candidates, timeout_loaded_modules

Methods included from Capabilities::Auditable::Taint

#taint_analysis

Methods included from Capabilities::Mutable

#altered_value, #altered_value=, #immutables, #mutated?, #mutations, #mutations_for, #permutations, #permutations_for, #switch_method

Constructor Details

#initialize(url, raw = {}) ⇒ Form

Creates a new Form element from a URL and auditable data.

Parameters:

  • url (String)

    Owner URL – URL of the page which contains the form.

  • raw (Hash) (defaults to: {})

    If empty, the element will be initialized without auditable inputs.

    If a full ‘Hash` is passed, it will look for an actionable URL `String` in the following keys:

    • ‘’href’‘

    • ‘:href`

    • ‘’action’‘

    • ‘:action`

    For an method ‘String` in:

    • ‘’method’‘

    • ‘:method`

    Method defaults to ‘get’.

    For an auditable inputs ‘Hash` in:

    • ‘’inputs’‘

    • ‘:inputs`

    • ‘’auditable’‘

    these should contain inputs in ‘name => value` pairs.



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/arachni/element/form.rb', line 84

def initialize( url, raw = {} )
    super( url, raw )

    was_opts_hash = false
    begin
        self.action = @raw['action'] || @raw[:action] || @raw['attrs']['action']
        was_opts_hash = true
    rescue
        self.action = self.url
    end

    begin
        self.method = @raw['method'] || @raw[:method] || @raw['attrs']['method']
        was_opts_hash = true
    rescue
        self.method = 'get'
    end

    if !was_opts_hash && (@raw.keys & [:inputs, 'inputs', 'auditable']).empty?
        self.auditable = @raw
    else
        self.auditable = @raw[:inputs] || @raw['inputs'] || simple['auditable']
    end

    self.auditable ||= {}

    @orig = self.auditable.dup
    @orig.freeze
end

Instance Attribute Details

#nodeNokogiri::XML::Element

Returns:

  • (Nokogiri::XML::Element)


51
52
53
# File 'lib/arachni/element/form.rb', line 51

def node
  @node
end

#nonce_nameString

Returns the name of the input name that holds the nonce.

Returns:

  • (String)

    the name of the input name that holds the nonce



48
49
50
# File 'lib/arachni/element/form.rb', line 48

def nonce_name
  @nonce_name
end

Class Method Details

.decode(str) ⇒ String

Decodes a String encoded for an HTTP request’s body.

Examples:

p Form.decode "%2B%25+%3B%26%5C%3D%5C0"
#=> "+% ;&\\=\\0"

Parameters:

Returns:



814
815
816
# File 'lib/arachni/element/form.rb', line 814

def self.decode( str )
    URI.decode( str.to_s.recode.gsub( '+', ' ' ) )
end

.encode(str) ⇒ String

Encodes a String‘s reserved characters in order to prepare it to be included in a request body.

#example

p Form.encode "+% ;&\\=\0"
#=> "%2B%25+%3B%26%5C%3D%00"

Parameters:

Returns:



795
796
797
# File 'lib/arachni/element/form.rb', line 795

def self.encode( str )
    ::URI.encode( ::URI.encode( str, '+%' ).recode.gsub( ' ', '+' ), ";&\\=\0" )
end

.from_document(url, document) ⇒ Array<Form>

Extracts forms from an HTML document.

Examples:

html_form = <<-HTML
<form action='/submit'>
    <input type='text' name='text-input' />
</form>
HTML

ap Form.from_document( 'http://stuff.com', html_form ).first
#=> #<Arachni::Element::Form:0x03123600
#    attr_accessor :action = "http://stuff.com/submit",
#    attr_accessor :auditable = {
#        "text-input" => ""
#    },
#    attr_accessor :method = "get",
#    attr_accessor :url = "http://stuff.com/",
#    attr_reader :hash = 3370163854416367834,
#    attr_reader :opts = {},
#    attr_reader :orig = {
#        "text-input" => ""
#    },
#    attr_reader :raw = {
#            "attrs" => {
#            "action" => "http://stuff.com/submit",
#            "method" => "get"
#        },
#         "textarea" => [],
#            "input" => [
#            [0] {
#                "type" => "text",
#                "name" => "text-input"
#            }
#        ],
#           "select" => [],
#        "auditable" => [
#            [0] {
#                "type" => "text",
#                "name" => "text-input"
#            }
#        ]
#    }
#>

ap Form.from_document( 'http://stuff.com', Nokogiri::HTML( html_form ) ).first
#=> #<Arachni::Element::Form:0x03123600
#    attr_accessor :action = "http://stuff.com/submit",
#    attr_accessor :auditable = {
#        "text-input" => ""
#    },
#    attr_accessor :method = "get",
#    attr_accessor :url = "http://stuff.com/",
#    attr_reader :hash = 3370163854416367834,
#    attr_reader :opts = {},
#    attr_reader :orig = {
#        "text-input" => ""
#    },
#    attr_reader :raw = {
#            "attrs" => {
#            "action" => "http://stuff.com/submit",
#            "method" => "get"
#        },
#         "textarea" => [],
#            "input" => [
#            [0] {
#                "type" => "text",
#                "name" => "text-input"
#            }
#        ],
#           "select" => [],
#        "auditable" => [
#            [0] {
#                "type" => "text",
#                "name" => "text-input"
#            }
#        ]
#    }
#>

Parameters:

  • url (String)

    URL of the document – used for path normalization purposes.

  • document (String, Nokogiri::HTML::Document)

Returns:



737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
# File 'lib/arachni/element/form.rb', line 737

def self.from_document( url, document )
    document = Nokogiri::HTML( document.to_s ) if !document.is_a?( Nokogiri::HTML::Document )

    base_url = document.search( '//base[@href]' )[0]['href'] rescue nil
    base_url = url if base_url.to_s.empty?

    document.search( '//form' ).map do |cform|
        next if !(form = form_from_element( base_url, cform ))
        form.url = url

        # We do it this way to remove references to parents etc.
        form.node = Nokogiri::HTML.fragment( cform.to_html ).css( 'form' ).first

        form
    end.compact
end

.from_response(response) ⇒ Array<Form>

Extracts forms by parsing the body of an HTTP response.

Examples:

body = <<-HTML
   <form action='/submit'>
        <input type='text' name='text-input' />
   </form>
HTML

res = Typhoeus::Response.new( effective_url: 'http://host', body: body )

ap Form.from_response( res ).first
#=> #<Arachni::Element::Form:0x017c7788
#    attr_accessor :action = "http://host/submit",
#    attr_accessor :auditable = {
#        "text-input" => ""
#    },
#    attr_accessor :method = "get",
#    attr_accessor :url = "http://host/",
#    attr_reader :hash = 343244616730070569,
#    attr_reader :opts = {},
#    attr_reader :orig = {
#        "text-input" => ""
#    },
#    attr_reader :raw = {
#            "attrs" => {
#            "action" => "http://host/submit",
#            "method" => "get"
#        },
#         "textarea" => [],
#            "input" => [
#            [0] {
#                "type" => "text",
#                "name" => "text-input"
#            }
#        ],
#           "select" => [],
#        "auditable" => [
#            [0] {
#                "type" => "text",
#                "name" => "text-input"
#            }
#        ]
#    }
#>

Parameters:

Returns:



646
647
648
# File 'lib/arachni/element/form.rb', line 646

def self.from_response( response )
    from_document( response.effective_url, response.body )
end

.parse_request_body(body) ⇒ Hash

Parses an HTTP request body generated by submitting a form.

Examples:

Simple

p Form.parse_request_body 'first_name=John&last_name=Doe'
#=> {"first_name"=>"John", "last_name"=>"Doe"}

Weird

body = 'testID=53738&deliveryID=53618&testIDs=&deliveryIDs=&selectedRows=2' +
    '&event=&section=&event%3Dmanage%26amp%3Bsection%3Dexam=Manage+selected+exam'
p Form.parse_request_body body
#=> {"testID"=>"53738", "deliveryID"=>"53618", "testIDs"=>"", "deliveryIDs"=>"", "selectedRows"=>"2", "event"=>"", "section"=>"", "event=manage&amp;section=exam"=>"Manage selected exam"}

Parameters:

Returns:

  • (Hash)

    Parameters.



771
772
773
774
775
776
777
# File 'lib/arachni/element/form.rb', line 771

def self.parse_request_body( body )
    body.to_s.split( '&' ).inject( {} ) do |h, pair|
        name, value = pair.split( '=', 2 )
        h[decode( name.to_s )] = decode( value )
        h
    end
end

Instance Method Details

#audit_id(injection_str = '', opts = {}) ⇒ Object



392
393
394
395
396
397
398
399
400
401
402
403
404
# File 'lib/arachni/element/form.rb', line 392

def audit_id( injection_str = '', opts = {} )
    str = if original?
              opts[:no_auditor] = true
              ORIGINAL_VALUES
          elsif sample?
              opts[:no_auditor] = true
              SAMPLE_VALUES
          else
              injection_str
          end

    super( str, opts )
end

#decode(str) ⇒ Object

See Also:



818
819
820
# File 'lib/arachni/element/form.rb', line 818

def decode( str )
    self.class.decode( str )
end

#dupObject



822
823
824
825
826
827
# File 'lib/arachni/element/form.rb', line 822

def dup
    super.tap do |f|
        f.nonce_name = nonce_name.dup if nonce_name
        f.requires_password = requires_password?
    end
end

#each_mutation(seed, opts = {}) {|elem| ... } ⇒ Object

Overrides Mutable#each_mutation adding support for mutations with:

  • Sample values (filled by Support::KeyFiller.fill).

  • Original values.

  • Password fields requiring identical values (in order to pass server-side validation).

Parameters:

Yields:

  • (elem)
  • (mutation)

    Each generated mutation.

Yield Parameters:

  • (Mutable)

See Also:



421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
# File 'lib/arachni/element/form.rb', line 421

def each_mutation( seed, opts = {} )
    opts = MUTATION_OPTIONS.merge( opts )

    generated = Arachni::Support::LookUp::HashSet.new

    super( seed, opts ) do |elem|
        elem.mirror_password_fields
        yield elem if !generated.include?( elem )
        generated << elem
    end

    return if opts[:skip_orig]

    # this is the original hash, in case the default values
    # are valid and present us with new attack vectors
    elem = self.dup
    elem.altered = ORIGINAL_VALUES
    yield elem if !generated.include?( elem )
    generated << elem

    elem = self.dup
    elem.auditable = Arachni::Support::KeyFiller.fill( auditable.dup )
    elem.altered = SAMPLE_VALUES
    yield elem if !generated.include?( elem )
    generated << elem
end

#encode(str) ⇒ Object

See Also:



799
800
801
# File 'lib/arachni/element/form.rb', line 799

def encode( str )
    self.class.encode( str )
end

#field_type_for(name) ⇒ String

Retrieves a field type for the given field ‘name`.

Examples:

html_form = <<-HTML
<form>
    <input type='text' name='text-input' />
    <input type='password' name='passwd' />
    <input type='hidden' name='cant-see-this' />
</form>
HTML

f = Form.from_document( 'http://stuff.com', html_form ).first

p f.field_type_for 'text-input'
#=> "text"

p f.field_type_for 'passwd'
#=> "password"

p f.field_type_for 'cant-see-this'
#=> "hidden"

Parameters:

  • name (String)

    Field name.

Returns:



564
565
566
567
568
569
570
571
# File 'lib/arachni/element/form.rb', line 564

def field_type_for( name )
    return if !@raw['auditable']

    field = @raw['auditable'].select { |f| f['name'] == name }.first
    return if !field

    field['type'].to_s.downcase
end

#has_nonce?Bool

Returns ‘true` if the form contains a nonce, `false` otherwise.

Examples:

f = Form.new( 'http://stuff.com', { nonce_input: '' } )
p f.has_nonce?
#=> false

f.nonce_name = 'nonce_input'
p f.has_nonce?
#=> true

Returns:

  • (Bool)

    ‘true` if the form contains a nonce, `false` otherwise.



509
510
511
# File 'lib/arachni/element/form.rb', line 509

def has_nonce?
    !!nonce_name
end

#idString

Returns Unique form ID.

Examples:

p f = Form.new( 'http://stuff.com', inputs: { name: 'value' } )
#=> #<Arachni::Element::Form:0x00000002190f80 @raw={:inputs=>{:name=>"value"}}, @url="http://stuff.com/", @hash=-432844557667991308, @opts={}, @action="http://stuff.com/", @method="post", @auditable={"name"=>"value"}, @orig={"name"=>"value"}>

p f.action
#=> "http://stuff.com/"

p f.method
#=> "post"

p f.auditable.keys
#=> ["name"]

p f.id
#=> "http://stuff.com/::post::[\"name\"]"

Returns:

  • (String)

    Unique form ID.



167
168
169
# File 'lib/arachni/element/form.rb', line 167

def id
    id_from :auditable
end

#id_from(type = :auditable) ⇒ Object

Examples:

ap f = Form.new( 'http://stuff.com', inputs: { name: 'value' } )
#=> #<Arachni::Element::Form:0x01da8d78
#     attr_accessor :action = "http://stuff.com/",
#     attr_accessor :auditable = {
#         "name" => "value"
#     },
#     attr_accessor :method = "get",
#     attr_accessor :url = "http://stuff.com/",
#     attr_reader :hash = -277024459210456651,
#     attr_reader :opts = {},
#     attr_reader :orig = {
#         "name" => "value"
#     },
#     attr_reader :raw = {
#         :inputs => {
#             :name => "value"
#         }
#     }
# >

p f.action
#=> "http://stuff.com/"

p f.method
#=> "post"

p f.auditable.keys
#=> ["name"]

p f.id_from :auditable
#=> "http://stuff.com/::post::[\"name\"]"

p f.id
#=> "http://stuff.com/::post::[\"name\"]"

p f.id_from :original
#=> "http://stuff.com/::post::[\"name\"]"

f['new-input'] = 'new value'

p f.id_from :auditable
#=> "http://stuff.com/::post::[\"name\", \"new-input\"]"

p f.id
#=> "http://stuff.com/::post::[\"name\", \"new-input\"]"

p f.id_from :original
#=> "http://stuff.com/::post::[\"name\"]"


222
223
224
225
226
# File 'lib/arachni/element/form.rb', line 222

def id_from( type = :auditable )
    query_vars = parse_url_vars( self.action )
    "#{self.action.split( '?' ).first.to_s.split( ';' ).first}::" <<
        "#{self.method}::#{query_vars.merge( self.send( type ) ).keys.compact.sort.to_s}"
end

#marshal_dumpObject



578
579
580
581
582
583
584
585
586
587
588
# File 'lib/arachni/element/form.rb', line 578

def marshal_dump
    instance_variables.inject( {} ) do |h, iv|
        if iv == :@node
            h[iv] = instance_variable_get( iv ).to_s
        else
            h[iv] = instance_variable_get( iv )
        end

        h
    end
end

#marshal_load(h) ⇒ Object



590
591
592
593
# File 'lib/arachni/element/form.rb', line 590

def marshal_load( h )
    self.node = Nokogiri::HTML( h.delete(:@node) ).css('form').first
    h.each { |k, v| instance_variable_set( k, v ) }
end

#mirror_password_fieldsObject



448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
# File 'lib/arachni/element/form.rb', line 448

def mirror_password_fields
    return if !requires_password?

    # if there are two password type fields in the form there's a good
    # chance that it's a 'please retype your password' thing so make sure
    # that we have a variation which has identical password values
    password_fields = auditable.keys.
        select { |input| field_type_for( input ) == 'password' }

    return if password_fields.size != 2

    self[password_fields[0]] = self[password_fields[1]]

    nil
end

#nameString?

Returns Name of the form, if it has one.

Examples:

p f = Form.from_document( 'http://stuff.com', '<form name="stuff"></form>' ).first
#=> #<Arachni::Element::Form:0x00000001ddfa08 @raw={"attrs"=>{"name"=>"stuff", "action"=>"http://stuff.com/", "method"=>"get"}, "textarea"=>[], "input"=>[], "select"=>[], "auditable"=>[]}, @url="http://stuff.com/", @hash=1935432807676141374, @opts={}, @action="http://stuff.com/", @method="get", @auditable={}, @orig={}>

p f.name
#=> "stuff"

p f = Form.new( 'http://stuff.com', 'attrs' => { 'name' => 'john' } )
#=> #<Arachni::Element::Form:0x00000002b46160 @raw={"attrs"=>{"name"=>"john"}}, @url="http://stuff.com/", @hash=2710248079644781147, @opts={}, @action="http://stuff.com/", @method=nil, @auditable={}, @orig={}>

p f.name
#=> "john"

p Form.new( 'http://stuff.com' ).name
#=> nil

Returns:

  • (String, nil)

    Name of the form, if it has one.



138
139
140
141
# File 'lib/arachni/element/form.rb', line 138

def name
    return if !@raw['attrs'].is_a?( Hash )
    @raw['attrs']['name']
end

#name_or_idObject



143
144
145
146
# File 'lib/arachni/element/form.rb', line 143

def name_or_id
    return if !@raw['attrs'].is_a?( Hash )
    name || @raw['attrs']['id']
end

#original?Bool

Returns ‘true` if the element has not been mutated, `false` otherwise.

Examples:

mutations = Form.new( 'http://stuff.com', inputs: { name: 'value' } ).mutations( 'seed' )

# mutations generally have seeds injected into their auditable inputs
ap mutations.first
#=> <Arachni::Element::Form:0x0327fdf0
#    attr_accessor :action = "http://stuff.com/",
#    attr_accessor :altered = "name",
#    attr_accessor :auditable = {
#        "name" => "seed"
#    },
#    attr_accessor :auditor = nil,
#    attr_accessor :method = "get",
#    attr_accessor :url = "http://stuff.com/",
#    attr_reader :hash = -3646163768215054761,
#    attr_reader :opts = {},
#    attr_reader :orig = {
#        "name" => "value"
#    },
#    attr_reader :raw = {
#        :inputs => {
#            :name => "value"
#        }
#    }
#>

p mutations.first.original?
#=> false

# but forms need to also be submitted with their default values
# for training purposes
ap original = mutations.select { |m| m.altered == Form::ORIGINAL_VALUES }.first
#=> #<Arachni::Element::Form:0x022a5a60
#     attr_accessor :action = "http://stuff.com/",
#     attr_accessor :altered = "__original_values__",
#     attr_accessor :auditable = {
#         "name" => "value"
#     },
#     attr_accessor :auditor = nil,
#     attr_accessor :method = "get",
#     attr_accessor :url = "http://stuff.com/",
#     attr_reader :hash = -608155834642701428,
#     attr_reader :opts = {},
#     attr_reader :orig = {
#         "name" => "value"
#     },
#     attr_reader :raw = {
#         :inputs => {
#             :name => "value"
#         }
#     }
# >

p original.original?
#=> true

Returns:

  • (Bool)

    ‘true` if the element has not been mutated, `false` otherwise.



324
325
326
# File 'lib/arachni/element/form.rb', line 324

def original?
    self.altered == ORIGINAL_VALUES
end

#parse_request_body(body) ⇒ Object

See Also:



779
780
781
# File 'lib/arachni/element/form.rb', line 779

def parse_request_body( body )
    self.class.parse_request_body( body )
end

#requires_password?Bool

Checks whether or not the form contains 1 or more password fields.

Examples:

With password

html_form = <<-HTML
   <form>
        <input type='password' name='pasword' />
   </form>
HTML

p Form.from_document( 'http://stuff.com', html_form ).first.requires_password?
#=> true

Without password

html_form = <<-HTML
   <form>
        <input type='text' name='stuff' />
   </form>
HTML

p Form.from_document( 'http://stuff.com', html_form ).first.requires_password?
#=> false

Returns:

  • (Bool)

    ‘true` if the form contains passwords fields, `false` otherwise.



490
491
492
493
494
495
# File 'lib/arachni/element/form.rb', line 490

def requires_password?
    return @requires_password if !@requires_password.nil?

    return @requires_password = false if !self.raw.is_a?( Hash ) || !self.raw['input'].is_a?( Array )
    @requires_password = self.raw['input'].select { |i| i['type'] == 'password' }.any?
end

#sample?Bool

Returns ‘true` if the element has been populated with sample (Support::KeyFiller) values, `false` otherwise.

Examples:

mutations = Form.new( 'http://stuff.com', inputs: { name: '' } ).mutations( 'seed' )

# mutations generally have seeds injected into their auditable inputs
ap mutations.first
#=> <Arachni::Element::Form:0x0327fdf0
#    attr_accessor :action = "http://stuff.com/",
#    attr_accessor :altered = "name",
#    attr_accessor :auditable = {
#        "name" => "seed"
#    },
#    attr_accessor :auditor = nil,
#    attr_accessor :method = "get",
#    attr_accessor :url = "http://stuff.com/",
#    attr_reader :hash = -3646163768215054761,
#    attr_reader :opts = {},
#    attr_reader :orig = {
#        "name" => "value"
#    },
#    attr_reader :raw = {
#        :inputs => {
#            :name => "value"
#        }
#    }
#>

# when values are missing the inputs are filled in using sample values
ap sample = mutations.select { |m| m.altered == Form::SAMPLE_VALUES }.first
#=> #<Arachni::Element::Form:0x02b23020
#     attr_accessor :action = "http://stuff.com/",
#     attr_accessor :altered = "__sample_values__",
#     attr_accessor :auditable = {
#         "name" => "arachni_name"
#     },
#     attr_accessor :auditor = nil,
#     attr_accessor :method = "get",
#     attr_accessor :url = "http://stuff.com/",
#     attr_reader :hash = 205637814585882034,
#     attr_reader :opts = {},
#     attr_reader :orig = {
#         "name" => ""
#     },
#     attr_reader :raw = {
#         :inputs => {
#             :name => ""
#         }
#     }
# >

p sample.sample?
#=> true

Returns:

  • (Bool)

    ‘true` if the element has been populated with sample (Support::KeyFiller) values, `false` otherwise.

See Also:



388
389
390
# File 'lib/arachni/element/form.rb', line 388

def sample?
    self.altered == SAMPLE_VALUES
end

#simpleHash

Returns a simple representation of self including attributes and auditables.

Examples:

p Form.new( 'http://stuff.com', inputs: { name: 'value' } ).simple
#=> {"auditable"=>{"name"=>"value"}, "attrs"=>{"method"=>"post", "action"=>"http://stuff.com/"}}

p Form.new( 'http://stuff.com', method: 'post', inputs: { name: 'value' } ).simple
#=> {"auditable"=>{"name"=>"value"}, "attrs"=>{"method"=>'post', "action"=>"http://stuff.com/"}}

Returns:

  • (Hash)

    a simple representation of self including attributes and auditables



238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/arachni/element/form.rb', line 238

def simple
    form = {}

    form['auditable'] = {}
    if @raw['auditable'] && !@raw['auditable'].empty?
        @raw['auditable'].each do |item|
            next if !item['name']
            form['auditable'][item['name']] = item['value']
        end
    end

    if @raw['attrs']
        form['attrs'] = @raw['attrs']
    else
        form['attrs'] = {
            'method' => @method,
            'action' => @action
        }
    end

    if form['auditable'].empty? && @auditable && !@auditable.empty?
        form['auditable'] = @auditable
    end

    form.dup
end

#to_htmlObject



114
115
116
117
# File 'lib/arachni/element/form.rb', line 114

def to_html
    return if !node
    node.to_html
end

#typeString

Returns ‘form’.

Returns:



574
575
576
# File 'lib/arachni/element/form.rb', line 574

def type
    Arachni::Element::FORM
end