clearance 1.15.1 → 1.16.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of clearance might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ed1114d2ef322be26b340c854c009cf3a43d11a6
4
- data.tar.gz: 06e17413cf20d6969c32ba696de6a8aa7dfb6162
3
+ metadata.gz: 4600924513a7c46fd73ebf5028b704bbff640f50
4
+ data.tar.gz: cb14d831486ab789f5a05e57787b3bcf7bd86be3
5
5
  SHA512:
6
- metadata.gz: 049710acdb4130cb12100d922f9c4191aadb3b43e13bec6b46edcf328a04622a458d771656d5cabb429dbc836812f9361ff7493c3f743f1925aff3e4d558d99b
7
- data.tar.gz: 73ecf1acaf7c2c5b365f9e43ab0c530b8bc3366b21c578ba08b071146224cf08960f161237dd030b79b9e50fe3d627934969f5082193ca91c4220cc72a475af1
6
+ metadata.gz: a3badd570870c53b355ea9bbd915bfc283064fdbd06cc97947bd6b01bf514b2f8fa4395545d4b9487fb8c0cb3eaf0f5e86487abb227cdf36d09ef57d1d104dfa
7
+ data.tar.gz: 61d3af42b4d82470966ad8b0f805ec656e6afb98f4c1ad5c0db5398f7b85e71a8c2f5bbb49cf838aff67e43255223791e9e86bc6741865e0b572bb5f0937899b
data/Gemfile CHANGED
@@ -2,12 +2,14 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
+ gem 'addressable', '~> 2.4.0'
5
6
  gem 'appraisal'
6
7
  gem 'ammeter'
7
8
  gem 'bundler', '~> 1.3'
8
9
  gem 'capybara', '>= 2.6.2'
9
10
  gem 'database_cleaner', '~> 1.0'
10
11
  gem 'factory_girl_rails', '~> 4.2'
12
+ gem 'nokogiri', '~> 1.6.8'
11
13
  gem 'rspec-rails', '~> 3.1'
12
14
  gem 'shoulda-matchers', '~> 2.8'
13
15
  gem 'sqlite3', '~> 1.3'
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- clearance (1.15.1)
4
+ clearance (1.16.0)
5
5
  bcrypt
6
6
  email_validator (~> 1.4)
7
7
  rails (>= 3.1)
@@ -53,9 +53,9 @@ GEM
53
53
  bundler
54
54
  rake
55
55
  thor (>= 0.14.0)
56
- arel (6.0.3)
56
+ arel (6.0.4)
57
57
  bcrypt (3.1.11)
58
- builder (3.2.2)
58
+ builder (3.2.3)
59
59
  capybara (2.7.1)
60
60
  addressable
61
61
  mime-types (>= 1.16)
@@ -64,7 +64,7 @@ GEM
64
64
  rack-test (>= 0.5.4)
65
65
  xpath (~> 2.0)
66
66
  coderay (1.1.1)
67
- concurrent-ruby (1.0.2)
67
+ concurrent-ruby (1.0.4)
68
68
  database_cleaner (1.5.3)
69
69
  diff-lcs (1.2.5)
70
70
  email_validator (1.6.0)
@@ -78,7 +78,7 @@ GEM
78
78
  globalid (0.3.7)
79
79
  activesupport (>= 4.1.0)
80
80
  i18n (0.7.0)
81
- json (1.8.3)
81
+ json (1.8.6)
82
82
  loofah (2.0.3)
83
83
  nokogiri (>= 1.5.9)
84
84
  mail (2.6.4)
@@ -88,14 +88,14 @@ GEM
88
88
  mime-types-data (~> 3.2015)
89
89
  mime-types-data (3.2016.0521)
90
90
  mini_portile2 (2.1.0)
91
- minitest (5.9.1)
91
+ minitest (5.10.1)
92
92
  nokogiri (1.6.8.1)
93
93
  mini_portile2 (~> 2.1.0)
94
94
  pry (0.10.3)
95
95
  coderay (~> 1.1.0)
96
96
  method_source (~> 0.8.1)
97
97
  slop (~> 3.4)
98
- rack (1.6.4)
98
+ rack (1.6.5)
99
99
  rack-test (0.6.3)
100
100
  rack (>= 1.0)
101
101
  rails (4.2.7.1)
@@ -111,9 +111,9 @@ GEM
111
111
  sprockets-rails
112
112
  rails-deprecated_sanitizer (1.0.3)
