safe_cookies 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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`.