actionpack 5.2.3 → 5.2.4.1

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

Potentially problematic release.


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

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fdbc11b76565d6d325a51b67c7a598b0a70c33e3e26c849dc57733e3fa7c0833
4
- data.tar.gz: 3afcd1526eb36e16fd199bb242fb232ddc3c01125e0d1306c94d31b315e93039
3
+ metadata.gz: 17edac04681c0d3a1f49b81fc2f1d6a19ca548cd1907dd84b93bd9bb4eaf7c13
4
+ data.tar.gz: c7903d709cebde205a7d7aec99b8f6d5d3ce39d7f1f54e9a829f4180b236c9bc
5
5
  SHA512:
6
- metadata.gz: 3122260924160e941c750fba0e3a671b2b2f40723c9c6766fae0f3987ac9521332d3a4128959fa61b993d72bd0539b7925ebb785b50d9b9811514897a2d5bf9e
7
- data.tar.gz: 4be02fcd7f87d2b725ba823274bc2c40eb367a2a26d7b1b53da8e4df699eae389fec796ff5164c7cb721426fa6cdf8f8b5ae5b6d74a712e5631e5e1ded283717
6
+ metadata.gz: c0eb2ce0a52c4bde406f914e23ee6ce0785d836c171769bb9da1a5342f2a0b0a2132dee11a9f15f348fb66f5be2b9aaab49e00d951c4ea9fa838a6da36595770
7
+ data.tar.gz: 2ab7695a61113cf2c52f0ea1fb33136a3d1e10fbc00c7c5fa06875006a2d8c62544cd20e9bff019f512c61d2bc64d7463359c57dc6a46e39c6267768b1c23d7e
@@ -1,10 +1,25 @@
1
+ ## Rails 5.2.4.1 (December 18, 2019) ##
2
+
3
+ * Fix possible information leak / session hijacking vulnerability.
4
+
5
+ The `ActionDispatch::Session::MemcacheStore` is still vulnerable given it requires the
6
+ gem dalli to be updated as well.
7
+
8
+ CVE-2019-16782.
9
+
10
+
11
+ ## Rails 5.2.4 (November 27, 2019) ##
12
+
13
+ * No changes.
14
+
15
+
1
16
  ## Rails 5.2.3 (March 27, 2019) ##
2
17
 
3
- * Allow using combine the Cache Control `public` and `no-cache` headers.
18
+ * Allow using `public` and `no-cache` together in the the Cache Control header.
4
19
 
5
- Before this change, even if `public` was specified for Cache Control header,
6
- it was excluded when `no-cache` was included. This fixed to keep `public`
7
- header as is.
20
+ Before this change, even if `public` was specified in the Cache Control header,
21
+ it was excluded when `no-cache` was included. This change preserves the
22
+ `public` value as is.
8
23
 
9
24
  Fixes #34780.
10
25
 
@@ -186,6 +201,34 @@
186
201
 
187
202
  * Matches behavior of `Hash#each` in `ActionController::Parameters#each`.
188
203
 
204
+ Rails 5.0 introduced a bug when looping through controller params using `each`. Only the keys of params hash were passed to the block, e.g.
205
+
206
+ # Parameters: {"param"=>"1", "param_two"=>"2"}
207
+ def index
208
+ params.each do |name|
209
+ puts name
210
+ end
211
+ end
212
+
213
+ # Prints
214
+ # param
215
+ # param_two
216
+
217
+ In Rails 5.2 the bug has been fixed and name will be an array (which was the behavior for all versions prior to 5.0), instead of a string.
218
+
219
+ To fix the code above simply change as per example below:
220
+
221
+ # Parameters: {"param"=>"1", "param_two"=>"2"}
222
+ def index
223
+ params.each do |name, value|
224
+ puts name
225
+ end
226
+ end
227
+
228
+ # Prints
229
+ # param
230
+ # param_two
231
+
189
232
  *Dominic Cleal*
190
233
 
191
234
  * Add `Referrer-Policy` header to default headers set.
@@ -26,10 +26,10 @@ module ActionController
26
26
  end
27
27
  end
28
28
 
29
- def build(action, app = Proc.new)
29
+ def build(action, app = nil, &block)
30
30
  action = action.to_s
31
31
 
32
- middlewares.reverse.inject(app) do |a, middleware|
32
+ middlewares.reverse.inject(app || block) do |a, middleware|
33
33
  middleware.valid?(action) ? middleware.build(a) : a
34
34
  end
35
35
  end
@@ -93,7 +93,7 @@ module ActionController
93
93
  end
94
94
 
95
95
  def model
96
- super || synchronize { super || self.model = _default_wrap_model }
96
+ super || self.model = _default_wrap_model
97
97
  end
98
98
 
99
99
  def include
@@ -115,7 +115,7 @@ module ActionController
115
115
 
