Class: Arachni::Checks::XssDom

Inherits:
Arachni::Check::Base show all
Defined in:
components/checks/active/xss_dom.rb

Overview

Author:

Constant Summary

Constants included from Arachni::Check::Auditor

Arachni::Check::Auditor::DOM_ELEMENTS_WITH_INPUTS, Arachni::Check::Auditor::ELEMENTS_WITH_INPUTS, Arachni::Check::Auditor::FILE_SIGNATURES, Arachni::Check::Auditor::FILE_SIGNATURES_PER_PLATFORM, Arachni::Check::Auditor::Format, Arachni::Check::Auditor::SOURCE_CODE_SIGNATURES_PER_PLATFORM

Constants included from Arachni

BANNER, Arachni::Cookie, Form, Header, JSON, Link, LinkTemplate, NestedCookie, Severity, UIForm, UIInput, VERSION, WEBSITE, WIKI, XML

Instance Attribute Summary

Attributes included from Arachni::Check::Auditor

#framework, #page

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Arachni::Check::Base

#browser_cluster, #clean_up, elements, exempt_platforms, has_exempt_platforms?, has_platforms?, #initialize, platforms, #plugins, prefer, #preferred, preferred, #prepare, #session, supports_platforms?

Methods included from Arachni::Check::Auditor

#audit, #audit_differential, #audit_signature, #audit_timeout, #audited, #audited?, #buffered_audit, #each_candidate_dom_element, #each_candidate_element, has_timeout_candidates?, #http, #initialize, #log, #log_issue, #log_remote_file, #log_remote_file_if_exists, #match_and_log, #max_issues, #preferred, reset, #skip?, timeout_audit_run, #trace_taint, #with_browser, #with_browser_cluster

Methods inherited from Arachni::Component::Base

author, description, fullname, #shortname, shortname, shortname=, version

Methods included from Arachni::Component::Output

#depersonalize_output, #depersonalize_output?, #intercept_print_message

Methods included from UI::Output

#caller_location, #debug?, #debug_level, #debug_level_1?, #debug_level_2?, #debug_level_3?, #debug_level_4?, #debug_off, #debug_on, #disable_only_positives, #error_buffer, #error_log_fd, #error_logfile, #has_error_log?, #included, #log_error, #mute, #muted?, #only_positives, #only_positives?, #print_bad, #print_debug, #print_debug_backtrace, #print_debug_exception, #print_debug_level_1, #print_debug_level_2, #print_debug_level_3, #print_debug_level_4, #print_error, #print_error_backtrace, #print_exception, #print_info, #print_line, #print_ok, #print_status, #print_verbose, #reroute_to_file, #reroute_to_file?, reset_output_options, #set_error_logfile, #unmute, #verbose?, #verbose_off, #verbose_on

Methods included from Arachni::Component::Utilities

#read_file

Methods included from Utilities

#available_port, available_port_mutex, #bytes_to_kilobytes, #bytes_to_megabytes, #caller_name, #caller_path, #cookie_decode, #cookie_encode, #cookies_from_file, #cookies_from_parser, #cookies_from_response, #exception_jail, #exclude_path?, #follow_protocol?, #form_decode, #form_encode, #forms_from_parser, #forms_from_response, #full_and_absolute_url?, #generate_token, #get_path, #hms_to_seconds, #html_decode, #html_encode, #include_path?, #links_from_parser, #links_from_response, #normalize_url, #page_from_response, #page_from_url, #parse_set_cookie, #path_in_domain?, #path_too_deep?, #port_available?, #rand_port, #random_seed, #redundant_path?, #regexp_array_match, #remove_constants, #request_parse_body, #seconds_to_hms, #skip_page?, #skip_path?, #skip_resource?, #skip_response?, #to_absolute, #uri_decode, #uri_encode, #uri_parse, #uri_parse_query, #uri_parser, #uri_rewrite

Methods included from Arachni

URI, collect_young_objects, #get_long_win32_filename, jruby?, null_device, profile?, windows?

Constructor Details

This class inherits a constructor from Arachni::Check::Base

Class Method Details

.check_and_log(page, element) ⇒ Object



