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 +4 -4
- data/CHANGELOG.md +47 -4
- data/lib/action_controller/metal.rb +2 -2
- data/lib/action_controller/metal/params_wrapper.rb +2 -2
- data/lib/action_controller/test_case.rb +3 -2
- data/lib/action_dispatch.rb +5 -4
- data/lib/action_dispatch/http/response.rb +4 -3
- data/lib/action_dispatch/journey/path/pattern.rb +2 -1
- data/lib/action_dispatch/middleware/session/abstract_store.rb +14 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +11 -6
- data/lib/action_dispatch/middleware/session/cookie_store.rb +17 -7
- data/lib/action_dispatch/middleware/stack.rb +2 -2
- data/lib/action_dispatch/request/session.rb +7 -1
- data/lib/action_pack/gem_version.rb +2 -2
- metadata +17 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17edac04681c0d3a1f49b81fc2f1d6a19ca548cd1907dd84b93bd9bb4eaf7c13
|
4
|
+
data.tar.gz: c7903d709cebde205a7d7aec99b8f6d5d3ce39d7f1f54e9a829f4180b236c9bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c0eb2ce0a52c4bde406f914e23ee6ce0785d836c171769bb9da1a5342f2a0b0a2132dee11a9f15f348fb66f5be2b9aaab49e00d951c4ea9fa838a6da36595770
|
7
|
+
data.tar.gz: 2ab7695a61113cf2c52f0ea1fb33136a3d1e10fbc00c7c5fa06875006a2d8c62544cd20e9bff019f512c61d2bc64d7463359c57dc6a46e39c6267768b1c23d7e
|
data/CHANGELOG.md
CHANGED
@@ -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
|
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
|
6
|
-
it was excluded when `no-cache` was included. This
|
7
|
-
|
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 =
|
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 ||
|
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
|
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
|
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 || {})
|
data/lib/action_dispatch.rb
CHANGED
@@ -83,10 +83,11 @@ module ActionDispatch
|
|
83
83
|
end
|
84
84
|
|
85
85
|
module Session
|
86
|
-
autoload :AbstractStore,
|
87
|
-
autoload :
|
88
|
-
autoload :
|
89
|
-
autoload :
|
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
|
414
|
-
|
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
|
@@ -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 <
|
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 =
|
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(
|
50
|
-
"_session_id:#{
|
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 <
|
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 =
|
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
|
-
|
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.
|
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.
|
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-
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
297
|
-
changelog_uri: https://github.com/rails/rails/blob/v5.2.
|
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.
|
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).
|