113
113
  activesupport (>= 4.2.0.alpha)
114
- rails-dom-testing (1.0.7)
114
+ rails-dom-testing (1.0.8)
115
115
  activesupport (>= 4.2.0.beta, < 5.0)
116
- nokogiri (~> 1.6.0)
116
+ nokogiri (~> 1.6)
117
117
  rails-deprecated_sanitizer (>= 1.0.1)
118
118
  rails-html-sanitizer (1.0.3)
119
119
  loofah (~> 2.0)
@@ -122,7 +122,7 @@ GEM
122
122
  activesupport (= 4.2.7.1)
123
123
  rake (>= 0.8.7)
124
124
  thor (>= 0.18.1, < 2.0)
125
- rake (11.3.0)
125
+ rake (12.0.0)
126
126
  rspec-core (3.4.4)
127
127
  rspec-support (~> 3.4.0)
128
128
  rspec-expectations (3.4.0)
@@ -143,7 +143,7 @@ GEM
143
143
  shoulda-matchers (2.8.0)
144
144
  activesupport (>= 3.0.0)
145
145
  slop (3.6.0)
146
- sprockets (3.7.0)
146
+ sprockets (3.7.1)
147
147
  concurrent-ruby (~> 1.0)
148
148
  rack (> 1, < 3)
149
149
  sprockets-rails (3.2.0)
@@ -151,7 +151,7 @@ GEM
151
151
  activesupport (>= 4.0)
152
152
  sprockets (>= 3.0.0)
153
153
  sqlite3 (1.3.11)
154
- thor (0.19.1)
154
+ thor (0.19.4)
155
155
  thread_safe (0.3.5)
156
156
  timecop (0.8.1)
157
157
  tzinfo (1.2.2)
@@ -163,6 +163,7 @@ PLATFORMS
163
163
  ruby
164
164
 
165
165
  DEPENDENCIES
166
+ addressable (~> 2.4.0)
166
167
  ammeter
167
168
  appraisal
168
169
  bundler (~> 1.3)
@@ -170,6 +171,7 @@ DEPENDENCIES
170
171
  clearance!
171
172
  database_cleaner (~> 1.0)
172
173
  factory_girl_rails (~> 4.2)
174
+ nokogiri (~> 1.6.8)
173
175
  pry
174
176
  rspec-rails (~> 3.1)
175
177
  shoulda-matchers (~> 2.8)
data/NEWS.md CHANGED
@@ -3,6 +3,19 @@
3
3
  The noteworthy changes for each Clearance version are included here. For a
4
4
  complete changelog, see the git history for each version via the version links.
5
5
 
6
+ ## [1.16.0] - January 16, 2017
7
+
8
+ ### Security
9
+ - Clearance users can now help prevent [session fixation attacks] by setting
10
+ `Clearance.configuration.rotate_csrf_on_sign_in` to `true`. This will cause
11
+ the user's CSRF token to be rotated on sign in and is recommended for all
12
+ Clearance applications. This setting will default to `true` in Clearance 2.0.
13
+ Clearance will emit a warning on each sign in until this configuration setting
14
+ is explicitly set to `true` or `false`.
15
+
16
+ [session fixation attacks]: https://www.owasp.org/index.php/Session_fixation
17
+ [1.16.0]: https://github.com/thoughtbot/clearance/compare/v1.15.1...v1.16.0
18
+
6
19
  ## [1.15.1] - October 6, 2016
7
20
 
8
21
  ### Fixed
data/README.md CHANGED
@@ -58,12 +58,17 @@ Clearance.configure do |config|
58
58
  config.mailer_sender = "reply@example.com"
59
59
  config.password_strategy = Clearance::PasswordStrategies::BCrypt
60
60
  config.redirect_url = "/"
61
+ config.rotate_csrf_on_sign_in = false
61
62
  config.secure_cookie = false
62
63
  config.sign_in_guards = []
63
64
  config.user_model = User
64
65
  end
