actionpack 6.1.4.2 → 6.1.7.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +151 -0
- data/MIT-LICENSE +1 -2
- data/lib/abstract_controller/collector.rb +4 -2
- data/lib/action_controller/metal/http_authentication.rb +1 -0
- data/lib/action_controller/metal/redirecting.rb +20 -1
- data/lib/action_controller/metal/rendering.rb +2 -2
- data/lib/action_controller/metal/strong_parameters.rb +1 -1
- data/lib/action_dispatch/http/cache.rb +1 -1
- data/lib/action_dispatch/http/content_security_policy.rb +2 -8
- data/lib/action_dispatch/http/response.rb +2 -2
- data/lib/action_dispatch/middleware/cookies.rb +28 -20
- data/lib/action_dispatch/middleware/executor.rb +1 -1
- data/lib/action_dispatch/middleware/host_authorization.rb +70 -20
- data/lib/action_dispatch/middleware/show_exceptions.rb +10 -0
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +1 -1
- data/lib/action_dispatch/routing/route_set.rb +2 -2
- data/lib/action_dispatch/system_test_case.rb +7 -1
- data/lib/action_dispatch/testing/test_process.rb +10 -7
- data/lib/action_dispatch.rb +1 -1
- data/lib/action_pack/gem_version.rb +2 -2
- data/lib/action_pack.rb +1 -1
- metadata +13 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 205004120a6da1bd9f41fd3214ae124b861c46d02efa302ad5cd6e76ae8a7f54
|
4
|
+
data.tar.gz: fd92a15b1a7beed26910076fcec04a9e28143e96e6016b7f4cfd18654c85aa12
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10e83333b2ee3da5b0210b6cd45e5e4520177e333e61b3e465301ad4e327baaa859b4462415b898ee76f42d5adc4815788d23d7c8d3b2aa5e104c7c74680cc97
|
7
|
+
data.tar.gz: 69dfca4a29df0b5b666cd7f918e672901a668f2a662f83aa38d60d3c11ce44cae4329e22c353958f4ab1bf511a0fdf03631fb20300d4717a5a66945519d2021a
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,154 @@
|
|
1
|
+
## Rails 6.1.7.7 (February 21, 2024) ##
|
2
|
+
|
3
|
+
* No changes.
|
4
|
+
|
5
|
+
|
6
|
+
## Rails 6.1.7.6 (August 22, 2023) ##
|
7
|
+
|
8
|
+
* No changes.
|
9
|
+
|
10
|
+
|
11
|
+
## Rails 6.1.7.5 (August 22, 2023) ##
|
12
|
+
|
13
|
+
* No changes.
|
14
|
+
|
15
|
+
|
16
|
+
## Rails 6.1.7.4 (June 26, 2023) ##
|
17
|
+
|
18
|
+
* Raise an exception if illegal characters are provide to redirect_to
|
19
|
+
[CVE-2023-28362]
|
20
|
+
|
21
|
+
*Zack Deveau*
|
22
|
+
|
23
|
+
## Rails 6.1.7.3 (March 13, 2023) ##
|
24
|
+
|
25
|
+
* No changes.
|
26
|
+
|
27
|
+
|
28
|
+
## Rails 6.1.7.2 (January 24, 2023) ##
|
29
|
+
|
30
|
+
* Fix `domain: :all` for two letter TLD
|
31
|
+
|
32
|
+
This fixes a compatibility issue introduced in our previous security
|
33
|
+
release when using `domain: :all` with a two letter but single level top
|
34
|
+
level domain domain (like `.ca`, rather than `.co.uk`).
|
35
|
+
|
36
|
+
|
37
|
+
## Rails 6.1.7.1 (January 17, 2023) ##
|
38
|
+
|
39
|
+
* Avoid regex backtracking on If-None-Match header
|
40
|
+
|
41
|
+
[CVE-2023-22795]
|
42
|
+
|
43
|
+
* Use string#split instead of regex for domain parts
|
44
|
+
|
45
|
+
[CVE-2023-22792]
|
46
|
+
|
47
|
+
|
48
|
+
## Rails 6.1.7 (September 09, 2022) ##
|
49
|
+
|
50
|
+
* No changes.
|
51
|
+
|
52
|
+
|
53
|
+
## Rails 6.1.6.1 (July 12, 2022) ##
|
54
|
+
|
55
|
+
* No changes.
|
56
|
+
|
57
|
+
|
58
|
+
## Rails 6.1.6 (May 09, 2022) ##
|
59
|
+
|
60
|
+
* No changes.
|
61
|
+
|
62
|
+
|
63
|
+
## Rails 6.1.5.1 (April 26, 2022) ##
|
64
|
+
|
65
|
+
* Allow Content Security Policy DSL to generate for API responses.
|
66
|
+
|
67
|
+
*Tim Wade*
|
68
|
+
|
69
|
+
## Rails 6.1.5 (March 09, 2022) ##
|
70
|
+
|
71
|
+
* Fix `content_security_policy` returning invalid directives.
|
72
|
+
|
73
|
+
Directives such as `self`, `unsafe-eval` and few others were not
|
74
|
+
single quoted when the directive was the result of calling a lambda
|
75
|
+
returning an array.
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
content_security_policy do |policy|
|
79
|
+
policy.frame_ancestors lambda { [:self, "https://example.com"] }
|
80
|
+
end
|
81
|
+
```
|
82
|
+
|
83
|
+
With this fix the policy generated from above will now be valid.
|
84
|
+
|
85
|
+
*Edouard Chin*
|
86
|
+
|
87
|
+
* Update `HostAuthorization` middleware to render debug info only
|
88
|
+
when `config.consider_all_requests_local` is set to true.
|
89
|
+
|
90
|
+
Also, blocked host info is always logged with level `error`.
|
91
|
+
|
92
|
+
Fixes #42813.
|
93
|
+
|
94
|
+
*Nikita Vyrko*
|
95
|
+
|
96
|
+
* Dup arrays that get "converted".
|
97
|
+
|
98
|
+
Fixes #43681.
|
99
|
+
|
100
|
+
*Aaron Patterson*
|
101
|
+
|
102
|
+
* Don't show deprecation warning for equal paths.
|
103
|
+
|
104
|
+
*Anton Rieder*
|
105
|
+
|
106
|
+
* Fix crash in `ActionController::Instrumentation` with invalid HTTP formats.
|
107
|
+
|
108
|
+
Fixes #43094.
|
109
|
+
|
110
|
+
*Alex Ghiculescu*
|
111
|
+
|
112
|
+
* Add fallback host for SystemTestCase driven by RackTest.
|
113
|
+
|
114
|
+
Fixes #42780.
|
115
|
+
|
116
|
+
*Petrik de Heus*
|
117
|
+
|
118
|
+
* Add more detail about what hosts are allowed.
|
119
|
+
|
120
|
+
*Alex Ghiculescu*
|
121
|
+
|
122
|
+
|
123
|
+
## Rails 6.1.4.7 (March 08, 2022) ##
|
124
|
+
|
125
|
+
* No changes.
|
126
|
+
|
127
|
+
|
128
|
+
## Rails 6.1.4.6 (February 11, 2022) ##
|
129
|
+
|
130
|
+
* No changes.
|
131
|
+
|
132
|
+
|
133
|
+
## Rails 6.1.4.5 (February 11, 2022) ##
|
134
|
+
|
135
|
+
* Under certain circumstances, the middleware isn't informed that the
|
136
|
+
response body has been fully closed which result in request state not
|
137
|
+
being fully reset before the next request
|
138
|
+
|
139
|
+
[CVE-2022-23633]
|
140
|
+
|
141
|
+
|
142
|
+
## Rails 6.1.4.4 (December 15, 2021) ##
|
143
|
+
|
144
|
+
* Fix issue with host protection not allowing host with port in development.
|
145
|
+
|
146
|
+
|
147
|
+
## Rails 6.1.4.3 (December 14, 2021) ##
|
148
|
+
|
149
|
+
* Fix issue with host protection not allowing localhost in development.
|
150
|
+
|
151
|
+
|
1
152
|
## Rails 6.1.4.2 (December 14, 2021) ##
|
2
153
|
|
3
154
|
* Fix X_FORWARDED_HOST protection. [CVE-2021-44528]
|
data/MIT-LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Copyright (c) 2004-
|
1
|
+
Copyright (c) 2004-2022 David Heinemeier Hansson
|
2
2
|
|
3
3
|
Permission is hereby granted, free of charge, to any person obtaining
|
4
4
|
a copy of this software and associated documentation files (the
|
@@ -18,4 +18,3 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
18
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
19
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
20
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
-
|
@@ -10,6 +10,7 @@ module AbstractController
|
|
10
10
|
def #{sym}(*args, &block)
|
11
11
|
custom(Mime[:#{sym}], *args, &block)
|
12
12
|
end
|
13
|
+
ruby2_keywords(:#{sym}) if respond_to?(:ruby2_keywords, true)
|
13
14
|
RUBY
|
14
15
|
end
|
15
16
|
|
@@ -22,7 +23,7 @@ module AbstractController
|
|
22
23
|
end
|
23
24
|
|
24
25
|
private
|
25
|
-
def method_missing(symbol, &block)
|
26
|
+
def method_missing(symbol, *args, &block)
|
26
27
|
unless mime_constant = Mime[symbol]
|
27
28
|
raise NoMethodError, "To respond to a custom format, register it as a MIME type first: " \
|
28
29
|
"https://guides.rubyonrails.org/action_controller_overview.html#restful-downloads. " \
|
@@ -33,10 +34,11 @@ module AbstractController
|
|
33
34
|
|
34
35
|
if Mime::SET.include?(mime_constant)
|
35
36
|
AbstractController::Collector.generate_method_for_mime(mime_constant)
|
36
|
-
|
37
|
+
public_send(symbol, *args, &block)
|
37
38
|
else
|
38
39
|
super
|
39
40
|
end
|
40
41
|
end
|
42
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
41
43
|
end
|
42
44
|
end
|
@@ -7,6 +7,10 @@ module ActionController
|
|
7
7
|
include AbstractController::Logger
|
8
8
|
include ActionController::UrlFor
|
9
9
|
|
10
|
+
ILLEGAL_HEADER_VALUE_REGEX = /[\x00-\x08\x0A-\x1F]/.freeze
|
11
|
+
|
12
|
+
class UnsafeRedirectError < StandardError; end
|
13
|
+
|
10
14
|
# Redirects the browser to the target specified in +options+. This parameter can be any one of:
|
11
15
|
#
|
12
16
|
# * <tt>Hash</tt> - The URL will be generated by calling url_for with the +options+.
|
@@ -60,7 +64,11 @@ module ActionController
|
|
60
64
|
raise AbstractController::DoubleRenderError if response_body
|
61
65
|
|
62
66
|
self.status = _extract_redirect_to_status(options, response_options)
|
63
|
-
|
67
|
+
|
68
|
+
redirect_to_location = _compute_redirect_to_location(request, options)
|
69
|
+
_ensure_url_is_http_header_safe(redirect_to_location)
|
70
|
+
|
71
|
+
self.location = redirect_to_location
|
64
72
|
self.response_body = "<html><body>You are being <a href=\"#{ERB::Util.unwrapped_html_escape(response.location)}\">redirected</a>.</body></html>"
|
65
73
|
end
|
66
74
|
|
@@ -129,5 +137,16 @@ module ActionController
|
|
129
137
|
rescue ArgumentError, URI::Error
|
130
138
|
false
|
131
139
|
end
|
140
|
+
|
141
|
+
def _ensure_url_is_http_header_safe(url)
|
142
|
+
# Attempt to comply with the set of valid token characters
|
143
|
+
# defined for an HTTP header value in
|
144
|
+
# https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6
|
145
|
+
if url.match(ILLEGAL_HEADER_VALUE_REGEX)
|
146
|
+
msg = "The redirect URL #{url} contains one or more illegal HTTP header field character. " \
|
147
|
+
"Set of legal characters defined in https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.6"
|
148
|
+
raise UnsafeRedirectError, msg
|
149
|
+
end
|
150
|
+
end
|
132
151
|
end
|
133
152
|
end
|
@@ -78,8 +78,8 @@ module ActionController
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def _set_vary_header
|
81
|
-
if
|
82
|
-
|
81
|
+
if response.headers["Vary"].blank? && request.should_apply_vary_header?
|
82
|
+
response.headers["Vary"] = "Accept"
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
@@ -940,7 +940,7 @@ module ActionController
|
|
940
940
|
when Array
|
941
941
|
return value if converted_arrays.member?(value)
|
942
942
|
converted = value.map { |_| convert_value_to_parameters(_) }
|
943
|
-
converted_arrays << converted
|
943
|
+
converted_arrays << converted.dup
|
944
944
|
converted
|
945
945
|
when Hash
|
946
946
|
self.class.new(value)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_support/core_ext/object/deep_dup"
|
4
|
+
require "active_support/core_ext/array/wrap"
|
4
5
|
|
5
6
|
module ActionDispatch #:nodoc:
|
6
7
|
class ContentSecurityPolicy
|
@@ -17,7 +18,6 @@ module ActionDispatch #:nodoc:
|
|
17
18
|
request = ActionDispatch::Request.new env
|
18
19
|
_, headers, _ = response = @app.call(env)
|
19
20
|
|
20
|
-
return response unless html_response?(headers)
|
21
21
|
return response if policy_present?(headers)
|
22
22
|
|
23
23
|
if policy = request.content_security_policy
|
@@ -31,12 +31,6 @@ module ActionDispatch #:nodoc:
|
|
31
31
|
end
|
32
32
|
|
33
33
|
private
|
34
|
-
def html_response?(headers)
|
35
|
-
if content_type = headers[CONTENT_TYPE]
|
36
|
-
/html/.match?(content_type)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
34
|
def header_name(request)
|
41
35
|
if request.content_security_policy_report_only
|
42
36
|
POLICY_REPORT_ONLY
|
@@ -272,7 +266,7 @@ module ActionDispatch #:nodoc:
|
|
272
266
|
raise RuntimeError, "Missing context for the dynamic content security policy source: #{source.inspect}"
|
273
267
|
else
|
274
268
|
resolved = context.instance_exec(&source)
|
275
|
-
|
269
|
+
apply_mappings(Array.wrap(resolved))
|
276
270
|
end
|
277
271
|
else
|
278
272
|
raise RuntimeError, "Unexpected content security policy source: #{source.inspect}"
|
@@ -88,13 +88,13 @@ module ActionDispatch # :nodoc:
|
|
88
88
|
|
89
89
|
def self.return_only_media_type_on_content_type=(*)
|
90
90
|
ActiveSupport::Deprecation.warn(
|
91
|
-
".return_only_media_type_on_content_type= is dreprecated with no replacement and will be removed in
|
91
|
+
".return_only_media_type_on_content_type= is dreprecated with no replacement and will be removed in 7.0."
|
92
92
|
)
|
93
93
|
end
|
94
94
|
|
95
95
|
def self.return_only_media_type_on_content_type
|
96
96
|
ActiveSupport::Deprecation.warn(
|
97
|
-
".return_only_media_type_on_content_type is dreprecated with no replacement and will be removed in
|
97
|
+
".return_only_media_type_on_content_type is dreprecated with no replacement and will be removed in 7.0."
|
98
98
|
)
|
99
99
|
end
|
100
100
|
|
@@ -283,20 +283,6 @@ module ActionDispatch
|
|
283
283
|
class CookieJar #:nodoc:
|
284
284
|
include Enumerable, ChainedCookieJars
|
285
285
|
|
286
|
-
# This regular expression is used to split the levels of a domain.
|
287
|
-
# The top level domain can be any string without a period or
|
288
|
-
# **.**, ***.** style TLDs like co.uk or com.au
|
289
|
-
#
|
290
|
-
# www.example.co.uk gives:
|
291
|
-
# $& => example.co.uk
|
292
|
-
#
|
293
|
-
# example.com gives:
|
294
|
-
# $& => example.com
|
295
|
-
#
|
296
|
-
# lots.of.subdomains.example.local gives:
|
297
|
-
# $& => example.local
|
298
|
-
DOMAIN_REGEXP = /[^.]*\.([^.]*|..\...|...\...)$/
|
299
|
-
|
300
286
|
def self.build(req, cookies)
|
301
287
|
jar = new(req)
|
302
288
|
jar.update(cookies)
|
@@ -449,13 +435,35 @@ module ActionDispatch
|
|
449
435
|
options[:same_site] ||= cookies_same_site_protection.call(request)
|
450
436
|
|
451
437
|
if options[:domain] == :all || options[:domain] == "all"
|
452
|
-
|
453
|
-
|
438
|
+
cookie_domain = ""
|
439
|
+
dot_splitted_host = request.host.split('.', -1)
|
440
|
+
|
441
|
+
# Case where request.host is not an IP address or it's an invalid domain
|
442
|
+
# (ip confirms to the domain structure we expect so we explicitly check for ip)
|
443
|
+
if request.host.match?(/^[\d.]+$/) || dot_splitted_host.include?("") || dot_splitted_host.length == 1
|
444
|
+
options[:domain] = nil
|
445
|
+
return
|
446
|
+
end
|
447
|
+
|
448
|
+
# If there is a provided tld length then we use it otherwise default domain.
|
449
|
+
if options[:tld_length].present?
|
450
|
+
# Case where the tld_length provided is valid
|
451
|
+
if dot_splitted_host.length >= options[:tld_length]
|
452
|
+
cookie_domain = dot_splitted_host.last(options[:tld_length]).join('.')
|
453
|
+
end
|
454
|
+
# Case where tld_length is not provided
|
455
|
+
else
|
456
|
+
# Regular TLDs
|
457
|
+
if !(/\.[^.]{2,3}\.[^.]{2}\z/.match?(request.host))
|
458
|
+
cookie_domain = dot_splitted_host.last(2).join(".")
|
459
|
+
# **.**, ***.** style TLDs like co.uk and com.au
|
460
|
+
else
|
461
|
+
cookie_domain = dot_splitted_host.last(3).join('.')
|
462
|
+
end
|
463
|
+
end
|
454
464
|
|
455
|
-
|
456
|
-
|
457
|
-
options[:domain] = if !request.host.match?(/^[\d.]+$/) && (request.host =~ domain_regexp)
|
458
|
-
".#{$&}"
|
465
|
+
options[:domain] = if cookie_domain.present?
|
466
|
+
".#{cookie_domain}"
|
459
467
|
end
|
460
468
|
elsif options[:domain].is_a? Array
|
461
469
|
# If host matches one of the supplied domains.
|
@@ -13,8 +13,22 @@ module ActionDispatch
|
|
13
13
|
#
|
14
14
|
# When a request comes to an unauthorized host, the +response_app+
|
15
15
|
# application will be executed and rendered. If no +response_app+ is given, a
|
16
|
-
# default one will run
|
16
|
+
# default one will run.
|
17
|
+
# The default response app logs blocked host info with level 'error' and
|
18
|
+
# responds with <tt>403 Forbidden</tt>. The body of the response contains debug info
|
19
|
+
# if +config.consider_all_requests_local+ is set to true, otherwise the body is empty.
|
17
20
|
class HostAuthorization
|
21
|
+
ALLOWED_HOSTS_IN_DEVELOPMENT = [".localhost", IPAddr.new("0.0.0.0/0"), IPAddr.new("::/0")]
|
22
|
+
PORT_REGEX = /(?::\d+)/ # :nodoc:
|
23
|
+
IPV4_HOSTNAME = /(?<host>\d+\.\d+\.\d+\.\d+)#{PORT_REGEX}?/ # :nodoc:
|
24
|
+
IPV6_HOSTNAME = /(?<host>[a-f0-9]*:[a-f0-9.:]+)/i # :nodoc:
|
25
|
+
IPV6_HOSTNAME_WITH_PORT = /\[#{IPV6_HOSTNAME}\]#{PORT_REGEX}/i # :nodoc:
|
26
|
+
VALID_IP_HOSTNAME = Regexp.union( # :nodoc:
|
27
|
+
/\A#{IPV4_HOSTNAME}\z/,
|
28
|
+
/\A#{IPV6_HOSTNAME}\z/,
|
29
|
+
/\A#{IPV6_HOSTNAME_WITH_PORT}\z/,
|
30
|
+
)
|
31
|
+
|
18
32
|
class Permissions # :nodoc:
|
19
33
|
def initialize(hosts)
|
20
34
|
@hosts = sanitize_hosts(hosts)
|
@@ -26,11 +40,17 @@ module ActionDispatch
|
|
26
40
|
|
27
41
|
def allows?(host)
|
28
42
|
@hosts.any? do |allowed|
|
29
|
-
allowed
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
43
|
+
if allowed.is_a?(IPAddr)
|
44
|
+
begin
|
45
|
+
allowed === extract_hostname(host)
|
46
|
+
rescue
|
47
|
+
# IPAddr#=== raises an error if you give it a hostname instead of
|
48
|
+
# IP. Treat similar errors as blocked access.
|
49
|
+
false
|
50
|
+
end
|
51
|
+
else
|
52
|
+
allowed === host
|
53
|
+
end
|
34
54
|
end
|
35
55
|
end
|
36
56
|
|
@@ -46,29 +66,59 @@ module ActionDispatch
|
|
46
66
|
end
|
47
67
|
|
48
68
|
def sanitize_regexp(host)
|
49
|
-
/\A#{host}
|
69
|
+
/\A#{host}#{PORT_REGEX}?\z/
|
50
70
|
end
|
51
71
|
|
52
72
|
def sanitize_string(host)
|
53
73
|
if host.start_with?(".")
|
54
|
-
/\A([a-z0-9-]+\.)?#{Regexp.escape(host[1..-1])}
|
74
|
+
/\A([a-z0-9-]+\.)?#{Regexp.escape(host[1..-1])}#{PORT_REGEX}?\z/i
|
55
75
|
else
|
56
|
-
/\A#{Regexp.escape host}
|
76
|
+
/\A#{Regexp.escape host}#{PORT_REGEX}?\z/i
|
57
77
|
end
|
58
78
|
end
|
79
|
+
|
80
|
+
def extract_hostname(host)
|
81
|
+
host.slice(VALID_IP_HOSTNAME, "host") || host
|
82
|
+
end
|
59
83
|
end
|
60
84
|
|
61
|
-
|
62
|
-
|
85
|
+
class DefaultResponseApp # :nodoc:
|
86
|
+
RESPONSE_STATUS = 403
|
87
|
+
|
88
|
+
def call(env)
|
89
|
+
request = Request.new(env)
|
90
|
+
format = request.xhr? ? "text/plain" : "text/html"
|
91
|
+
|
92
|
+
log_error(request)
|
93
|
+
response(format, response_body(request))
|
94
|
+
end
|
63
95
|
|
64
|
-
|
65
|
-
|
66
|
-
|
96
|
+
private
|
97
|
+
def response_body(request)
|
98
|
+
return "" unless request.get_header("action_dispatch.show_detailed_exceptions")
|
99
|
+
|
100
|
+
template = DebugView.new(host: request.host)
|
101
|
+
template.render(template: "rescues/blocked_host", layout: "rescues/layout")
|
102
|
+
end
|
103
|
+
|
104
|
+
def response(format, body)
|
105
|
+
[RESPONSE_STATUS,
|
106
|
+
{ "Content-Type" => "#{format}; charset=#{Response.default_charset}",
|
107
|
+
"Content-Length" => body.bytesize.to_s },
|
108
|
+
[body]]
|
109
|
+
end
|
67
110
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
111
|
+
def log_error(request)
|
112
|
+
logger = available_logger(request)
|
113
|
+
|
114
|
+
return unless logger
|
115
|
+
|
116
|
+
logger.error("[#{self.class.name}] Blocked host: #{request.host}")
|
117
|
+
end
|
118
|
+
|
119
|
+
def available_logger(request)
|
120
|
+
request.logger || ActionView::Base.logger
|
121
|
+
end
|
72
122
|
end
|
73
123
|
|
74
124
|
def initialize(app, hosts, deprecated_response_app = nil, exclude: nil, response_app: nil)
|
@@ -78,14 +128,14 @@ module ActionDispatch
|
|
78
128
|
|
79
129
|
unless deprecated_response_app.nil?
|
80
130
|
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
81
|
-
`action_dispatch.hosts_response_app` is deprecated and will be ignored in Rails
|
131
|
+
`action_dispatch.hosts_response_app` is deprecated and will be ignored in Rails 7.0.
|
82
132
|
Use the Host Authorization `response_app` setting instead.
|
83
133
|
MSG
|
84
134
|
|
85
135
|
response_app ||= deprecated_response_app
|
86
136
|
end
|
87
137
|
|
88
|
-
@response_app = response_app ||
|
138
|
+
@response_app = response_app || DefaultResponseApp.new
|
89
139
|
end
|
90
140
|
|
91
141
|
def call(env)
|
@@ -47,6 +47,7 @@ module ActionDispatch
|
|
47
47
|
request.set_header "action_dispatch.exception", wrapper.unwrapped_exception
|
48
48
|
request.set_header "action_dispatch.original_path", request.path_info
|
49
49
|
request.set_header "action_dispatch.original_request_method", request.raw_request_method
|
50
|
+
fallback_to_html_format_if_invalid_mime_type(request)
|
50
51
|
request.path_info = "/#{status}"
|
51
52
|
request.request_method = "GET"
|
52
53
|
response = @exceptions_app.call(request.env)
|
@@ -56,6 +57,15 @@ module ActionDispatch
|
|
56
57
|
FAILSAFE_RESPONSE
|
57
58
|
end
|
58
59
|
|
60
|
+
def fallback_to_html_format_if_invalid_mime_type(request)
|
61
|
+
# If the MIME type for the request is invalid then the
|
62
|
+
# @exceptions_app may not be able to handle it. To make it
|
63
|
+
# easier to handle, we switch to HTML.
|
64
|
+
request.formats
|
65
|
+
rescue ActionDispatch::Http::MimeNegotiation::InvalidType
|
66
|
+
request.set_header "HTTP_ACCEPT", "text/html"
|
67
|
+
end
|
68
|
+
|
59
69
|
def pass_response(status)
|
60
70
|
[status, { "Content-Type" => "text/html; charset=#{Response.default_charset}", "Content-Length" => "0" }, []]
|
61
71
|
end
|
@@ -2,6 +2,6 @@
|
|
2
2
|
<h1>Blocked host: <%= @host %></h1>
|
3
3
|
</header>
|
4
4
|
<div id="container">
|
5
|
-
<h2>To allow requests to <%= @host
|
5
|
+
<h2>To allow requests to <%= @host %> make sure it is a valid hostname (containing only numbers, letters, dashes and dots), then add the following to your environment configuration:</h2>
|
6
6
|
<pre>config.hosts << "<%= @host %>"</pre>
|
7
7
|
</div>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
Blocked host: <%= @host %>
|
2
2
|
|
3
|
-
To allow requests to <%= @host
|
3
|
+
To allow requests to <%= @host %> make sure it is a valid hostname (containing only numbers, letters, dashes and dots), then add the following to your environment configuration:
|
4
4
|
|
5
5
|
config.hosts << "<%= @host %>"
|
@@ -597,14 +597,14 @@ module ActionDispatch
|
|
597
597
|
if route.segment_keys.include?(:controller)
|
598
598
|
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
599
599
|
Using a dynamic :controller segment in a route is deprecated and
|
600
|
-
will be removed in Rails
|
600
|
+
will be removed in Rails 7.0.
|
601
601
|
MSG
|
602
602
|
end
|
603
603
|
|
604
604
|
if route.segment_keys.include?(:action)
|
605
605
|
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
606
606
|
Using a dynamic :action segment in a route is deprecated and
|
607
|
-
will be removed in Rails
|
607
|
+
will be removed in Rails 7.0.
|
608
608
|
MSG
|
609
609
|
end
|
610
610
|
|
@@ -115,6 +115,8 @@ module ActionDispatch
|
|
115
115
|
include SystemTesting::TestHelpers::SetupAndTeardown
|
116
116
|
include SystemTesting::TestHelpers::ScreenshotHelper
|
117
117
|
|
118
|
+
DEFAULT_HOST = "http://127.0.0.1"
|
119
|
+
|
118
120
|
def initialize(*) # :nodoc:
|
119
121
|
super
|
120
122
|
self.class.driven_by(:selenium) unless self.class.driver?
|
@@ -166,7 +168,11 @@ module ActionDispatch
|
|
166
168
|
include ActionDispatch.test_app.routes.mounted_helpers
|
167
169
|
|
168
170
|
def url_options
|
169
|
-
default_url_options.reverse_merge(host:
|
171
|
+
default_url_options.reverse_merge(host: app_host)
|
172
|
+
end
|
173
|
+
|
174
|
+
def app_host
|
175
|
+
Capybara.app_host || Capybara.current_session.server_url || DEFAULT_HOST
|
170
176
|
end
|
171
177
|
end.new
|
172
178
|
end
|
@@ -25,18 +25,21 @@ module ActionDispatch
|
|
25
25
|
if !self.class.file_fixture_path
|
26
26
|
ActiveSupport::Deprecation.warn(<<~EOM)
|
27
27
|
Passing a path to `fixture_file_upload` relative to `fixture_path` is deprecated.
|
28
|
-
In Rails
|
28
|
+
In Rails 7.0, the path needs to be relative to `file_fixture_path` which you
|
29
29
|
haven't set yet. Set `file_fixture_path` to discard this warning.
|
30
30
|
EOM
|
31
31
|
elsif path.exist?
|
32
32
|
non_deprecated_path = Pathname(File.absolute_path(path)).relative_path_from(Pathname(File.absolute_path(self.class.file_fixture_path)))
|
33
|
-
ActiveSupport::Deprecation.warn(<<~EOM)
|
34
|
-
Passing a path to `fixture_file_upload` relative to `fixture_path` is deprecated.
|
35
|
-
In Rails 6.2, the path needs to be relative to `file_fixture_path`.
|
36
33
|
|
37
|
-
|
38
|
-
|
39
|
-
|
34
|
+
if Pathname(original_path) != non_deprecated_path
|
35
|
+
ActiveSupport::Deprecation.warn(<<~EOM)
|
36
|
+
Passing a path to `fixture_file_upload` relative to `fixture_path` is deprecated.
|
37
|
+
In Rails 7.0, the path needs to be relative to `file_fixture_path`.
|
38
|
+
|
39
|
+
Please modify the call from
|
40
|
+
`fixture_file_upload("#{original_path}")` to `fixture_file_upload("#{non_deprecated_path}")`.
|
41
|
+
EOM
|
42
|
+
end
|
40
43
|
else
|
41
44
|
path = file_fixture(original_path)
|
42
45
|
end
|
data/lib/action_dispatch.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c) 2004-
|
4
|
+
# Copyright (c) 2004-2022 David Heinemeier Hansson
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
7
7
|
# a copy of this software and associated documentation files (the
|
data/lib/action_pack.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#--
|
4
|
-
# Copyright (c) 2004-
|
4
|
+
# Copyright (c) 2004-2022 David Heinemeier Hansson
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining
|
7
7
|
# a copy of this software and associated documentation files (the
|
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: 6.1.
|
4
|
+
version: 6.1.7.7
|
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:
|
11
|
+
date: 2024-02-21 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: 6.1.
|
19
|
+
version: 6.1.7.7
|
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: 6.1.
|
26
|
+
version: 6.1.7.7
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rack
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,28 +98,28 @@ dependencies:
|
|
98
98
|
requirements:
|
99
99
|
- - '='
|
100
100
|
- !ruby/object:Gem::Version
|
101
|
-
version: 6.1.
|
101
|
+
version: 6.1.7.7
|
102
102
|
type: :runtime
|
103
103
|
prerelease: false
|
104
104
|
version_requirements: !ruby/object:Gem::Requirement
|
105
105
|
requirements:
|
106
106
|
- - '='
|
107
107
|
- !ruby/object:Gem::Version
|
108
|
-
version: 6.1.
|
108
|
+
version: 6.1.7.7
|
109
109
|
- !ruby/object:Gem::Dependency
|
110
110
|
name: activemodel
|
111
111
|
requirement: !ruby/object:Gem::Requirement
|
112
112
|
requirements:
|
113
113
|
- - '='
|
114
114
|
- !ruby/object:Gem::Version
|
115
|
-
version: 6.1.
|
115
|
+
version: 6.1.7.7
|
116
116
|
type: :development
|
117
117
|
prerelease: false
|
118
118
|
version_requirements: !ruby/object:Gem::Requirement
|
119
119
|
requirements:
|
120
120
|
- - '='
|
121
121
|
- !ruby/object:Gem::Version
|
122
|
-
version: 6.1.
|
122
|
+
version: 6.1.7.7
|
123
123
|
description: Web apps on Rails. Simple, battle-tested conventions for building and
|
124
124
|
testing MVC web applications. Works with any Rack-compatible server.
|
125
125
|
email: david@loudthinking.com
|
@@ -309,10 +309,11 @@ licenses:
|
|
309
309
|
- MIT
|
310
310
|
metadata:
|
311
311
|
bug_tracker_uri: https://github.com/rails/rails/issues
|
312
|
-
changelog_uri: https://github.com/rails/rails/blob/v6.1.
|
313
|
-
documentation_uri: https://api.rubyonrails.org/v6.1.
|
312
|
+
changelog_uri: https://github.com/rails/rails/blob/v6.1.7.7/actionpack/CHANGELOG.md
|
313
|
+
documentation_uri: https://api.rubyonrails.org/v6.1.7.7/
|
314
314
|
mailing_list_uri: https://discuss.rubyonrails.org/c/rubyonrails-talk
|
315
|
-
source_code_uri: https://github.com/rails/rails/tree/v6.1.
|
315
|
+
source_code_uri: https://github.com/rails/rails/tree/v6.1.7.7/actionpack
|
316
|
+
rubygems_mfa_required: 'true'
|
316
317
|
post_install_message:
|
317
318
|
rdoc_options: []
|
318
319
|
require_paths:
|
@@ -329,7 +330,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
329
330
|
version: '0'
|
330
331
|
requirements:
|
331
332
|
- none
|
332
|
-
rubygems_version: 3.2.
|
333
|
+
rubygems_version: 3.2.22
|
333
334
|
signing_key:
|
334
335
|
specification_version: 4
|
335
336
|
summary: Web-flow and rendering framework putting the VC in MVC (part of Rails).
|