123456789_123456789_123456789_123456789_123456789_

Class: Rack::Protection::CookieTossing

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, Base
Instance Chain:
self, Base
Inherits: Rack::Protection::Base
Defined in: rack-protection/lib/rack/protection/cookie_tossing.rb

Overview

Prevented attack

Cookie Tossing

Supported browsers

all

More infos

https://github.com/blog/1466-yummy-cookies-across-domains

Does not accept HTTP requests if the Cookie header contains more than one session cookie. This does not protect against a cookie overflow attack.

Options

[:session_key] The name of the session cookie (default: 'rack.session')

[Rack::Protection::Base options] any option supported by Rack::Protection::Base.

Example: Default session key

use Rack::Protection::CookieTossing

Example: Custom session key

use Rack::Session::Cookie, key: "custom.session"
use Rack::Protection::CookieTossing, session_key: "custom.session"

Constant Summary

Base - Inherited

DEFAULT_OPTIONS

Class Method Summary

Base - Inherited

.default_options

Used by subclasses to declare default values for options they require.

.default_reaction

Used by subclasses to declare default reaction when a request is rejected.

.new

Instance Attribute Summary

Base - Inherited

Instance Method Summary

Base - Inherited

#accepts?, #call, #debug, #default_options,
#default_reaction

Alias for Base#deny.

#deny

Deny the request.

#drop_session, #encrypt, #html?, #instrument, #origin, #random_string, #react, #referrer,
#report

When used as a reaction (with option reaction: :report), any rejected request will be allowed through, and a warning is omitted (note that warnings will not be shown if the :logging option has been set to false).

#safe?, #secure_compare, #session, #session?, #warn

Constructor Details

This class inherits a constructor from Rack::Protection::Base

Instance Method Details

#accepts?(env) ⇒ Boolean

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/cookie_tossing.rb', line 42

def accepts?(env)
  cookie_header = env['HTTP_COOKIE']
  cookies = Rack::Utils.parse_query(cookie_header, ';,') { |s| s }
  cookies.each do |k, v|
    if (k == session_key && Array(v).size > 1) ||
       (k != session_key && Rack::Utils.unescape(k) == session_key)
      bad_cookies << k
    end
  end
  bad_cookies.empty?
end

#bad_cookies

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/cookie_tossing.rb', line 69

def bad_cookies
  @bad_cookies ||= []
end

#call(env)

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/cookie_tossing.rb', line 34

def call(env)
  status, headers, body = super
  response = Rack::Response.new(body, status, headers)
  request = Rack::Request.new(env)
  remove_bad_cookies(request, response)
  response.finish
end

#redirect(env)

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/cookie_tossing.rb', line 63

def redirect(env)
  request = Request.new(env)
  warn env, "attack prevented by #{self.class}"
  [302, { 'content-type' => 'text/html', 'location' => request.path }, []]
end

#remove_bad_cookies(request, response)

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/cookie_tossing.rb', line 54

def remove_bad_cookies(request, response)
  return if bad_cookies.empty?

  paths = cookie_paths(request.path)
  bad_cookies.each do |name|
    paths.each { |path| response.set_cookie name, empty_cookie(request.host, path) }
  end
end

#session_key

[ GitHub ]

  
# File 'rack-protection/lib/rack/protection/cookie_tossing.rb', line 84

def session_key
  @session_key ||= options[:session_key]
end