116
116
  if m.respond_to?(:nested_attributes_options) && m.nested_attributes_options.keys.any?
117
117
  self.include += m.nested_attributes_options.keys.map do |key|
118
- key.to_s.concat("_attributes")
118
+ key.to_s.dup.concat("_attributes")
119
119
  end
120
120
  end
121
121
 
@@ -460,6 +460,7 @@ module ActionController
460
460
  def process(action, method: "GET", params: nil, session: nil, body: nil, flash: {}, format: nil, xhr: false, as: nil)
461
461
  check_required_ivars
462
462
 
463
+ action = action.to_s.dup
463
464
  http_method = method.to_s.upcase
464
465
 
465
466
  @html_document = nil
@@ -491,11 +492,11 @@ module ActionController
491
492
  parameters[:format] = format
492
493
  end
493
494
 
494
- generated_extras = @routes.generate_extras(parameters.merge(controller: controller_class_name, action: action.to_s))
495
+ generated_extras = @routes.generate_extras(parameters.merge(controller: controller_class_name, action: action))
495
496
  generated_path = generated_path(generated_extras)
496
497
  query_string_keys = query_parameter_names(generated_extras)
497
498
 
498
- @request.assign_parameters(@routes, controller_class_name, action.to_s, parameters, generated_path, query_string_keys)
499
+ @request.assign_parameters(@routes, controller_class_name, action, parameters, generated_path, query_string_keys)
499
500
 
500
501
  @request.session.update(session) if session
501
502
  @request.flash.update(flash || {})
@@ -83,10 +83,11 @@ module ActionDispatch
83
83
  end
84
84
 
85
85
  module Session
86
- autoload :AbstractStore, "action_dispatch/middleware/session/abstract_store"
87
- autoload :CookieStore, "action_dispatch/middleware/session/cookie_store"
88
- autoload :MemCacheStore, "action_dispatch/middleware/session/mem_cache_store"
89
- autoload :CacheStore, "action_dispatch/middleware/session/cache_store"
86
+ autoload :AbstractStore, "action_dispatch/middleware/session/abstract_store"
87
+ autoload :AbstractSecureStore, "action_dispatch/middleware/session/abstract_store"
88
+ autoload :CookieStore, "action_dispatch/middleware/session/cookie_store"
89
+ autoload :MemCacheStore, "action_dispatch/middleware/session/mem_cache_store"
90
+ autoload :CacheStore, "action_dispatch/middleware/session/cache_store"
90
91
  end
91
92
 
92
93
  mattr_accessor :test_app
@@ -82,7 +82,6 @@ module ActionDispatch # :nodoc:
82
82
  SET_COOKIE = "Set-Cookie".freeze
83
83
  LOCATION = "Location".freeze
84
84
  NO_CONTENT_CODES = [100, 101, 102, 204, 205, 304]
