safe_cookies 0.2.0 → 0.2.1

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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YjY2ZmQ0ZDEzMWVhMDRmNWE0MmM2ODRjYTU5MzEyZmQxN2JkMGQzMg==
4
+ YWE0YmVmNWE0NjE3N2ZiYWUzNDM2ODYwMDFhNGNkYTE1Yzc2ZjllYQ==
5
5
  data.tar.gz: !binary |-
6
- N2E2Yzg5OGQzMzkyYWI3N2E1MWJlZWJmZjI1NGM0ZjY2MjkzNDVkZQ==
6
+ NDliMDkwMDFjOTMxZDVhNmU4NjgyZDgxZTQ1OWQ1N2E4NjFhNmZmYw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MzU1ZTQyYjQzNmNhNzljNzA2Y2U2NWIyMDU5MTkyMTU5MDZjYmQ0ZDY4MjNl
10
- M2MxMWJhYmQwMzJkZDdlYzJlZTkwYWFkNWJkNzE4ZTc5MTUxOWI0YjMwNmVk
11
- NGM0YzUyZWU3MjJjMGZlMzgzYjk2OTg4OWU1MzY5ZGQzYjE0NzE=
9
+ YzYxNGU4MmIyNjg1MDhjNzM0ZjRmNWMxZGYwNmM4MDUxYmMwNDE0ZDRiYmQx
10
+ YmY0NTdiOGUxODQ4NWFiOTUzOTUyMjM0MTU2ZWUyOGQ3OGUxYjZhMDYzZGFk
11
+ ZDc5NTcwYjg2Zjc5MWM0MzgwMGE3YTA2NGMyZmQxYmIyOTg5NGY=
12
12
  data.tar.gz: !binary |-
13
- OTMzYTYzN2JkMzk3OGU5NzE4MzAwMWUxYWVmMmI1ZThmYTExNmQyNzgyYWU4
14
- YjFiYzIyOTg4YTk0Njg3YTk0NzRiMjAyMzc1NmM0OWVhYjRhNWI3NDdlZjZm
15
- NTMxYTkwNmJlYTJlMjBkY2NhMGYzM2MwYzRkYzcwMTViMTlmMzc=
13
+ NWI3YmNhNzE2ODI1YzQ2ZGQ0NTk3NTAxODg5MTFhMWI0MDIxYWJmODNlZTU2
14
+ ZjVjZDRkYjE1YmNlNTU4YTIwYTYxNTMyNDFjMWQ2MGFiOTU3ZGNkNTlmZmZi
15
+ ZTdlOTI1M2ZhNTE1NDQzZTRiNTIzMjc2NTYxYzk3MGQ1Zjk5N2Q=
data/README.md CHANGED
@@ -1,84 +1,79 @@
1
1
  # SafeCookies
2
2
 
3
- This Gem has a middleware that will make all cookies secure. In detail, it will:
3
+ This gem has a middleware that will make all cookies secure. In detail, it will
4
+ to two separate things:
4
5
 
5
- * set all new application cookies 'HttpOnly', unless specified otherwise
6
- * set all new application cookies 'secure', if the request came via HTTPS and not specified otherwise
7
- * rewrite request cookies, setting both flags as above
6
+ 1) set all new application cookies 'HttpOnly', unless specified otherwise;
7
+ set all new application cookies 'secure', if the request came via HTTPS and not specified otherwise
8
+
9
+ 2) rewrite request cookies, setting both flags as above
8
10
 
9
11
  ## Installation
10
12
 
11
13
  ### Step 1
12
- Add this line to your application's Gemfile:
13
-
14
- gem 'safe_cookies'
15
-
16
- Then run `bundle install`.
14
+ Add `gem 'safe_cookies'` to your application's Gemfile, then run `bundle install`.
17
15
 
18
- Though this gem is aimed at Rails applications, you may even use it without
19
- Rails. In that case, install it with `gem install safe_cookies`.
16
+ ### Step 2
17
+ **Rails 3 and 4**: add the following lines to the application block in config/application.rb:
20
18
 
19
+ require 'safe_cookies'
20
+ config.middleware.insert_before ActionDispatch::Cookies, SafeCookies::Middleware
21
21
 
22
- ### Step 2
23
- **Rails 3 and 4**: add the following line in config/application.rb:
22
+ **Rails 2:** add the following lines to the initializer block in config/environment.rb:
24
23
 
