safe_cookies 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/lib/safe_cookies/configuration.rb +2 -1
- data/lib/safe_cookies/cookie_path_fix.rb +17 -14
- data/lib/safe_cookies/helpers.rb +96 -0
- data/lib/safe_cookies/version.rb +1 -1
- data/lib/safe_cookies.rb +55 -110
- data/safe_cookies.gemspec +1 -0
- data/spec/configuration_spec.rb +8 -31
- data/spec/safe_cookies_spec.rb +7 -4
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MjI5NWM4ZWE1M2UzNWFjNjFkNzc2M2EzN2U4NzJhZTgzNjQ0NmQ1NQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
OGNlMjkzMmI2MTFhZTFlNzA3MDZmMmYxOWQ3YmQ1ZGE4Njg0OWZlOA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MjU5MGUyMzQyNTI2MzE5OTkzYjBkOTI4NjQ1ZjQxOTk4NGQzOTkxMDEyNDk3
|
10
|
+
YmQ3YjJjZDBhYTU3ZjBhNzgzMGYwNzdmNzcyZTFmYWY1NzQ0N2RhZDUyYzA1
|
11
|
+
NjJlZDc4NjdiMWU2M2NhOWY5YzBmNWFkNWNmY2Y1OTgxNjI1YjQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
Yjg4YTA3OGYyY2RhYmJkZTAyYmNiNjE2ZGRjNTc4MTA0NDJjMTc1ZjA3Mjcy
|
14
|
+
MjFhYjlhOGY1ZjQyYTE3OTEzODE3ZmU3YmE5YzIxOTNhOWE4NTg5M2M3ZTk4
|
15
|
+
ZWMzMzVmODk4MWE3MDdjN2RkZjI1N2UwN2EyOTVlNmM0MmMwMjk=
|
@@ -36,10 +36,11 @@ module SafeCookies
|
|
36
36
|
# :path => '/foo/path'
|
37
37
|
#
|
38
38
|
def register_cookie(name, options)
|
39
|
+
name.is_a?(String) or raise "Cookie name must be a String"
|
39
40
|
options.has_key?(:expire_after) or raise MissingOptionError.new("Cookie #{name.inspect} was registered without an expiry")
|
40
41
|
raise NotImplementedError if options.has_key?(:domain)
|
41
42
|
|
42
|
-
registered_cookies[name
|
43
|
+
registered_cookies[name] = (options || {}).freeze
|
43
44
|
insecure_cookies << name if options[:secure] == false
|
44
45
|
scriptable_cookies << name if options[:http_only] == false
|
45
46
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module SafeCookies
|
2
2
|
module CookiePathFix
|
3
|
-
|
3
|
+
|
4
4
|
# Previously, the SafeCookies gem would not set a path when rewriting
|
5
5
|
# cookies. Browsers then would assume and store the current "directory",
|
6
6
|
# leading to multiple cookies per domain.
|
@@ -10,25 +10,25 @@ module SafeCookies
|
|
10
10
|
# SECURED_COOKIE_NAME helper cookie.
|
11
11
|
# The middleware still sees the request cookies and will rewrite them as
|
12
12
|
# if it hadn't seen them before.
|
13
|
-
|
13
|
+
|
14
14
|
def fix_cookie_paths
|
15
15
|
registered_cookies_in_request.keys.each do |registered_cookie|
|
16
16
|
delete_cookie_for_current_directory(registered_cookie)
|
17
17
|
end
|
18
18
|
delete_cookie_for_current_directory(SafeCookies::SECURED_COOKIE_NAME)
|
19
|
-
|
19
|
+
|
20
20
|
# Delete this cookie here, so the middleware will secure all cookies anew.
|
21
|
-
|
21
|
+
request_cookies.delete(SafeCookies::SECURED_COOKIE_NAME)
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
private
|
25
|
-
|
25
|
+
|
26
26
|
def fix_cookie_paths?
|
27
27
|
@configuration.fix_cookie_paths or return false
|
28
|
-
|
28
|
+
|
29
29
|
cookies_need_path_fix = (secured_old_cookies_timestamp < @configuration.correct_cookie_paths_timestamp)
|
30
30
|
|
31
|
-
cookies_have_been_rewritten_before and cookies_need_path_fix
|
31
|
+
cookies_have_been_rewritten_before? and cookies_need_path_fix
|
32
32
|
end
|
33
33
|
|
34
34
|
# Delete cookies by giving them an expiry in the past,
|
@@ -44,21 +44,24 @@ module SafeCookies
|
|
44
44
|
# However, Firefox includes the right-most slash when guessing the cookie path,
|
45
45
|
# so we must resort to letting browsers estimate the deletion cookie path again.
|
46
46
|
def delete_cookie_for_current_directory(cookie_name)
|
47
|
-
|
48
|
-
|
49
|
-
if current_directory_is_not_root
|
47
|
+
unless current_directory_is_root?
|
50
48
|
one_week = (7 * 24 * 60 * 60)
|
51
49
|
set_cookie!(cookie_name, "", :path => nil, :expire_after => -one_week)
|
52
50
|
end
|
53
51
|
end
|
54
|
-
|
52
|
+
|
53
|
+
def current_directory_is_root?
|
54
|
+
!@request.path[%r(^/[^/]+/[^\?]+), 0] # roughly: "there are not three slashes"
|
55
|
+
end
|
56
|
+
|
55
57
|
def secured_old_cookies_timestamp
|
56
|
-
Time.rfc2822(
|
58
|
+
Time.rfc2822(request_cookies[SafeCookies::SECURED_COOKIE_NAME])
|
57
59
|
rescue ArgumentError
|
58
60
|
# If we cannot parse the secured_old_cookies time,
|
59
61
|
# assume it was before we noticed the bug to ensure
|
60
62
|
# broken cookie paths will be fixed.
|
61
63
|
Time.parse "2013-08-25 0:00"
|
62
64
|
end
|
65
|
+
|
63
66
|
end
|
64
|
-
end
|
67
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module SafeCookies
|
2
|
+
module Helpers
|
3
|
+
|
4
|
+
KNOWN_COOKIES_DIVIDER = '|'
|
5
|
+
|
6
|
+
def cache_application_cookies_string
|
7
|
+
cookies = @headers['Set-Cookie']
|
8
|
+
# Rack 1.1 returns an Array
|
9
|
+
cookies = cookies.join("\n") if cookies.is_a?(Array)
|
10
|
+
|
11
|
+
if cookies and cookies.length > 0
|
12
|
+
@application_cookies = cookies
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def secure(cookie)
|
17
|
+
# Regexp from https://github.com/tobmatth/rack-ssl-enforcer/
|
18
|
+
if should_be_secure?(cookie) and cookie !~ /(^|;\s)secure($|;)/
|
19
|
+
"#{cookie}; secure"
|
20
|
+
else
|
21
|
+
cookie
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def http_only(cookie)
|
26
|
+
if should_be_http_only?(cookie) and cookie !~ /(^|;\s)HttpOnly($|;)/
|
27
|
+
"#{cookie}; HttpOnly"
|
28
|
+
else
|
29
|
+
cookie
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def set_cookie!(name, value, options)
|
34
|
+
options = options.dup
|
35
|
+
expire_after = options.delete(:expire_after)
|
36
|
+
|
37
|
+
options[:expires] = Time.now + expire_after if expire_after
|
38
|
+
options[:path] = '/' unless options.has_key?(:path) # allow setting path = nil
|
39
|
+
options[:value] = value
|
40
|
+
options[:secure] = should_be_secure?(name)
|
41
|
+
options[:httponly] = should_be_http_only?(name)
|
42
|
+
|
43
|
+
Rack::Utils.set_cookie_header!(@headers, name, options)
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
# getters
|
48
|
+
|
49
|
+
def stored_application_cookie_names
|
50
|
+
store_cookie = request_cookies[STORE_COOKIE_NAME] || ""
|
51
|
+
store_cookie.split(KNOWN_COOKIES_DIVIDER)
|
52
|
+
end
|
53
|
+
|
54
|
+
# returns those of the registered cookies that appear in the request
|
55
|
+
def registered_cookies_in_request
|
56
|
+
Util.slice(@configuration.registered_cookies, *request_cookies.keys)
|
57
|
+
end
|
58
|
+
|
59
|
+
def known_cookie_names
|
60
|
+
known = [STORE_COOKIE_NAME, SECURED_COOKIE_NAME]
|
61
|
+
known += stored_application_cookie_names
|
62
|
+
known += @configuration.registered_cookies.keys
|
63
|
+
end
|
64
|
+
|
65
|
+
def request_cookies
|
66
|
+
@request.cookies
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
# boolean
|
71
|
+
|
72
|
+
def cookies_have_been_rewritten_before?
|
73
|
+
request_cookies.has_key? SECURED_COOKIE_NAME
|
74
|
+
end
|
75
|
+
|
76
|
+
def should_be_secure?(cookie)
|
77
|
+
cookie_name = cookie.split('=').first.strip
|
78
|
+
ssl? and not @configuration.insecure_cookie?(cookie_name)
|
79
|
+
end
|
80
|
+
|
81
|
+
def ssl?
|
82
|
+
if @request.respond_to?(:ssl?)
|
83
|
+
@request.ssl?
|
84
|
+
else
|
85
|
+
# older Rack versions
|
86
|
+
@request.scheme == 'https'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def should_be_http_only?(cookie)
|
91
|
+
cookie_name = cookie.split('=').first.strip
|
92
|
+
not @configuration.scriptable_cookie?(cookie_name)
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
data/lib/safe_cookies/version.rb
CHANGED
data/lib/safe_cookies.rb
CHANGED
@@ -1,23 +1,31 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
require "safe_cookies/configuration"
|
3
3
|
require "safe_cookies/cookie_path_fix"
|
4
|
+
require "safe_cookies/helpers"
|
4
5
|
require "safe_cookies/util"
|
5
6
|
require "safe_cookies/version"
|
6
7
|
require "rack"
|
7
8
|
|
9
|
+
# Naming:
|
10
|
+
# - application_cookies: cookies received from the application. The 'Set-Cookie' header is a string
|
11
|
+
# - request_cookies: cookies received from the client. Rack::Request#cookies returns a Hash of { 'name' => 'value' }
|
12
|
+
# - response_cookies: cookies to be sent to the client
|
13
|
+
# (= application_cookies + any cookies set in the middleware)
|
14
|
+
|
8
15
|
module SafeCookies
|
9
16
|
|
10
17
|
UnknownCookieError = Class.new(StandardError)
|
11
18
|
|
12
|
-
|
19
|
+
STORE_COOKIE_NAME = '_safe_cookies__known_cookies'
|
13
20
|
SECURED_COOKIE_NAME = 'secured_old_cookies'
|
14
21
|
HELPER_COOKIES_LIFETIME = 10 * 365 * 24 * 60 * 60 # 10 years
|
15
22
|
|
16
23
|
class Middleware
|
17
24
|
|
18
25
|
include CookiePathFix
|
26
|
+
include Helpers
|
19
27
|
|
20
|
-
|
28
|
+
COOKIE_NAME_REGEX = /(?=^|\n)[^\n;,=]+/i
|
21
29
|
|
22
30
|
|
23
31
|
def initialize(app)
|
@@ -29,14 +37,16 @@ module SafeCookies
|
|
29
37
|
reset_instance_variables
|
30
38
|
|
31
39
|
@request = Rack::Request.new(env)
|
32
|
-
|
40
|
+
ensure_no_unknown_cookies_in_request!
|
33
41
|
|
34
42
|
status, @headers, body = @app.call(env)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
cache_application_cookies
|
43
|
+
cache_application_cookies_string
|
44
|
+
|
45
|
+
remove_application_cookies_from_request_cookies
|
39
46
|
rewrite_application_cookies
|
47
|
+
store_application_cookie_names
|
48
|
+
fix_cookie_paths if fix_cookie_paths?
|
49
|
+
rewrite_request_cookies unless cookies_have_been_rewritten_before?
|
40
50
|
|
41
51
|
[ status, @headers, body ]
|
42
52
|
end
|
@@ -44,63 +54,31 @@ module SafeCookies
|
|
44
54
|
private
|
45
55
|
|
46
56
|
def reset_instance_variables
|
47
|
-
@request, @headers = nil
|
57
|
+
@request, @headers, @application_cookies = nil
|
48
58
|
end
|
49
59
|
|
50
|
-
def
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
60
|
+
def ensure_no_unknown_cookies_in_request!
|
61
|
+
request_cookie_names = request_cookies.keys.map(&:to_s)
|
62
|
+
unknown_cookie_names = request_cookie_names - known_cookie_names
|
63
|
+
|
64
|
+
if unknown_cookie_names.any?
|
65
|
+
handle_unknown_cookies(unknown_cookie_names)
|
56
66
|
end
|
57
67
|
end
|
58
68
|
|
59
|
-
def
|
60
|
-
if
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# This method takes all cookies sent with the request and rewrites them,
|
68
|
-
# making them both secure and http-only (unless specified otherwise in
|
69
|
-
# the configuration).
|
70
|
-
# With the SECURED_COOKIE_NAME cookie we remember the exact time that we
|
71
|
-
# rewrote the cookies.
|
72
|
-
def rewrite_request_cookies
|
73
|
-
if @request.cookies.any?
|
74
|
-
registered_cookies_in_request.each do |registered_cookie, options|
|
75
|
-
value = @request.cookies[registered_cookie]
|
76
|
-
|
77
|
-
set_cookie!(registered_cookie, value, options)
|
69
|
+
def remove_application_cookies_from_request_cookies
|
70
|
+
if @application_cookies
|
71
|
+
application_cookie_names = @application_cookies.scan(COOKIE_NAME_REGEX)
|
72
|
+
application_cookie_names.each do |cookie|
|
73
|
+
request_cookies.delete(cookie)
|
78
74
|
end
|
79
|
-
|
80
|
-
formatted_now = Rack::Utils.rfc2822(Time.now.gmtime)
|
81
|
-
set_cookie!(SECURED_COOKIE_NAME, formatted_now, :expire_after => HELPER_COOKIES_LIFETIME)
|
82
75
|
end
|
83
76
|
end
|
84
77
|
|
85
|
-
def set_cookie!(name, value, options)
|
86
|
-
options = options.dup
|
87
|
-
expire_after = options.delete(:expire_after)
|
88
|
-
|
89
|
-
options[:expires] = Time.now + expire_after if expire_after
|
90
|
-
options[:path] = '/' unless options.has_key?(:path) # allow setting path = nil
|
91
|
-
options[:value] = value
|
92
|
-
options[:secure] = should_be_secure?(name)
|
93
|
-
options[:httponly] = should_be_http_only?(name)
|
94
|
-
|
95
|
-
Rack::Utils.set_cookie_header!(@headers, name, options)
|
96
|
-
end
|
97
|
-
|
98
78
|
def rewrite_application_cookies
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
cookies = cookies.split("\n") unless cookies.is_a?(Array)
|
103
|
-
|
79
|
+
if @application_cookies
|
80
|
+
cookies = @application_cookies.split("\n")
|
81
|
+
|
104
82
|
# On Rack 1.1, cookie values sometimes contain trailing newlines.
|
105
83
|
# Example => ["foo=1; path=/\n", "bar=2; path=/"]
|
106
84
|
# Note that they also mess up browsers, when this array is merged
|
@@ -118,69 +96,36 @@ module SafeCookies
|
|
118
96
|
@headers['Set-Cookie'] = cookies.join("\n")
|
119
97
|
end
|
120
98
|
end
|
121
|
-
|
122
|
-
def
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
if @request.respond_to?(:ssl?)
|
129
|
-
@request.ssl?
|
130
|
-
else
|
131
|
-
# older Rack versions
|
132
|
-
@request.scheme == 'https'
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
def should_be_http_only?(cookie)
|
137
|
-
cookie_name = cookie.split('=').first.strip
|
138
|
-
not @configuration.scriptable_cookie?(cookie_name)
|
139
|
-
end
|
140
|
-
|
141
|
-
def ensure_no_unknown_cookies!
|
142
|
-
request_cookies = @request.cookies.keys.map(&:to_s)
|
143
|
-
unknown_cookies = request_cookies - known_cookies
|
144
|
-
|
145
|
-
if unknown_cookies.any?
|
146
|
-
handle_unknown_cookies(unknown_cookies)
|
99
|
+
|
100
|
+
def store_application_cookie_names
|
101
|
+
if @application_cookies
|
102
|
+
application_cookie_names = stored_application_cookie_names + @application_cookies.scan(COOKIE_NAME_REGEX)
|
103
|
+
application_cookies_string = application_cookie_names.uniq.join(KNOWN_COOKIES_DIVIDER)
|
104
|
+
|
105
|
+
set_cookie!(STORE_COOKIE_NAME, application_cookies_string, :expire_after => HELPER_COOKIES_LIFETIME)
|
147
106
|
end
|
148
107
|
end
|
149
108
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
109
|
+
# This method takes all cookies sent with the request and rewrites them,
|
110
|
+
# making them both secure and http-only (unless specified otherwise in
|
111
|
+
# the configuration).
|
112
|
+
# With the SECURED_COOKIE_NAME cookie we remember the exact time that we
|
113
|
+
# rewrote the cookies.
|
114
|
+
def rewrite_request_cookies
|
115
|
+
if request_cookies.any?
|
116
|
+
registered_cookies_in_request.each do |cookie_name, options|
|
117
|
+
value = request_cookies[cookie_name]
|
118
|
+
|
119
|
+
set_cookie!(cookie_name, value, options)
|
120
|
+
end
|
156
121
|
|
157
|
-
|
158
|
-
|
159
|
-
application_cookies = cached_application_cookies + new_application_cookies.scan(/(?=^|\n)[^\n;,=]+/i)
|
160
|
-
application_cookies_string = application_cookies.uniq.join(KNOWN_COOKIES_DIVIDER)
|
161
|
-
|
162
|
-
set_cookie!(CACHE_COOKIE_NAME, application_cookies_string, :expire_after => HELPER_COOKIES_LIFETIME)
|
122
|
+
formatted_now = Rack::Utils.rfc2822(Time.now.gmtime)
|
123
|
+
set_cookie!(SECURED_COOKIE_NAME, formatted_now, :expire_after => HELPER_COOKIES_LIFETIME)
|
163
124
|
end
|
164
125
|
end
|
165
126
|
|
166
|
-
def
|
167
|
-
|
168
|
-
cache_cookie.split(KNOWN_COOKIES_DIVIDER)
|
169
|
-
end
|
170
|
-
|
171
|
-
def known_cookies
|
172
|
-
known = [CACHE_COOKIE_NAME, SECURED_COOKIE_NAME]
|
173
|
-
known += cached_application_cookies
|
174
|
-
known += @configuration.registered_cookies.keys
|
175
|
-
end
|
176
|
-
|
177
|
-
def cookies_have_been_rewritten_before
|
178
|
-
@request.cookies.has_key? SECURED_COOKIE_NAME
|
179
|
-
end
|
180
|
-
|
181
|
-
# returns those of the registered cookies that appear in the request
|
182
|
-
def registered_cookies_in_request
|
183
|
-
Util.slice(@configuration.registered_cookies, *@request.cookies.keys)
|
127
|
+
def handle_unknown_cookies(cookie_names)
|
128
|
+
raise SafeCookies::UnknownCookieError.new("Request for '#{@request.url}' had unknown cookies: #{cookie_names.join(', ')}")
|
184
129
|
end
|
185
130
|
|
186
131
|
end
|
data/safe_cookies.gemspec
CHANGED
data/spec/configuration_spec.rb
CHANGED
@@ -26,53 +26,30 @@ describe SafeCookies::Middleware do
|
|
26
26
|
|
27
27
|
describe 'register_cookie' do
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
let(:set_cookie) do
|
32
|
-
# These tests for the Configuration module require an integration with
|
33
|
-
# the middleware itself. Therefore, we need to actually use it.
|
34
|
-
|
35
|
-
app = stub('app')
|
36
|
-
env = { 'HTTPS' => 'on' }
|
37
|
-
stub_app_call(app, :application_cookies => 'cookie_name=value')
|
38
|
-
|
39
|
-
middleware = described_class.new(app)
|
40
|
-
code, headers, response = middleware.call(env)
|
41
|
-
headers['Set-Cookie']
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'understands cookies registered as symbol' do
|
45
|
-
SafeCookies.configure do |config|
|
46
|
-
config.register_cookie(:cookie_name, :expire_after => nil)
|
47
|
-
end
|
48
|
-
|
49
|
-
set_cookie.should =~ /cookie_name=value;.* secure; HttpOnly/
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'understands cookies registered as string' do
|
29
|
+
it 'raises an error if a cookie is registered without passing its expiry' do
|
30
|
+
registration_without_expiry = lambda do
|
53
31
|
SafeCookies.configure do |config|
|
54
|
-
config.register_cookie('
|
32
|
+
config.register_cookie('filter', :some => :option)
|
55
33
|
end
|
56
|
-
|
57
|
-
set_cookie.should =~ /cookie_name=value;.* secure; HttpOnly/
|
58
34
|
end
|
59
35
|
|
36
|
+
expect(®istration_without_expiry).to raise_error(SafeCookies::MissingOptionError)
|
60
37
|
end
|
61
38
|
|
62
|
-
it 'raises an error if
|
63
|
-
|
39
|
+
it 'raises an error if the cookie name is not a String, because the middleware’s logic depends on strings' do
|
40
|
+
registration_as_symbol = lambda do
|
64
41
|
SafeCookies.configure do |config|
|
65
42
|
config.register_cookie(:filter, :some => :option)
|
66
43
|
end
|
67
44
|
end
|
68
45
|
|
69
|
-
expect(&
|
46
|
+
expect(®istration_as_symbol).to raise_error(RuntimeError, /must be a string/i)
|
70
47
|
end
|
71
48
|
|
72
49
|
it 'allows nil as expiry (means session cookie)' do
|
73
50
|
registration_with_nil_expiry = lambda do
|
74
51
|
SafeCookies.configure do |config|
|
75
|
-
config.register_cookie(
|
52
|
+
config.register_cookie('filter', :expire_after => nil)
|
76
53
|
end
|
77
54
|
end
|
78
55
|
|
data/spec/safe_cookies_spec.rb
CHANGED
@@ -70,7 +70,6 @@ describe SafeCookies::Middleware do
|
|
70
70
|
code, headers, response = subject.call(env)
|
71
71
|
|
72
72
|
cookies = headers['Set-Cookie'].split("\n")
|
73
|
-
cookies.size.should == 3 # my_old_cookie and secured_old_cookies and _known_cookies
|
74
73
|
cookies.each do |cookie|
|
75
74
|
cookie.should include('; path=/;')
|
76
75
|
end
|
@@ -124,7 +123,6 @@ describe SafeCookies::Middleware do
|
|
124
123
|
SafeCookies.configure do |config|
|
125
124
|
config.register_cookie('javascript-cookie', :expire_after => 3600, :http_only => false)
|
126
125
|
end
|
127
|
-
|
128
126
|
stub_app_call(app, :application_cookies => 'javascript-cookie=xss')
|
129
127
|
|
130
128
|
code, headers, response = subject.call(env)
|
@@ -132,11 +130,16 @@ describe SafeCookies::Middleware do
|
|
132
130
|
headers['Set-Cookie'].should_not =~ /javascript-cookie=.*HttpOnly/i
|
133
131
|
end
|
134
132
|
|
135
|
-
it '
|
133
|
+
it 'does not rewrite a client cookie when the application is setting a cookie with the same name' do
|
134
|
+
SafeCookies.configure do |config|
|
135
|
+
config.register_cookie('cookie', :expire_after => 3600)
|
136
|
+
end
|
137
|
+
|
136
138
|
stub_app_call(app, :application_cookies => 'cookie=from_application')
|
137
|
-
set_request_cookies(env, 'cookie=from_client
|
139
|
+
set_request_cookies(env, 'cookie=from_client')
|
138
140
|
|
139
141
|
code, headers, response = subject.call(env)
|
142
|
+
|
140
143
|
headers['Set-Cookie'].should include("cookie=from_application")
|
141
144
|
headers['Set-Cookie'].should_not include("cookie=from_client")
|
142
145
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: safe_cookies
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dominik Schöler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-10-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ! '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: debugger
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
description: Make all cookies `secure` and `HttpOnly`.
|
56
70
|
email:
|
57
71
|
- dominik.schoeler@makandra.de
|
@@ -67,6 +81,7 @@ files:
|
|
67
81
|
- lib/safe_cookies.rb
|
68
82
|
- lib/safe_cookies/configuration.rb
|
69
83
|
- lib/safe_cookies/cookie_path_fix.rb
|
84
|
+
- lib/safe_cookies/helpers.rb
|
70
85
|
- lib/safe_cookies/util.rb
|
71
86
|
- lib/safe_cookies/version.rb
|
72
87
|
- safe_cookies.gemspec
|