85
- CONTENT_TYPE_PARSER = /\A(?<type>[^;\s]+)?(?:.*;\s*charset=(?<quote>"?)(?<charset>[^;\s]+)\k<quote>)?/ # :nodoc:
86
85
 
87
86
  cattr_accessor :default_charset, default: "utf-8"
88
87
  cattr_accessor :default_headers
@@ -410,8 +409,10 @@ module ActionDispatch # :nodoc:
410
409
  NullContentTypeHeader = ContentTypeHeader.new nil, nil
411
410
 
412
411
  def parse_content_type(content_type)
413
- if content_type && match = CONTENT_TYPE_PARSER.match(content_type)
414
- ContentTypeHeader.new(match[:type], match[:charset])
412
+ if content_type
413
+ type, charset = content_type.split(/;\s*charset=/)
414
+ type = nil if type && type.empty?
415
+ ContentTypeHeader.new(type, charset)
415
416
  else
416
417
  NullContentTypeHeader
417
418
  end
@@ -119,7 +119,8 @@ module ActionDispatch
119
119
 
120
120
  class UnanchoredRegexp < AnchoredRegexp # :nodoc:
121
121
  def accept(node)
122
- %r{\A#{visit node}(?:\b|\Z)}
122
+ path = visit node
123
+ path == "/" ? %r{\A/} : %r{\A#{path}(?:\b|\Z|/)}
123
124
  end
124
125
  end
125
126
 
@@ -83,7 +83,21 @@ module ActionDispatch
83
83
  include SessionObject
84
84
 
85
85
  private
86
+ def set_cookie(request, session_id, cookie)
87
+ request.cookie_jar[key] = cookie
88
+ end
89
+ end
90
+
91
+ class AbstractSecureStore < Rack::Session::Abstract::PersistedSecure
92
+ include Compatibility
93
+ include StaleSessionCheck
94
+ include SessionObject
95
+
96
+ def generate_sid
97
+ Rack::Session::SessionId.new(super)
98
+ end
86
99
 
100
+ private
87
101
  def set_cookie(request, session_id, cookie)
88
102
  request.cookie_jar[key] = cookie
89
103
  end
@@ -12,7 +12,7 @@ module ActionDispatch
12
12
  # * <tt>cache</tt> - The cache to use. If it is not specified, <tt>Rails.cache</tt> will be used.
13
13
  # * <tt>expire_after</tt> - The length of time a session will be stored before automatically expiring.
14
14
  # By default, the <tt>:expires_in</tt> option of the cache is used.
15
- class CacheStore < AbstractStore
15
+ class CacheStore < AbstractSecureStore
16
16
  def initialize(app, options = {})
17
17
  @cache = options[:cache] || Rails.cache
18
18
  options[:expire_after] ||= @cache.options[:expires_in]
@@ -21,7 +21,7 @@ module ActionDispatch
21
21
 
22
22
  # Get a session from the cache.
23
23
  def find_session(env, sid)
24
- unless sid && (session = @cache.read(cache_key(sid)))
24
+ unless sid && (session = get_session_with_fallback(sid))
25
25
  sid, session = generate_sid, {}
26
26
  end
27
27
  [sid, session]
@@ -29,7 +29,7 @@ module ActionDispatch
29
29
 
30
30
  # Set a session in the cache.
31
31
  def write_session(env, sid, session, options)
32
- key = cache_key(sid)
32
+ key = cache_key(sid.private_id)
33
33
  if session
34
34
  @cache.write(key, session, expires_in: options[:expire_after])
35
35
  else
@@ -40,14 +40,19 @@ module ActionDispatch
40
40
 
41
41
  # Remove a session from the cache.
42
42
  def delete_session(env, sid, options)
43
- @cache.delete(cache_key(sid))
43
+ @cache.delete(cache_key(sid.private_id))
44
+ @cache.delete(cache_key(sid.public_id))
44
45
  generate_sid
45
46
  end
46
47
 
47
48
  private
48
49
  # Turn the session id into a cache key.
49
- def cache_key(sid)
50
- "_session_id:#{sid}"
50
+ def cache_key(id)
51
+ "_session_id:#{id}"
52
+ end
53
+
54
+ def get_session_with_fallback(sid)
55
+ @cache.read(cache_key(sid.private_id)) || @cache.read(cache_key(sid.public_id))
51
56
  end
52
57
  end
53
58
  end
@@ -51,7 +51,16 @@ module ActionDispatch
51
51
  # would set the session cookie to expire automatically 14 days after creation.
52
52
  # Other useful options include <tt>:key</tt>, <tt>:secure</tt> and
53
53
  # <tt>:httponly</tt>.
54
- class CookieStore < AbstractStore
54
+ class CookieStore < AbstractSecureStore
55
+ class SessionId < DelegateClass(Rack::Session::SessionId)
56
+ attr_reader :cookie_value
57
+
58
+ def initialize(session_id, cookie_value = {})
59
+ super(session_id)
60
+ @cookie_value = cookie_value
61
+ end
62
+ end
63
+
55
64
  def initialize(app, options = {})
56
65
  super(app, options.merge!(cookie_only: true))
57
66
  end
@@ -59,7 +68,7 @@ module ActionDispatch
59
68
  def delete_session(req, session_id, options)
60
69
  new_sid = generate_sid unless options[:drop]
61
70
  # Reset hash and Assign the new session id
62
- req.set_header("action_dispatch.request.unsigned_session_cookie", new_sid ? { "session_id" => new_sid } : {})
71
+ req.set_header("action_dispatch.request.unsigned_session_cookie", new_sid ? { "session_id" => new_sid.public_id } : {})
63
72
  new_sid
64
73
  end
65
74
 
@@ -67,7 +76,7 @@ module ActionDispatch
67
76
  stale_session_check! do
68
77
  data = unpacked_cookie_data(req)
69
78
  data = persistent_session_id!(data)
70
- [data["session_id"], data]
79
+ [Rack::Session::SessionId.new(data["session_id"]), data]
71
80
  end
72
81
  end
73
82
 
@@ -75,7 +84,8 @@ module ActionDispatch
75
84
 
76
85
  def extract_session_id(req)
77
86
  stale_session_check! do
78
- unpacked_cookie_data(req)["session_id"]
87
+ sid = unpacked_cookie_data(req)["session_id"]
88
+ sid && Rack::Session::SessionId.new(sid)
79
89
  end
80
90
  end
81
91
 
@@ -93,13 +103,13 @@ module ActionDispatch
93
103
 
94
104
  def persistent_session_id!(data, sid = nil)
95
105
  data ||= {}
96
- data["session_id"] ||= sid || generate_sid
106
+ data["session_id"] ||= sid || generate_sid.public_id
97
107
  data
98
108
  end
99
109
 
100
110
  def write_session(req, sid, session_data, options)
101
- session_data["session_id"] = sid
102
- session_data
111
+ session_data["session_id"] = sid.public_id
112
+ SessionId.new(sid, session_data)
103
113
  end
104
114
 
105
115
  def set_cookie(request, session_id, cookie)
@@ -97,8 +97,8 @@ module ActionDispatch
97
97
  middlewares.push(build_middleware(klass, args, block))
98
98
  end
99
99
 
100
- def build(app = Proc.new)
101
- middlewares.freeze.reverse.inject(app) { |a, e| e.build(a) }
100
+ def build(app = nil, &block)
101
+ middlewares.freeze.reverse.inject(app || block) { |a, e| e.build(a) }
102
102
  end
103
103
 
104
104
  private
@@ -90,7 +90,13 @@ module ActionDispatch
90
90
  # +nil+ if the given key is not found in the session.
91
91
  def [](key)
92
92
  load_for_read!
93
- @delegate[key.to_s]
93
+ key = key.to_s
94
+
95
+ if key == "session_id"
96
+ id&.public_id
97
+ else
98
+ @delegate[key]
99
+ end
94
100
  end
95
101
 
96
102
  # Returns true if the session has the given key or false.
@@ -9,8 +9,8 @@ module ActionPack
9
9
  module VERSION
10
10
  MAJOR = 5
11
11
  MINOR = 2
12
- TINY = 3
13
- PRE = nil
12
+ TINY = 4
13
+ PRE = "1"
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
16
16
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: actionpack
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.2.3
4
+ version: 5.2.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Heinemeier Hansson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-28 00:00:00.000000000 Z
11
+ date: 2019-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: 5.2.3
19
+ version: 5.2.4.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: 5.2.3
26
+ version: 5.2.4.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rack
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -31,6 +31,9 @@ dependencies:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '2.0'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 2.0.8
34
37
  type: :runtime
35
38
  prerelease: false
36
39
  version_requirements: !ruby/object:Gem::Requirement
@@ -38,6 +41,9 @@ dependencies:
38
41
  - - "~>"
39
42
  - !ruby/object:Gem::Version
40
43
  version: '2.0'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 2.0.8
41
47
  - !ruby/object:Gem::Dependency
42
48
  name: rack-test
43
49
  requirement: !ruby/object:Gem::Requirement
@@ -92,28 +98,28 @@ dependencies:
92
98
  requirements:
93
99
  - - '='
94
100
  - !ruby/object:Gem::Version
95
- version: 5.2.3
101
+ version: 5.2.4.1
96
102
  type: :runtime
97
103
  prerelease: false
98
104
  version_requirements: !ruby/object:Gem::Requirement
99
105
  requirements:
100
106
  - - '='
101
107
  - !ruby/object:Gem::Version
102
- version: 5.2.3
108
+ version: 5.2.4.1
103
109
  - !ruby/object:Gem::Dependency
104
110
  name: activemodel
105
111
  requirement: !ruby/object:Gem::Requirement
106
112
  requirements:
107
113
  - - '='
108
114
  - !ruby/object:Gem::Version
109
- version: 5.2.3
115
+ version: 5.2.4.1
110
116
  type: :development
111
117
  prerelease: false
112
118
  version_requirements: !ruby/object:Gem::Requirement
113
119
  requirements:
114
120
  - - '='
115
121
  - !ruby/object:Gem::Version
116
- version: 5.2.3
122
+ version: 5.2.4.1
117
123
  description: Web apps on Rails. Simple, battle-tested conventions for building and
118
124
  testing MVC web applications. Works with any Rack-compatible server.
119
125
  email: david@loudthinking.com
@@ -293,8 +299,8 @@ homepage: http://rubyonrails.org
293
299
  licenses:
294
300
  - MIT
295
301
  metadata:
296
- source_code_uri: https://github.com/rails/rails/tree/v5.2.3/actionpack
297
- changelog_uri: https://github.com/rails/rails/blob/v5.2.3/actionpack/CHANGELOG.md
302
+ source_code_uri: https://github.com/rails/rails/tree/v5.2.4.1/actionpack
303
+ changelog_uri: https://github.com/rails/rails/blob/v5.2.4.1/actionpack/CHANGELOG.md
298
304
  post_install_message:
299
305
  rdoc_options: []
300
306
  require_paths:
@@ -311,7 +317,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
311
317
  version: '0'
312
318
  requirements:
313
319
  - none
314
- rubygems_version: 3.0.1
320
+ rubygems_version: 3.0.3
315
321
  signing_key:
316
322
  specification_version: 4
317
323
  summary: Web-flow and rendering framework putting the VC in MVC (part of Rails).