Module: Arachni::Element::Form::Capabilities::Mutable

Includes:
Capabilities::Mutable
Defined in:
lib/arachni/element/form/capabilities/mutable.rb

Overview

Extends Capabilities::Mutable with Arachni::Element::Form-specific functionality.

Author:

  • Tasos “Zapotek” Laskos <tasos.laskos@arachni-scanner.com>

Constant Summary

Constants included from Capabilities::Mutable

Capabilities::Mutable::EXTRA_NAME, Capabilities::Mutable::FUZZ_NAME, Capabilities::Mutable::FUZZ_NAME_VALUE, Capabilities::Mutable::MUTATION_OPTIONS

Instance Attribute Summary

Attributes included from Capabilities::Mutable

#affected_input_name, #format, #seed

Instance Method Summary collapse

Methods included from Capabilities::Mutable

#affected_input_value, #affected_input_value=, #dup, #immutables, #inspect, #mutation?, #mutations, #parameter_name_audit?, #reset, #switch_method, #to_h, #to_rpc_data, #with_raw_payload, #with_raw_payload?

Instance Method Details

#each_mutation(payload, opts = {}) {|mutation| ... } ⇒ Object

Overrides Mutable#each_mutation adding support for mutations with:

  • Sample values (filled by OptionGroups::Input.fill).

  • Original values.

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

Parameters:

Options Hash (opts):

  • :skip_original (Bool)

    Whether or not to skip adding a mutation holding original values and sample values.

Yields:

  • (mutation)

    Each generated mutation.

Yield Parameters:

See Also:



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/arachni/element/form/capabilities/mutable.rb', line 66

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

    generated = Arachni::Support::LookUp::HashSet.new( hasher: :mutable_id )

    # Completely remove fake inputs prior to mutation generation, they'll
    # be restored at the end of this method.
    pre_inputs = @inputs
    @inputs    = @inputs.reject{ |name, _| fake_field?( name ) }

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

    return if opts[:skip_original]

    elem = self.dup
    elem.mutation_with_original_values
    elem.affected_input_name = ORIGINAL_VALUES
    yield elem if !generated.include?( elem )
    generated << elem

    # Default select values, in case they reveal new resources.
    inputs.keys.each do |input|
        next if field_type_for( input ) != :select

        # We do the break inside the loop because #node is lazy parsed
        # and we don't want to parse it unless we have a select input.
        break if !node

        node.nodes_by_name( 'select' ).each do |select_node|
            next if select_node['name'] != input

            select_node.children.each do |child|
                next if !child.is_a?( Arachni::Parser::Nodes::Element ) ||
                    child.name != :option

                try_input do
                    elem = self.dup
                    elem.mutation_with_original_values
                    elem.affected_input_name  = input
                    elem.affected_input_value = child['value'] || child.text.strip
                    yield elem if !generated.include?( elem )
                    generated << elem
                end
            end
        end
    end

    try_input do
        # Sample values, in case they reveal new resources.
        elem = self.dup
        elem.inputs = Arachni::Options.input.fill( inputs.dup )
        elem.affected_input_name = SAMPLE_VALUES
        elem.mutation_with_sample_values
        yield elem if !generated.include?( elem )
        generated << elem
    end
ensure
    @inputs = pre_inputs
end

#mutation_with_original_valuesObject



26
27
28
# File 'lib/arachni/element/form/capabilities/mutable.rb', line 26

def mutation_with_original_values
    @mutation_with_original_values = true
end

#mutation_with_original_values?Bool

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

Returns:

  • (Bool)

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



22
23
24
# File 'lib/arachni/element/form/capabilities/mutable.rb', line 22

def mutation_with_original_values?
    !!@mutation_with_original_values
end

#mutation_with_sample_valuesObject



39
40
41
# File 'lib/arachni/element/form/capabilities/mutable.rb', line 39

def mutation_with_sample_values
    @mutation_with_sample_values = true
end

#mutation_with_sample_values?Bool

Returns `true` if the element has been populated with sample (OptionGroups::Input.fill) values, `false` otherwise.

Returns:

  • (Bool)

    `true` if the element has been populated with sample (OptionGroups::Input.fill) values, `false` otherwise.

See Also:



35
36
37
# File 'lib/arachni/element/form/capabilities/mutable.rb', line 35

def mutation_with_sample_values?
    !!@mutation_with_sample_values
end