46
47
48
49
50
# File 'components/checks/active/xss_dom.rb', line 46

def self.check_and_log( page, element )
    return if !(proof = find_proof( page ))

    log vector: element, proof: proof, page: page
end

.find_proof(page) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
# File 'components/checks/active/xss_dom.rb', line 52

def self.find_proof( page )
    return if !page.body.has_html_tag?( self.tag_name )

    proof = Arachni::Parser.parse(
        page.body,
        whitelist:     [self.tag_name],
        stop_on_first: [self.tag_name]
    ).nodes_by_name( self.tag_name ).first
    return if !proof

    proof.to_html
end

.infoObject



65
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
# File 'components/checks/active/xss_dom.rb', line 65

def self.info
    {
        name:        'DOM XSS',
        description: %q{
Injects an HTML element into page DOM inputs and then parses the HTML markup of
tainted responses to look for proof of vulnerability.
},
        elements:    DOM_ELEMENTS_WITH_INPUTS,
        author:      'Tasos "Zapotek" Laskos <[email protected]>',
        version:     '0.1.4',

        issue:       {
            name:            %q{DOM-based Cross-Site Scripting (XSS)},
            description:     %q{
Client-side scripts are used extensively by modern web applications.
They perform from simple functions (such as the formatting of text) up to full
manipulation of client-side data and Operating System interaction.

Unlike traditional Cross-Site Scripting (XSS), where the client is able to inject
scripts into a request and have the server return the script to the client, DOM
XSS does not require that a request be sent to the server and may be abused entirely
within the loaded page.

This occurs when elements of the DOM (known as the sources) are able to be
manipulated to contain untrusted data, which the client-side scripts (known as the
sinks) use or execute an unsafe way.

Arachni has discovered that by inserting an HTML element into the page's DOM inputs
(sources), it was possible to then have the HTML element rendered as part of the
page by the sink.
},
            references:  {
                'WASC'  => 'http://projects.webappsec.org/w/page/13246920/Cross%20Site%20Scripting',
                'OWASP' => 'https://www.owasp.org/index.php/DOM_Based_XSS',
                'OWASP - Prevention'  => 'https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet'
            },
            tags:            %w(xss dom injection script),
            cwe:             79,
            severity:        Severity::HIGH,
            remedy_guidance: %q{
Client-side document rewriting, redirection, or other sensitive action, using
untrusted data, should be avoided wherever possible, as these may not be inspected
by server side filtering.

To remedy DOM XSS vulnerabilities where these sensitive document actions must be
used, it is essential to:

1. Ensure any untrusted data is treated as text, as opposed to being interpreted
as code or mark-up within the page.
2. Escape untrusted data prior to being used within the page. Escaping methods
will vary depending on where the untrusted data is being used.
(See references for details.)
3. Use `document.createElement`, `element.setAttribute`, `element.appendChild`,
etc. to build dynamic interfaces as opposed to HTML rendering methods such as
`document.write`, `document.writeIn`, `element.innerHTML`, or `element.outerHTML `etc.
}
        }
    }
end

.optionsObject



31
32
33
34
35
36
# File 'components/checks/active/xss_dom.rb', line 31

def self.options
    @options ||= {
        format: [ Format::APPEND ],
        submit: { taint: tag_name }
    }
end

.stringsObject



21
22
23
24
25
26
27
28
29
# File 'components/checks/active/xss_dom.rb', line 21

def self.strings
    @strings ||= [
        # Straight injection.
        tag,

        # Break out of HTML comments and text areas.
        "</textarea>-->#{tag}<!--<textarea>"
    ]
end

.tagObject



17
18
19
# File 'components/checks/active/xss_dom.rb', line 17

def self.tag
    "<#{tag_name}/>"
end

.tag_nameObject



13
14
15
# File 'components/checks/active/xss_dom.rb', line 13

def self.tag_name
    "#{shortname}_#{random_seed}"
end

Instance Method Details

#runObject



38
39
40
41
42
43
44
# File 'components/checks/active/xss_dom.rb', line 38

def run
    return if !browser_cluster

    each_candidate_dom_element do |element|
        element.audit( self.class.strings, self.class.options )
    end
end