65
66
  ```
66
67
 
68
+ The install generator will set `rotate_csrf_on_sign_in` to `true`, so new
69
+ installations will get this behavior from the start. This helps avoid session
70
+ fixation attacks, and will become the default in Clearance 2.0.
71
+
67
72
  ## Use
68
73
 
69
74
  ### Access Control
@@ -2,12 +2,14 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "addressable", "~> 2.4.0"
5
6
  gem "appraisal", "~> 1.0"
6
7
  gem "ammeter"
7
8
  gem "bundler", "~> 1.3"
8
9
  gem "capybara", ">= 2.6.2"
9
10
  gem "database_cleaner", "~> 1.0"
10
11
  gem "factory_girl_rails", "~> 4.2"
12
+ gem "nokogiri", "~> 1.6.8"
11
13
  gem "rspec-rails", "~> 3.1"
12
14
  gem "shoulda-matchers", "~> 2.8"
13
15
  gem "sqlite3", "~> 1.3"
@@ -2,12 +2,14 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "addressable", "~> 2.4.0"
5
6
  gem "appraisal"
6
7
  gem "ammeter"
7
8
  gem "bundler", "~> 1.3"
8
9
  gem "capybara", ">= 2.6.2"
9
10
  gem "database_cleaner", "~> 1.0"
10
11
  gem "factory_girl_rails", "~> 4.2"
12
+ gem "nokogiri", "~> 1.6.8"
11
13
  gem "rspec-rails", "~> 3.1"
12
14
  gem "shoulda-matchers", "~> 2.8"
13
15
  gem "sqlite3", "~> 1.3"
@@ -2,12 +2,14 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "addressable", "~> 2.4.0"
5
6
  gem "appraisal"
6
7
  gem "ammeter"
7
8
  gem "bundler", "~> 1.3"
8
9
  gem "capybara", ">= 2.6.2"
9
10
  gem "database_cleaner", "~> 1.0"
10
11
  gem "factory_girl_rails", "~> 4.2"
12
+ gem "nokogiri", "~> 1.6.8"
11
13
  gem "rspec-rails", "~> 3.1"
12
14
  gem "shoulda-matchers", "~> 2.8"
13
15
  gem "sqlite3", "~> 1.3"
@@ -2,12 +2,14 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "addressable", "~> 2.4.0"
5
6
  gem "appraisal"
6
7
  gem "ammeter"
7
8
  gem "bundler", "~> 1.3"
8
9
  gem "capybara", ">= 2.6.2"
9
10
  gem "database_cleaner", "~> 1.0"
10
11
  gem "factory_girl_rails", "~> 4.2"
12
+ gem "nokogiri", "~> 1.6.8"
11
13
  gem "rspec-rails", "~> 3.1"
12
14
  gem "shoulda-matchers", "~> 2.8"
13
15
  gem "sqlite3", "~> 1.3"
@@ -2,12 +2,14 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
+ gem "addressable", "~> 2.4.0"
5
6
  gem "appraisal"
6
7
  gem "ammeter"
7
8
  gem "bundler", "~> 1.3"
8
9
  gem "capybara", ">= 2.6.2"
9
10
  gem "database_cleaner", "~> 1.0"
10
11
  gem "factory_girl_rails", "~> 4.2"
12
+ gem "nokogiri", "~> 1.6.8"
11
13
  gem "rspec-rails", "~> 3.5.0.beta1"
12
14
  gem "shoulda-matchers", "~> 2.8"
13
15
  gem "sqlite3", "~> 1.3"
@@ -62,8 +62,16 @@ module Clearance
62
62
  #
63
63
  # For an example of how clearance uses this internally, see
64
64
  # {SessionsController#create}.
65
+ #
66
+ # Signing in will also regenerate the CSRF token for the current session,
67
+ # provided {Configuration#rotate_csrf_token_on_sign_in} is set.
65
68
  def sign_in(user, &block)
66
- clearance_session.sign_in user, &block
69
+ clearance_session.sign_in(user, &block)
70
+
71
+ if signed_in? && Clearance.configuration.rotate_csrf_on_sign_in?
72
+ session.delete(:_csrf_token)
73
+ form_authenticity_token
74
+ end
67
75
  end
68
76
 
69
77
  # Destroy the current user's Clearance session.
@@ -58,6 +58,11 @@ module Clearance
58
58
  # @return [String]
59
59
  attr_accessor :redirect_url
60
60
 
61
+ # Controls whether Clearance will rotate the CSRF token on sign in.
62
+ # Defaults to `nil` which generates a warning. Will default to true in
63
+ # Clearance 2.0.
64
+ attr_accessor :rotate_csrf_on_sign_in
65
+
61
66
  # Set to `false` to disable Clearance's built-in routes.
62
67
  # Defaults to `true`. When set to false, your app is responsible for all
63
68
  # routes. You can dump a copy of Clearance's default routes with
@@ -95,6 +100,7 @@ module Clearance
95
100
  @mailer_sender = 'reply@example.com'
96
101
  @redirect_url = '/'
97
102
  @routes = true
103
+ @rotate_csrf_on_sign_in = nil
98
104
  @secure_cookie = false
99
105
  @sign_in_guards = []
100
106
  end
@@ -153,6 +159,25 @@ module Clearance
153
159
  @user_model = @user_model.to_s.constantize
154
160
  end
155
161
  end
162
+
163
+ def rotate_csrf_on_sign_in?
164
+ if rotate_csrf_on_sign_in.nil?
165
+ warn <<-EOM.squish
166
+ Clearance's `rotate_csrf_on_sign_in` configration setting is unset and
167
+ will be treated as `false`. Setting this value to `true` is
168
+ recommended to avoid session fixation attacks and will be the default
169
+ in Clearance 2.0. It is recommended that you opt-in to this setting
170
+ now and test your application. To silence this warning, set
171
+ `rotate_csrf_on_sign_in` to `true` or `false` in Clearance's
172
+ inializer.
173
+
174
+ For more information on session fixation, see:
175
+ https://www.owasp.org/index.php/Session_fixation
176
+ EOM
177
+ end
178
+
179
+ rotate_csrf_on_sign_in
180
+ end
156
181
  end
157
182
 
158
183
  # @return [Clearance::Configuration] Clearance's current configuration
@@ -1,3 +1,3 @@
1
1
  module Clearance
2
- VERSION = "1.15.1".freeze
2
+ VERSION = "1.16.0".freeze
3
3
  end
@@ -1,3 +1,4 @@
1
1
  Clearance.configure do |config|
2
2
  config.mailer_sender = "reply@example.com"
3
+ config.rotate_csrf_on_sign_in = true
3
4
  end
@@ -39,8 +39,6 @@ describe Clearance::Session do
39
39
 
40
40
  expect(headers["Set-Cookie"]).to match(/custom_cookie_name=.+;/)
41
41
  end
42
-
43
- after { restore_default_config }
44
42
  end
45
43
 
46
44
  describe '#sign_in' do
@@ -113,7 +111,6 @@ describe Clearance::Session do
113
111
  expect(session.current_user).to be_nil
114
112
  end
115
113
 
116
-
117
114
  def stub_sign_in_guard(options)
118
115
  session_status = stub_status(options.fetch(:succeed))
119
116
 
@@ -159,8 +156,6 @@ describe Clearance::Session do
159
156
 
160
157
  expect(headers['Set-Cookie']).to match(/remember_token=.+; HttpOnly/)
161
158
  end
162
-
163
- after { restore_default_config }
164
159
  end
165
160
 
166
161
  context 'if httponly is not set' do
@@ -270,8 +265,6 @@ describe Clearance::Session do
270
265
 
271
266
  expect(headers['Set-Cookie']).to match(/remember_token=.+; secure/)
272
267
  end
273
-
274
- after { restore_default_config }
275
268
  end
276
269
  end
277
270
 
@@ -287,8 +280,6 @@ describe Clearance::Session do
287
280
 
288
281
  expect(headers['Set-Cookie']).to match(/domain=\.example\.com; path/)
289
282
  end
290
-
291
- after { restore_default_config }
292
283
  end
293
284
 
294
285
  context 'when not set' do
@@ -324,8 +315,6 @@ describe Clearance::Session do
324
315
 
325
316
  expect(headers['Set-Cookie']).to match(/path=\/user; expires/)
326
317
  end
327
-
328
- after { restore_default_config }
329
318
  end
330
319
  end
331
320
 
@@ -375,7 +364,5 @@ describe Clearance::Session do
375
364
  def with_custom_expiration(custom_duration)
376
365
  Clearance.configuration.cookie_expiration = custom_duration
377
366
  yield
378
- ensure
379
- restore_default_config
380
367
  end
381
368
  end
@@ -1,8 +1,6 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Clearance::Configuration do
4
- after { restore_default_config }
5
-
6
4
  context "when no user_model_name is specified" do
7
5
  it "defaults to User" do
8
6
  expect(Clearance.configuration.user_model).to eq ::User
@@ -146,4 +144,30 @@ describe Clearance::Configuration do
146
144
  expect(Clearance.configuration.reload_user_model).to be_nil
147
145
  end
148
146
  end
147
+
148
+ describe "#rotate_csrf_on_sign_in?" do
149
+ it "defaults to falsey and warns" do
150
+ Clearance.configuration = Clearance::Configuration.new
151
+ allow(Clearance.configuration).to receive(:warn)
152
+
153
+ expect(Clearance.configuration.rotate_csrf_on_sign_in?).to be_falsey
154
+ expect(Clearance.configuration).to have_received(:warn)
155
+ end
156
+
157
+ it "is true and does not warn when `rotate_csrf_on_sign_in` is true" do
158
+ Clearance.configure { |config| config.rotate_csrf_on_sign_in = true }
159
+ allow(Clearance.configuration).to receive(:warn)
160
+
161
+ expect(Clearance.configuration.rotate_csrf_on_sign_in?).to be true
162
+ expect(Clearance.configuration).not_to have_received(:warn)
163
+ end
164
+
165
+ it "is false and does not warn when `rotate_csrf_on_sign_in` is false" do
166
+ Clearance.configure { |config| config.rotate_csrf_on_sign_in = false }
167
+ allow(Clearance.configuration).to receive(:warn)
168
+
169
+ expect(Clearance.configuration.rotate_csrf_on_sign_in?).to be false
170
+ expect(Clearance.configuration).not_to have_received(:warn)
171
+ end
172
+ end
149
173
  end
@@ -5,9 +5,7 @@ describe Clearance::PasswordsController do
5
5
 
6
6
  describe "#new" do
7
7
  it "renders the password reset form" do
8
- user = create(:user)
9
-
10
- get :new, user_id: user
8
+ get :new
11
9
 
12
10
  expect(response).to be_success
13
11
  expect(response).to render_template(:new)
@@ -0,0 +1,33 @@
1
+ require "spec_helper"
2
+
3
+ describe "CSRF Rotation" do
4
+ around do |example|
5
+ ActionController::Base.allow_forgery_protection = true
6
+ example.run
7
+ ActionController::Base.allow_forgery_protection = false
8
+ end
9
+
10
+ context "Clearance is configured to rotate CSRF token on sign in" do
11
+ describe "sign in" do
12
+ it "rotates the CSRF token" do
13
+ Clearance.configure { |config| config.rotate_csrf_on_sign_in = true }
14
+ get sign_in_path
15
+ user = create(:user, password: "password")
16
+ original_token = csrf_token
17
+
18
+ post session_path, session: session_params(user, "password")
19
+
20
+ expect(csrf_token).not_to eq original_token
21
+ expect(csrf_token).to be_present
22
+ end
23
+ end
24
+ end
25
+
26
+ def csrf_token
27
+ session[:_csrf_token]
28
+ end
29
+
30
+ def session_params(user, password)
31
+ { email: user.email, password: password, authenticity_token: csrf_token }
32
+ end
33
+ end
@@ -27,6 +27,8 @@ RSpec.configure do |config|
27
27
  mocks.syntax = :expect
28
28
  end
29
29
 
30
+ config.before { restore_default_warning_free_config }
31
+
30
32
  if Rails::VERSION::MAJOR >= 5
31
33
  require 'rails-controller-testing'
32
34
  config.include Rails::Controller::Testing::TestProcess
@@ -35,7 +37,7 @@ RSpec.configure do |config|
35
37
  end
36
38
  end
37
39
 
38
- def restore_default_config
40
+ def restore_default_warning_free_config
39
41
  Clearance.configuration = nil
40
- Clearance.configure {}
42
+ Clearance.configure { |config| config.rotate_csrf_on_sign_in = true }
41
43
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clearance
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.15.1
4
+ version: 1.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Croak
@@ -25,7 +25,7 @@ authors:
25
25
  autorequire:
26
26
  bindir: bin
27
27
  cert_chain: []
28
- date: 2016-10-06 00:00:00.000000000 Z
28
+ date: 2017-01-16 00:00:00.000000000 Z
29
29
  dependencies:
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: bcrypt
@@ -213,6 +213,7 @@ files:
213
213
  - spec/password_strategies/blowfish_spec.rb
214
214
  - spec/password_strategies/password_strategies_spec.rb
215
215
  - spec/password_strategies/sha1_spec.rb
216
+ - spec/requests/csrf_rotation_spec.rb
216
217
  - spec/routing/clearance_routes_spec.rb
217
218
  - spec/spec_helper.rb
218
219
  - spec/support/clearance.rb