25
- class Application < Rails::Application
26
- # ...
27
- config.middleware.insert_before ActionDispatch::Cookies, SafeCookies::Middleware
28
- end
24
+ require 'safe_cookies'
25
+ config.middleware.insert_before ActionController::Session::CookieStore, SafeCookies::Middleware
29
26
 
30
- **Rails 2:** add the following lines in config/environment.rb:
31
27
 
32
- Rails::Initializer.run do |config|
33
- # ...
34
- require 'safe_cookies'
35
- config.middleware.insert_before ActionController::Session::CookieStore, SafeCookies::Middleware
36
- end
28
+ Now all your cookies will be made `secure` and `HttpOnly`. But what if you need
29
+ a cookie to be accessible via HTTP or Javascript?
37
30
 
38
- ### Step 3
39
- Register cookies, either just after the lines you added above or in in an initializer
40
- (e.g. in `config/initializers/safe_cookies.rb`):
31
+ ### Having a cookie non-secure or non-HttpOnly
32
+ Tell the middleware which cookies not to make `secure` or `HttpOnly` by
33
+ registering them. Do it either just after the lines you added above or in an
34
+ initializer (e.g. in `config/initializers/safe_cookies.rb`). The `:expire_after` option is required.
41
35
 
42
36
  SafeCookies.configure do |config|
43
- config.register_cookie :remember_token, :expire_after => 1.year
44
- config.register_cookie :last_action, :expire_after => 30.days
45
37
  config.register_cookie :default_language, :expire_after => 10.years, :secure => false
46
38
  config.register_cookie :javascript_data, :expire_after => 1.day, :http_only => false
47
39
  end
48
40
 
49
- If a request has any of those four cookies, the middleware will set them anew. The `remember_token` and
50
- `last_action` cookies will be made `secure` and `HttpOnly`.
51
- Since we want to access the default language even if the user comes via HTTP, the `default_language`
52
- cookie is not made secure. Analogous, the `javascript_data` cookie will be used by a script and hence is
53
- not made `HttpOnly`.
41
+ ### Employing SafeCookies in apps that are already running in production
42
+ Unfortunately, [the client won't ever tell us](http://tools.ietf.org/html/rfc6265#section-4.2.2)
43
+ if it stores the cookie with flags such as `secure` or which expiry date it
44
+ currently has. Therefore, in order to make the middleware retroactively secure
45
+ cookies owned by the client, you need to register each of those cookies with
46
+ the middleware, specifying their properties.
47
+
48
+ Carefully scan your app for cookies you are using. There's no easy way to find
49
+ out if you missed one (but see below for some help the gem provides).
54
50
 
55
- Available options are: `:expire_after (required), :path, :secure, :http_only`.
51
+ SafeCookies.configure do |config|
52
+ config.register_cookie :remember_token, :expire_after => 1.year
53
+ config.register_cookie :last_action, :expire_after => 30.days, :path => '/commerce'
54
+ end
56
55
 
57
- ### Step 4 (important for Rails 2 only)
58
- Override `SafeCookies::Middleware#handle_unknown_cookies(cookies)` to notify you
59
- e.g. by email (see "Dealing with unregistered cookies" below).
56
+ Available options are: `:expire_after` (required)`, :path, :secure, :http_only`.
60
57
 
61
58
 
62
- ## Dealing with unregistered cookies
59
+ ## Dealing with unknown cookies
63
60
 
64
- The middleware is not able to secure cookies without knowing their attributes
65
- (most importantly: their expiry). Unfortunately, [the client won't ever tell us](http://tools.ietf.org/html/rfc6265#section-4.2.2)
66
- if it stores the cookie with flags such as "secure" or which expiry date it
67
- currently has. Therefore, it is important to register all cookies that may be
68
- sent by the client, specifying their properties. Unregistered cookies cannot be
69
- secured by the middleware.
61
+ There are lots of cookies your application receives that you never did set.
62
+ However, if you want to know about any unknown cookies touching your
63
+ application, SafeCookies offers two ways to achieve this.
70
64
 
71
- Unknown cookies are written to the Rails log. When you start implementing the
72
- middleware, you should closely watch it to find cookies you forgot to register.
73
- You may overwrite `SafeCookies::Middleware#handle_unknown_cookies(cookies)` in
74
- the config initializer for customized behaviour (like, notifying you per email).
65
+ 1) If you set `config.log_unknown_cookies = true` in the configuration, all
66
+ unknown cookies will be written to the Rails log. When you start implementing
67
+ the middleware, closely watch it to find cookies you forgot to register.
75
68
 
76
- You should register any cookie that your application is using.
69
+ 2) You may overwrite `SafeCookies::Middleware#handle_unknown_cookies(cookies)`
70
+ in the config initializer for customized behaviour (like, notifying you per
71
+ email).
77
72
 
