Class: Arachni::Element::Cookie
- Defined in:
- lib/arachni/element/cookie.rb
Overview
Represents a Cookie object and provides helper class methods for parsing, encoding, etc.
Constant Summary collapse
- DEFAULT =
Default cookie values
{ "name" => nil, "value" => nil, "version" => 0, "port" => nil, "discard" => nil, "comment_url" => nil, "expires" => nil, "max_age" => nil, "comment" => nil, "secure" => nil, "path" => nil, "domain" => nil, "httponly" => false }
Constants included from Arachni::Element::Capabilities::Auditable
Arachni::Element::Capabilities::Auditable::OPTIONS
Constants included from Arachni::Element::Capabilities::Auditable::RDiff
Arachni::Element::Capabilities::Auditable::RDiff::RDIFF_OPTIONS
Constants included from Arachni::Element::Capabilities::Auditable::Taint
Arachni::Element::Capabilities::Auditable::Taint::TAINT_OPTIONS
Constants included from Arachni::Element::Capabilities::Mutable
Arachni::Element::Capabilities::Mutable::MUTATION_OPTIONS
Instance Attribute Summary
Attributes inherited from Base
Attributes included from Arachni::Element::Capabilities::Auditable
Attributes included from Arachni::Element::Capabilities::Mutable
Class Method Summary collapse
-
.decode(str) ⇒ String
Decodes a String encoded for the
Cookieheader field. -
.encode(str) ⇒ String
Encodes a String‘s reserved characters in order to prepare it for the ’Cookie’ header field.
-
.expires_to_time(expires) ⇒ Time
Converts a cookie’s expiration date to a Ruby
Timeobject. -
.from_document(url, document) ⇒ Array<Cookie>
Returns an array of cookies from a document based on
Set-Cookiehttp-equiv meta tags. -
.from_file(url, filepath) ⇒ Array<Cookie>
Returns an array of cookies from an Netscape HTTP cookiejar file.
-
.from_headers(url, headers) ⇒ Array<Cookie>
Returns an array of cookies from the
Set-Cookieheader field. -
.from_response(response) ⇒ Array<Cookie>
Returns an array of cookies from an HTTP response.
-
.from_set_cookie(url, str) ⇒ Array<Cookie>
Parses the
Set-Cookieheader value into cookie elements. - .parse_set_cookie(*args) ⇒ Object
Instance Method Summary collapse
-
#audit(*args) ⇒ Object
Overrides Arachni::Element::Capabilities::Auditable#audit to enforce cookie exclusion settings from Options#exclude_cookies.
-
#auditable=(inputs) ⇒ Object
Sets auditable inputs as a key=>value pair.
- #decode(str) ⇒ Object
- #dup ⇒ Object
- #encode(str) ⇒ Object
-
#expired?(time = Time.now) ⇒ Boolean
Indicates whether or not the cookie has expired.
-
#expires_at ⇒ Time, NilClass
Expiration
Timeof the cookie ornilif it doesn’t have one (i.e. is a session cookie). -
#http_only? ⇒ Bool
Indicates whether the cookie is safe from modification from client-side code.
-
#initialize(url, raw = {}) ⇒ Cookie
constructor
A new instance of Cookie.
-
#method_missing(sym, *args, &block) ⇒ Object
Uses the method name as a key to cookie attributes in DEFAULT.
-
#mutations(injection_str, opts = {}) ⇒ Object
Overrides Arachni::Element::Capabilities::Mutable#mutations to handle cookie-specific limitations and the Options#audit_cookies_extensively option.
-
#respond_to?(sym) ⇒ Bool
Used by #method_missing to determine if it should process the call.
-
#secure? ⇒ Bool
Indicates whether the cookie must be only sent over an encrypted channel.
-
#session? ⇒ Bool
Indicates whether the cookie is to be discarded at the end of the session.
-
#simple ⇒ Hash
Simple representation of the cookie as a hash with the cookie name as key and the cookie value as value.
-
#to_s ⇒ String
To be used in a ‘Cookie’ request header.
-
#type ⇒ String
Name of the current element, ‘cookie’ in this case.
Methods inherited from Base
#action, #action=, #id, #method, #method=, #url, #url=
Methods included from Utilities
#cookie_encode, #cookies_from_document, #cookies_from_file, #cookies_from_response, #exception_jail, #exclude_path?, #extract_domain, #form_decode, #form_encode, #form_parse_request_body, #forms_from_document, #forms_from_response, #get_path, #hash_keys_to_str, #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?, #remove_constants, #seed, #skip_path?, #to_absolute, #uri_decode, #uri_encode, #uri_parse, #uri_parser, #url_sanitize
Methods included from Arachni::Element::Capabilities::Auditable
#==, #[], #[]=, #audit_id, #auditable, #changes, #debug?, #has_inputs?, #hash, #http, #info, #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?, #skip_path?, #status_string, #submit, #update
Methods included from Arachni::Element::Capabilities::Auditable::RDiff
Methods included from Arachni::Element::Capabilities::Auditable::Timeout
add_timeout_audit_block, add_timeout_candidate, #call_on_timing_blocks, call_on_timing_blocks, current_timeout_audit_operations_cnt, included, on_timing_attacks, #responsive?, running_timeout_attacks?, #timeout_analysis, timeout_analysis_phase_2, timeout_audit_blocks, timeout_audit_operations_cnt, timeout_audit_run, timeout_loaded_modules
Methods included from Arachni::Element::Capabilities::Auditable::Taint
Methods included from Arachni::Element::Capabilities::Mutable
#altered_value, #altered_value=, #immutables, #mutated?, #mutations_for, #original?, #permutations, #permutations_for
Constructor Details
#initialize(url, raw = {}) ⇒ Cookie
Returns a new instance of Cookie.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/arachni/element/cookie.rb', line 52 def initialize( url, raw = {} ) super( url, raw ) self.action = @url self.method = 'get' @raw ||= {} if @raw['name'] && @raw['value'] self.auditable = { @raw['name'] => @raw['value'] } else self.auditable = raw.dup end @raw = @raw.merge( DEFAULT.merge( @raw ) ) if @raw['value'] && !@raw['value'].empty? @raw['value'] = decode( @raw['value'].to_s ) end parsed_uri = uri_parse( @url ) if !@raw['path'] path = parsed_uri.path path = !path.empty? ? path : '/' @raw['path'] = path end @raw['domain'] ||= parsed_uri.host @raw['max_age'] = @raw['max_age'] if @raw['max_age'] @orig = self.auditable.dup @orig.freeze end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
Class Method Details
.decode(str) ⇒ String
Decodes a String encoded for the Cookie header field.
1023 1024 1025 |
# File 'lib/arachni/element/cookie.rb', line 1023 def self.decode( str ) URI.decode( str.gsub( '+', ' ' ) ) end |
.encode(str) ⇒ String
1004 1005 1006 |
# File 'lib/arachni/element/cookie.rb', line 1004 def self.encode( str ) URI.encode( str, "+;%=\0" ).gsub( ' ', '+' ) end |
.expires_to_time(expires) ⇒ Time
Converts a cookie’s expiration date to a Ruby Time object.
636 637 638 |
# File 'lib/arachni/element/cookie.rb', line 636 def self.expires_to_time( expires ) (expires_to_i = expires.to_i) > 0 ? Time.at( expires_to_i ) : Time.parse( expires ) end |
.from_document(url, document) ⇒ Array<Cookie>
Returns an array of cookies from a document based on Set-Cookie http-equiv meta tags.
852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 |
# File 'lib/arachni/element/cookie.rb', line 852 def self.from_document( url, document ) # optimizations in case there are no cookies in the doc, # avoid parsing unless absolutely necessary! if !document.is_a?( Nokogiri::HTML::Document ) # get get the head in order to check if it has an http-equiv for set-cookie head = document.to_s.match( /<head(.*)<\/head>/imx ) # if it does feed the head to the parser in order to extract the cookies return [] if !head || !head.to_s.downcase.substring?( 'set-cookie' ) document = Nokogiri::HTML( head.to_s ) end Arachni::Utilities.exception_jail { document.search( "//meta[@http-equiv]" ).map do |elem| next if elem['http-equiv'].downcase != 'set-cookie' ( url, elem['content'] ) end.flatten.compact } rescue [] end |
.from_file(url, filepath) ⇒ Array<Cookie>
Returns an array of cookies from an Netscape HTTP cookiejar file.
596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 |
# File 'lib/arachni/element/cookie.rb', line 596 def self.from_file( url, filepath ) File.open( filepath, 'r' ).map do |line| # skip empty lines next if (line = line.strip).empty? || line[0] == '#' c = {} c['domain'], foo, c['path'], c['secure'], c['expires'], c['name'], c['value'] = *line.split( "\t" ) # expiry date is optional so if we don't have one push everything back begin c['expires'] = expires_to_time( c['expires'] ) rescue c['value'] = c['name'].dup c['name'] = c['expires'].dup c['expires'] = nil end c['secure'] = (c['secure'] == 'TRUE') ? true : false new( url, c ) end.flatten.compact end |
.from_headers(url, headers) ⇒ Array<Cookie>
Returns an array of cookies from the Set-Cookie header field.
919 920 921 922 923 924 925 926 927 |
# File 'lib/arachni/element/cookie.rb', line 919 def self.from_headers( url, headers ) set_strings = [] headers.each { |k, v| set_strings = [v].flatten if k.downcase == 'set-cookie' } return set_strings if set_strings.empty? exception_jail { set_strings.map { |c| ( url, c ) }.flatten } rescue [] end |
.from_response(response) ⇒ Array<Cookie>
Returns an array of cookies from an HTTP response.
760 761 762 763 |
# File 'lib/arachni/element/cookie.rb', line 760 def self.from_response( response ) ( from_document( response.effective_url, response.body ) | from_headers( response.effective_url, response.headers_hash ) ) end |
.from_set_cookie(url, str) ⇒ Array<Cookie>
Parses the Set-Cookie header value into cookie elements.
974 975 976 977 978 979 980 981 982 983 984 985 986 987 |
# File 'lib/arachni/element/cookie.rb', line 974 def self.( url, str ) WEBrick::Cookie.( str ).flatten.uniq.map do || = {} .instance_variables.each do |var| [var.to_s.gsub( /@/, '' )] = .instance_variable_get( var ) end ['expires'] = .expires ['name'] = decode( .name ) ['value'] = decode( .value ) new( url.to_s, ) end.flatten.compact end |
.parse_set_cookie(*args) ⇒ Object
988 989 990 |
# File 'lib/arachni/element/cookie.rb', line 988 def self.( *args ) ( *args ) end |
Instance Method Details
#audit(*args) ⇒ Object
Overrides Arachni::Element::Capabilities::Auditable#audit to enforce cookie exclusion settings from Options#exclude_cookies.
91 92 93 94 95 96 97 |
# File 'lib/arachni/element/cookie.rb', line 91 def audit( *args ) if Arachni::Options..include?( name ) auditor.print_info "Skipping audit of '#{name}' cookie." return end super( *args ) end |
#auditable=(inputs) ⇒ Object
Sets auditable inputs as a key=>value pair.
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
# File 'lib/arachni/element/cookie.rb', line 249 def auditable=( inputs ) k = inputs.keys.first.to_s v = inputs.values.first.to_s raw = @raw.dup raw['name'] = k raw['value'] = v @raw = raw.freeze if k.to_s.empty? super( {} ) else super( { k => v } ) end end |
#decode(str) ⇒ Object
1027 1028 1029 |
# File 'lib/arachni/element/cookie.rb', line 1027 def decode( str ) self.class.decode( str ) end |
#dup ⇒ Object
224 225 226 227 228 |
# File 'lib/arachni/element/cookie.rb', line 224 def dup d = super d.action = self.action d end |
#encode(str) ⇒ Object
1008 1009 1010 |
# File 'lib/arachni/element/cookie.rb', line 1008 def encode( str ) self.class.encode( str ) end |
#expired?(time = Time.now) ⇒ Boolean
Indicates whether or not the cookie has expired.
203 204 205 |
# File 'lib/arachni/element/cookie.rb', line 203 def expired?( time = Time.now ) expires_at != nil && time > expires_at end |
#expires_at ⇒ Time, NilClass
Returns expiration Time of the cookie or nil if it doesn’t have one (i.e. is a session cookie).
163 164 165 |
# File 'lib/arachni/element/cookie.rb', line 163 def expires_at expires end |
#http_only? ⇒ Bool
Indicates whether the cookie is safe from modification from client-side code.
127 128 129 |
# File 'lib/arachni/element/cookie.rb', line 127 def http_only? @raw['httponly'] == true end |
#mutations(injection_str, opts = {}) ⇒ Object
Overrides Arachni::Element::Capabilities::Mutable#mutations to handle cookie-specific limitations and the Options#audit_cookies_extensively option.
c = Cookie.( 'http://owner-url.com', 'session=stuffstuffstuff' ).first
402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 |
# File 'lib/arachni/element/cookie.rb', line 402 def mutations( injection_str, opts = {} ) flip = opts.delete( :param_flip ) muts = super( injection_str, opts ) if flip elem = self.dup # when under HPG mode element auditing is strictly regulated # and when we flip params we essentially create a new element # which won't be on the whitelist elem.override_instance_scope elem.altered = 'Parameter flip' elem.auditable = { injection_str => seed } muts << elem end if !orphan? && Arachni::Options. # submit all links and forms of the page along with our cookie mutations muts << muts.map do |m| (auditor.page.links | auditor.page.forms).map do |e| next if e.auditable.empty? c = e.dup c.altered = "mutation for the '#{m.altered}' cookie" c.auditor = auditor c.opts[:cookies] = m.auditable.dup c.auditable = Arachni::Module::KeyFiller.fill( c.auditable.dup ) c end end.flatten.compact muts.flatten! end muts end |
#respond_to?(sym) ⇒ Bool
Used by #method_missing to determine if it should process the call.
464 465 466 |
# File 'lib/arachni/element/cookie.rb', line 464 def respond_to?( sym ) @raw.include?( sym.to_s ) || super( sym ) end |
#secure? ⇒ Bool
Indicates whether the cookie must be only sent over an encrypted channel.
111 112 113 |
# File 'lib/arachni/element/cookie.rb', line 111 def secure? @raw['secure'] == true end |
#session? ⇒ Bool
Indicates whether the cookie is to be discarded at the end of the session.
Doesn’t play a role during the scan but it can provide useful info to modules and such.
147 148 149 |
# File 'lib/arachni/element/cookie.rb', line 147 def session? @raw['expires'].nil? end |
#simple ⇒ Hash
Returns simple representation of the cookie as a hash with the cookie name as key and the cookie value as value.
215 216 217 |
# File 'lib/arachni/element/cookie.rb', line 215 def simple self.auditable.dup end |
#to_s ⇒ String
Returns to be used in a ‘Cookie’ request header. (name=value).
479 480 481 |
# File 'lib/arachni/element/cookie.rb', line 479 def to_s "#{encode( name )}=#{encode( value )}" end |