78
73
 
79
74
  ## Ignoring cookies
80
75
 
81
- Currently, ignoring cookies only prevents the middleware from writing them to the logs.
76
+ The middleware won't see request cookies that are configured to be ignored. Use this to keep your logs lean, if you are using the `log_unknown_cookies` option.
82
77
 
83
78
  You can tell the middleware to ignore cookies with the `config.ignore_cookie`
84
79
  directive, which takes either a String or a Regex parameter. Be careful when using regular expressions!
@@ -93,7 +88,7 @@ Users would get multiple cookies for that domain, leading to issues like being u
93
88
  The configuration option `config.fix_paths` turns on fixing this error. It requires an option
94
89
  `:for_cookies_secured_before => Time.parse('some minutes after you will have deployed')` which reflects the
95
90
  point of time from which cookies will be secured with the correct path. The middleware will fix the cookie
96
- paths by rewriting all cookies that it has already secured, but only if the were secured before the time
91
+ paths by rewriting all cookies that it has already secured, but only if they were secured before the time
97
92
  you specified.
98
93
 
99
94
 
data/lib/safe_cookies.rb CHANGED
@@ -64,6 +64,9 @@ module SafeCookies
64
64
  unknown_cookie_names = request_cookie_names - known_cookie_names
65
65
 
66
66
  if unknown_cookie_names.any?
67
+ message = "Request for '#{@request.url}' had unknown cookies: #{unknown_cookie_names.join(', ')}"
68
+ log(message) if @config.log_unknown_cookies
69
+
67
70
  handle_unknown_cookies(unknown_cookie_names)
68
71
  end
69
72
  end
@@ -128,11 +131,10 @@ module SafeCookies
128
131
 
129
132
  # API method
130
133
  def handle_unknown_cookies(cookie_names)
131
- log_error("Request for '#{@request.url}' had unknown cookies: #{cookie_names.join(', ')}")
132
134
  end
133
135
 
134
- def log_error(error_message)
135
- message = '** [SafeCookies error] '
136
+ def log(error_message)
137
+ message = '** [SafeCookies] '
136
138
  message << error_message
137
139
 
138
140
  Rails.logger.error(message) if defined?(Rails)
@@ -13,7 +13,9 @@ module SafeCookies
13
13
  end
14
14
 
15
15
  class Configuration
16
- attr_reader :registered_cookies, :fix_cookie_paths, :correct_cookie_paths_timestamp, :ignored_cookies
16
+ attr_accessor :log_unknown_cookies
17
+ attr_reader :registered_cookies, :fix_cookie_paths, :correct_cookie_paths_timestamp,
18
+ :ignored_cookies
17
19
 
18
20
  def initialize
19
21
  self.registered_cookies = {}
@@ -72,7 +74,8 @@ module SafeCookies
72
74
  private
73
75
 
74
76
  attr_accessor :insecure_cookies, :scriptable_cookies
75
- attr_writer :registered_cookies, :fix_cookie_paths, :correct_cookie_paths_timestamp, :ignored_cookies
77
+ attr_writer :registered_cookies, :fix_cookie_paths, :correct_cookie_paths_timestamp,
78
+ :ignored_cookies
76
79
 
77
80
  end
78
81
 
@@ -1,3 +1,3 @@
1
1
  module SafeCookies
2
- VERSION = '0.2.0'
2
+ VERSION = '0.2.1'
3
3
  end
@@ -214,69 +214,79 @@ describe SafeCookies::Middleware do
214
214
  # importance in the future.
215
215
  context 'when a request has unknown cookies,' do
216
216
 
217
- it 'logs an error message' do
217
+ it 'allows overwriting the handling mechanism' do
218
218
  stub_app_call(app)
219
219
  set_request_cookies(env, 'foo=bar')
220
220
 
221
- subject.should_receive(:log_error).with(/unknown cookies: foo/)
221
+ def subject.handle_unknown_cookies(*args)
222
+ @custom_method_called = true
223
+ end
224
+
222
225
  subject.call(env)
226
+ subject.instance_variable_get('@custom_method_called').should == true
223
227
  end
224
228
 
225
- it 'does not log an error if the (unregistered) cookie was initially set by the application' do
226
- # application sets cookie
227
- stub_app_call(app, :application_cookies => 'foo=bar; path=/some/path; secure')
229
+ context 'and it is configured to log unknown cookies' do
230
+
231
+ before do
232
+ SafeCookies.configure do |config|
233
+ config.log_unknown_cookies = true
234
+ end
235
+ end
236
+
237
+ it 'logs an error message' do
238
+ stub_app_call(app)
239
+ set_request_cookies(env, 'foo=bar')
228
240
 
229
- code, headers, response = subject.call(env)
241
+ subject.should_receive(:log).with(/unknown cookies: foo/)
242
+ subject.call(env)
243
+ end
244
+
245
+ it 'does not log an error if the (unregistered) cookie was initially set by the application' do
246
+ # application sets cookie
247
+ stub_app_call(app, :application_cookies => 'foo=bar; path=/some/path; secure')
248
+
249
+ code, headers, response = subject.call(env)
230
250
 
231
- received_cookies = extract_cookies(headers['Set-Cookie'])
232
- received_cookies.should include('foo=bar') # sanity check
251
+ received_cookies = extract_cookies(headers['Set-Cookie'])
252
+ received_cookies.should include('foo=bar') # sanity check
233
253
 
234
- # client returns with the cookie, `app` and `subject` are different
235
- # objects than in the previous request
236
- other_app = stub('application')
237
- other_subject = described_class.new(other_app)
254
+ # client returns with the cookie, `app` and `subject` are different
255
+ # objects than in the previous request
256
+ other_app = stub('application')
257
+ other_subject = described_class.new(other_app)
238
258
 
239
- stub_app_call(other_app)
240
- set_request_cookies(env, *received_cookies)
259
+ stub_app_call(other_app)
260
+ set_request_cookies(env, *received_cookies)
241
261
 
242
- other_subject.should_not_receive(:log_error)
243
- other_subject.call(env)
244
- end
245
-
246
- it 'does not log an error if the cookie is listed in the cookie configuration' do
247
- SafeCookies.configure do |config|
248
- config.register_cookie('foo', :expire_after => 3600)
262
+ other_subject.should_not_receive(:log)
263
+ other_subject.call(env)
249
264
  end
250
265
 
251
- stub_app_call(app)
252
- set_request_cookies(env, 'foo=bar')
253
-
254
- subject.should_not_receive(:log_error)
255
- subject.call(env)
256
- end
266
+ it 'does not log an error if the cookie is listed in the cookie configuration' do
267
+ SafeCookies.configure do |config|
268
+ config.register_cookie('foo', :expire_after => 3600)
269
+ end
257
270
 
258
- it 'does not log an error if the cookie is ignored' do
259
- SafeCookies.configure do |config|
260
- config.ignore_cookie '__utma'
261
- end
262
-
263
- stub_app_call(app)
264
- set_request_cookies(env, '__utma=tracking')
271
+ stub_app_call(app)
272
+ set_request_cookies(env, 'foo=bar')
265
273
 
266
- subject.should_not_receive(:log_error)
267
- subject.call(env)
268
- end
274
+ subject.should_not_receive(:log)
275
+ subject.call(env)
276
+ end
269
277
 
270
- it 'allows overwriting the handling mechanism' do
271
- stub_app_call(app)
272
- set_request_cookies(env, 'foo=bar')
278
+ it 'does not log an error if the cookie is ignored' do
279
+ SafeCookies.configure do |config|
280
+ config.ignore_cookie '__utma'
281
+ end
282
+
283
+ stub_app_call(app)
284
+ set_request_cookies(env, '__utma=tracking')
273
285
 
274
- def subject.handle_unknown_cookies(*args)
275
- @custom_method_called = true
286
+ subject.should_not_receive(:log)
287
+ subject.call(env)
276
288
  end
277
-
278
- subject.call(env)
279
- subject.instance_variable_get('@custom_method_called').should == true
289
+
280
290
  end
281
291
 
282
292
  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.2.0
4
+ version: 0.2.1
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-11 00:00:00.000000000 Z
11
+ date: 2013-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -109,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
109
  version: '0'
110
110
  requirements: []
111
111
  rubyforge_project:
112
- rubygems_version: 2.1.3
112
+ rubygems_version: 2.1.2
113
113
  signing_key:
114
114
  specification_version: 4
115
115
  summary: Make all cookies `secure` and `HttpOnly`.