actionpack 5.1.7 → 5.2.4.3
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 +282 -362
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -5
- data/lib/abstract_controller.rb +3 -0
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +10 -2
- data/lib/abstract_controller/caching.rb +3 -2
- data/lib/abstract_controller/caching/fragments.rb +30 -7
- data/lib/abstract_controller/callbacks.rb +25 -3
- data/lib/abstract_controller/collector.rb +2 -0
- data/lib/abstract_controller/error.rb +2 -0
- data/lib/abstract_controller/helpers.rb +4 -5
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
- data/lib/abstract_controller/rendering.rb +9 -16
- data/lib/abstract_controller/translation.rb +2 -0
- data/lib/abstract_controller/url_for.rb +2 -0
- data/lib/action_controller.rb +3 -0
- data/lib/action_controller/api.rb +2 -0
- data/lib/action_controller/api/api_rendering.rb +2 -0
- data/lib/action_controller/base.rb +3 -0
- data/lib/action_controller/caching.rb +2 -0
- data/lib/action_controller/form_builder.rb +2 -0
- data/lib/action_controller/log_subscriber.rb +5 -3
- data/lib/action_controller/metal.rb +13 -14
- data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
- data/lib/action_controller/metal/conditional_get.rb +4 -3
- data/lib/action_controller/metal/content_security_policy.rb +52 -0
- data/lib/action_controller/metal/cookies.rb +2 -0
- data/lib/action_controller/metal/data_streaming.rb +7 -5
- data/lib/action_controller/metal/etag_with_flash.rb +2 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +3 -2
- data/lib/action_controller/metal/exceptions.rb +2 -3
- data/lib/action_controller/metal/flash.rb +3 -2
- data/lib/action_controller/metal/force_ssl.rb +4 -2
- data/lib/action_controller/metal/head.rb +2 -0
- data/lib/action_controller/metal/helpers.rb +4 -3
- data/lib/action_controller/metal/http_authentication.rb +8 -9
- data/lib/action_controller/metal/implicit_render.rb +2 -0
- data/lib/action_controller/metal/instrumentation.rb +4 -6
- data/lib/action_controller/metal/live.rb +3 -1
- data/lib/action_controller/metal/mime_responds.rb +3 -1
- data/lib/action_controller/metal/parameter_encoding.rb +2 -0
- data/lib/action_controller/metal/params_wrapper.rb +14 -10
- data/lib/action_controller/metal/redirecting.rb +22 -11
- data/lib/action_controller/metal/renderers.rb +4 -3
- data/lib/action_controller/metal/rendering.rb +2 -2
- data/lib/action_controller/metal/request_forgery_protection.rb +62 -10
- data/lib/action_controller/metal/rescue.rb +5 -3
- data/lib/action_controller/metal/streaming.rb +3 -1
- data/lib/action_controller/metal/strong_parameters.rb +36 -25
- data/lib/action_controller/metal/testing.rb +2 -6
- data/lib/action_controller/metal/url_for.rb +2 -0
- data/lib/action_controller/railtie.rb +16 -4
- data/lib/action_controller/railties/helpers.rb +2 -0
- data/lib/action_controller/renderer.rb +2 -0
- data/lib/action_controller/template_assertions.rb +2 -0
- data/lib/action_controller/test_case.rb +16 -10
- data/lib/action_dispatch.rb +9 -5
- data/lib/action_dispatch/http/cache.rb +22 -14
- data/lib/action_dispatch/http/content_security_policy.rb +272 -0
- data/lib/action_dispatch/http/filter_parameters.rb +4 -2
- data/lib/action_dispatch/http/filter_redirect.rb +2 -0
- data/lib/action_dispatch/http/headers.rb +2 -0
- data/lib/action_dispatch/http/mime_negotiation.rb +4 -8
- data/lib/action_dispatch/http/mime_type.rb +15 -13
- data/lib/action_dispatch/http/mime_types.rb +17 -2
- data/lib/action_dispatch/http/parameter_filter.rb +2 -0
- data/lib/action_dispatch/http/parameters.rb +6 -9
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +36 -16
- data/lib/action_dispatch/http/response.rb +11 -9
- data/lib/action_dispatch/http/upload.rb +2 -0
- data/lib/action_dispatch/http/url.rb +5 -6
- data/lib/action_dispatch/journey.rb +2 -0
- data/lib/action_dispatch/journey/formatter.rb +4 -2
- data/lib/action_dispatch/journey/gtg/builder.rb +2 -0
- data/lib/action_dispatch/journey/gtg/simulator.rb +2 -8
- data/lib/action_dispatch/journey/gtg/transition_table.rb +3 -2
- data/lib/action_dispatch/journey/nfa/builder.rb +2 -0
- data/lib/action_dispatch/journey/nfa/dot.rb +12 -10
- data/lib/action_dispatch/journey/nfa/simulator.rb +2 -0
- data/lib/action_dispatch/journey/nfa/transition_table.rb +2 -0
- data/lib/action_dispatch/journey/nodes/node.rb +2 -0
- data/lib/action_dispatch/journey/parser_extras.rb +2 -0
- data/lib/action_dispatch/journey/path/pattern.rb +4 -1
- data/lib/action_dispatch/journey/route.rb +15 -6
- data/lib/action_dispatch/journey/router.rb +3 -1
- data/lib/action_dispatch/journey/router/utils.rb +14 -7
- data/lib/action_dispatch/journey/routes.rb +3 -1
- data/lib/action_dispatch/journey/scanner.rb +1 -0
- data/lib/action_dispatch/journey/visitors.rb +5 -3
- data/lib/action_dispatch/middleware/callbacks.rb +2 -0
- data/lib/action_dispatch/middleware/cookies.rb +148 -91
- data/lib/action_dispatch/middleware/debug_exceptions.rb +4 -2
- data/lib/action_dispatch/middleware/debug_locks.rb +9 -7
- data/lib/action_dispatch/middleware/exception_wrapper.rb +5 -6
- data/lib/action_dispatch/middleware/executor.rb +2 -0
- data/lib/action_dispatch/middleware/flash.rb +4 -2
- data/lib/action_dispatch/middleware/public_exceptions.rb +6 -4
- data/lib/action_dispatch/middleware/reloader.rb +2 -0
- data/lib/action_dispatch/middleware/remote_ip.rb +7 -5
- data/lib/action_dispatch/middleware/request_id.rb +3 -1
- data/lib/action_dispatch/middleware/session/abstract_store.rb +17 -1
- data/lib/action_dispatch/middleware/session/cache_store.rb +13 -6
- data/lib/action_dispatch/middleware/session/cookie_store.rb +31 -32
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +2 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +3 -1
- data/lib/action_dispatch/middleware/ssl.rb +44 -38
- data/lib/action_dispatch/middleware/stack.rb +4 -2
- data/lib/action_dispatch/middleware/static.rb +14 -12
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +21 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +13 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +1 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +6 -2
- data/lib/action_dispatch/railtie.rb +11 -1
- data/lib/action_dispatch/request/session.rb +16 -5
- data/lib/action_dispatch/request/utils.rb +6 -4
- data/lib/action_dispatch/routing.rb +3 -1
- data/lib/action_dispatch/routing/endpoint.rb +9 -2
- data/lib/action_dispatch/routing/inspector.rb +6 -4
- data/lib/action_dispatch/routing/mapper.rb +64 -52
- data/lib/action_dispatch/routing/polymorphic_routes.rb +2 -0
- data/lib/action_dispatch/routing/redirection.rb +7 -5
- data/lib/action_dispatch/routing/route_set.rb +29 -24
- data/lib/action_dispatch/routing/routes_proxy.rb +5 -2
- data/lib/action_dispatch/routing/url_for.rb +25 -5
- data/lib/action_dispatch/system_test_case.rb +22 -6
- data/lib/action_dispatch/system_testing/browser.rb +49 -0
- data/lib/action_dispatch/system_testing/driver.rb +9 -3
- data/lib/action_dispatch/system_testing/server.rb +2 -16
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +12 -14
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +8 -2
- data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +26 -0
- data/lib/action_dispatch/testing/assertion_response.rb +2 -0
- data/lib/action_dispatch/testing/assertions.rb +2 -0
- data/lib/action_dispatch/testing/assertions/response.rb +4 -2
- data/lib/action_dispatch/testing/assertions/routing.rb +5 -5
- data/lib/action_dispatch/testing/integration.rb +24 -21
- data/lib/action_dispatch/testing/request_encoder.rb +3 -1
- data/lib/action_dispatch/testing/test_process.rb +2 -0
- data/lib/action_dispatch/testing/test_request.rb +3 -1
- data/lib/action_dispatch/testing/test_response.rb +23 -3
- data/lib/action_pack.rb +3 -1
- data/lib/action_pack/gem_version.rb +5 -3
- data/lib/action_pack/version.rb +2 -0
- metadata +23 -11
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionController
|
2
4
|
module Redirecting
|
3
5
|
extend ActiveSupport::Concern
|
@@ -29,7 +31,7 @@ module ActionController
|
|
29
31
|
# redirect_to post_url(@post), status: 301
|
30
32
|
# redirect_to action: 'atom', status: 302
|
31
33
|
#
|
32
|
-
# The status code can either be a standard {HTTP Status code}[
|
34
|
+
# The status code can either be a standard {HTTP Status code}[https://www.iana.org/assignments/http-status-codes] as an
|
33
35
|
# integer, or a symbol representing the downcased, underscored and symbolized description.
|
34
36
|
# Note that the status code must be a 3xx HTTP code, or redirection will not occur.
|
35
37
|
#
|
@@ -66,7 +68,7 @@ module ActionController
|
|
66
68
|
# if possible, otherwise redirects to the provided default fallback
|
67
69
|
# location.
|
68
70
|
#
|
69
|
-
# The referrer information is pulled from the HTTP
|
71
|
+
# The referrer information is pulled from the HTTP +Referer+ (sic) header on
|
70
72
|
# the request. This is an optional header and its presence on the request is
|
71
73
|
# subject to browser security settings and user preferences. If the request
|
72
74
|
# is missing this header, the <tt>fallback_location</tt> will be used.
|
@@ -77,15 +79,18 @@ module ActionController
|
|
77
79
|
# redirect_back fallback_location: "/images/screenshot.jpg"
|
78
80
|
# redirect_back fallback_location: posts_url
|
79
81
|
# redirect_back fallback_location: proc { edit_post_url(@post) }
|
82
|
+
# redirect_back fallback_location: '/', allow_other_host: false
|
83
|
+
#
|
84
|
+
# ==== Options
|
85
|
+
# * <tt>:fallback_location</tt> - The default fallback location that will be used on missing +Referer+ header.
|
86
|
+
# * <tt>:allow_other_host</tt> - Allow or disallow redirection to the host that is different to the current host, defaults to true.
|
80
87
|
#
|
81
|
-
# All options that can be passed to <tt>redirect_to</tt> are accepted as
|
88
|
+
# All other options that can be passed to <tt>redirect_to</tt> are accepted as
|
82
89
|
# options and the behavior is identical.
|
83
|
-
def redirect_back(fallback_location:, **args)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
redirect_to fallback_location, **args
|
88
|
-
end
|
90
|
+
def redirect_back(fallback_location:, allow_other_host: true, **args)
|
91
|
+
referer = request.headers["Referer"]
|
92
|
+
redirect_to_referer = referer && (allow_other_host || _url_host_allowed?(referer))
|
93
|
+
redirect_to redirect_to_referer ? referer : fallback_location, **args
|
89
94
|
end
|
90
95
|
|
91
96
|
def _compute_redirect_to_location(request, options) #:nodoc:
|
@@ -93,14 +98,14 @@ module ActionController
|
|
93
98
|
# The scheme name consist of a letter followed by any combination of
|
94
99
|
# letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
|
95
100
|
# characters; and is terminated by a colon (":").
|
96
|
-
# See
|
101
|
+
# See https://tools.ietf.org/html/rfc3986#section-3.1
|
97
102
|
# The protocol relative scheme starts with a double slash "//".
|
98
103
|
when /\A([a-z][a-z\d\-+\.]*:|\/\/).*/i
|
99
104
|
options
|
100
105
|
when String
|
101
106
|
request.protocol + request.host_with_port + options
|
102
107
|
when Proc
|
103
|
-
_compute_redirect_to_location request, options
|
108
|
+
_compute_redirect_to_location request, instance_eval(&options)
|
104
109
|
else
|
105
110
|
url_for(options)
|
106
111
|
end.delete("\0\r\n")
|
@@ -118,5 +123,11 @@ module ActionController
|
|
118
123
|
302
|
119
124
|
end
|
120
125
|
end
|
126
|
+
|
127
|
+
def _url_host_allowed?(url)
|
128
|
+
URI(url.to_s).host == request.host
|
129
|
+
rescue ArgumentError, URI::Error
|
130
|
+
false
|
131
|
+
end
|
121
132
|
end
|
122
133
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "set"
|
2
4
|
|
3
5
|
module ActionController
|
@@ -26,8 +28,7 @@ module ActionController
|
|
26
28
|
RENDERERS = Set.new
|
27
29
|
|
28
30
|
included do
|
29
|
-
class_attribute :_renderers
|
30
|
-
self._renderers = Set.new.freeze
|
31
|
+
class_attribute :_renderers, default: Set.new.freeze
|
31
32
|
end
|
32
33
|
|
33
34
|
# Used in <tt>ActionController::Base</tt>
|
@@ -84,7 +85,7 @@ module ActionController
|
|
84
85
|
def self.remove(key)
|
85
86
|
RENDERERS.delete(key.to_sym)
|
86
87
|
method_name = _render_with_renderer_method_name(key)
|
87
|
-
|
88
|
+
remove_possible_method(method_name)
|
88
89
|
end
|
89
90
|
|
90
91
|
def self._render_with_renderer_method_name(key)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module ActionController
|
4
4
|
module Rendering
|
@@ -40,7 +40,7 @@ module ActionController
|
|
40
40
|
def render_to_string(*)
|
41
41
|
result = super
|
42
42
|
if result.respond_to?(:each)
|
43
|
-
string = ""
|
43
|
+
string = "".dup
|
44
44
|
result.each { |r| string << r }
|
45
45
|
string
|
46
46
|
else
|
@@ -1,6 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "rack/session/abstract/id"
|
2
4
|
require "action_controller/metal/exceptions"
|
3
5
|
require "active_support/security_utils"
|
6
|
+
require "active_support/core_ext/string/strip"
|
4
7
|
|
5
8
|
module ActionController #:nodoc:
|
6
9
|
class InvalidAuthenticityToken < ActionControllerError #:nodoc:
|
@@ -20,7 +23,7 @@ module ActionController #:nodoc:
|
|
20
23
|
# Since HTML and JavaScript requests are typically made from the browser, we
|
21
24
|
# need to ensure to verify request authenticity for the web browser. We can
|
22
25
|
# use session-oriented authentication for these types of requests, by using
|
23
|
-
# the
|
26
|
+
# the <tt>protect_from_forgery</tt> method in our controllers.
|
24
27
|
#
|
25
28
|
# GET requests are not protected since they don't have side effects like writing
|
26
29
|
# to the database and don't leak sensitive information. JavaScript requests are
|
@@ -85,6 +88,10 @@ module ActionController #:nodoc:
|
|
85
88
|
config_accessor :per_form_csrf_tokens
|
86
89
|
self.per_form_csrf_tokens = false
|
87
90
|
|
91
|
+
# Controls whether forgery protection is enabled by default.
|
92
|
+
config_accessor :default_protect_from_forgery
|
93
|
+
self.default_protect_from_forgery = false
|
94
|
+
|
88
95
|
helper_method :form_authenticity_token
|
89
96
|
helper_method :protect_against_forgery?
|
90
97
|
end
|
@@ -128,6 +135,15 @@ module ActionController #:nodoc:
|
|
128
135
|
append_after_action :verify_same_origin_request
|
129
136
|
end
|
130
137
|
|
138
|
+
# Turn off request forgery protection. This is a wrapper for:
|
139
|
+
#
|
140
|
+
# skip_before_action :verify_authenticity_token
|
141
|
+
#
|
142
|
+
# See +skip_before_action+ for allowed options.
|
143
|
+
def skip_forgery_protection(options = {})
|
144
|
+
skip_before_action :verify_authenticity_token, options
|
145
|
+
end
|
146
|
+
|
131
147
|
private
|
132
148
|
|
133
149
|
def protection_method_class(name)
|
@@ -201,7 +217,7 @@ module ActionController #:nodoc:
|
|
201
217
|
# The actual before_action that is used to verify the CSRF token.
|
202
218
|
# Don't override this directly. Provide your own forgery protection
|
203
219
|
# strategy instead. If you override, you'll disable same-origin
|
204
|
-
#
|
220
|
+
# <tt><script></tt> verification.
|
205
221
|
#
|
206
222
|
# Lean on the protect_from_forgery declaration to mark which actions are
|
207
223
|
# due for same-origin request verification. If protect_from_forgery is
|
@@ -233,8 +249,9 @@ module ActionController #:nodoc:
|
|
233
249
|
"If you know what you're doing, go ahead and disable forgery " \
|
234
250
|
"protection on this action to permit cross-origin JavaScript embedding."
|
235
251
|
private_constant :CROSS_ORIGIN_JAVASCRIPT_WARNING
|
252
|
+
# :startdoc:
|
236
253
|
|
237
|
-
# If
|
254
|
+
# If +verify_authenticity_token+ was run (indicating that we have
|
238
255
|
# forgery protection enabled for this request) then also verify that
|
239
256
|
# we aren't serving an unauthorized cross-origin response.
|
240
257
|
def verify_same_origin_request # :doc:
|
@@ -251,7 +268,7 @@ module ActionController #:nodoc:
|
|
251
268
|
@marked_for_same_origin_verification = request.get?
|
252
269
|
end
|
253
270
|
|
254
|
-
# If the
|
271
|
+
# If the +verify_authenticity_token+ before_action ran, verify that
|
255
272
|
# JavaScript responses are only served to same-origin GET requests.
|
256
273
|
def marked_for_same_origin_verification? # :doc:
|
257
274
|
@marked_for_same_origin_verification ||= false
|
@@ -301,13 +318,15 @@ module ActionController #:nodoc:
|
|
301
318
|
action_path = normalize_action_path(action)
|
302
319
|
per_form_csrf_token(session, action_path, method)
|
303
320
|
else
|
304
|
-
|
321
|
+
global_csrf_token(session)
|
305
322
|
end
|
306
323
|
|
307
324
|
one_time_pad = SecureRandom.random_bytes(AUTHENTICITY_TOKEN_LENGTH)
|
308
325
|
encrypted_csrf_token = xor_byte_strings(one_time_pad, raw_token)
|
309
326
|
masked_token = one_time_pad + encrypted_csrf_token
|
310
|
-
Base64.
|
327
|
+
Base64.urlsafe_encode64(masked_token, padding: false)
|
328
|
+
|
329
|
+
mask_token(raw_token)
|
311
330
|
end
|
312
331
|
|
313
332
|
# Checks the client's masked token to see if it matches the
|
@@ -337,7 +356,8 @@ module ActionController #:nodoc:
|
|
337
356
|
elsif masked_token.length == AUTHENTICITY_TOKEN_LENGTH * 2
|
338
357
|
csrf_token = unmask_token(masked_token)
|
339
358
|
|
340
|
-
|
359
|
+
compare_with_global_token(csrf_token, session) ||
|
360
|
+
compare_with_real_token(csrf_token, session) ||
|
341
361
|
valid_per_form_csrf_token?(csrf_token, session)
|
342
362
|
else
|
343
363
|
false # Token is malformed.
|
@@ -352,8 +372,19 @@ module ActionController #:nodoc:
|
|
352
372
|
xor_byte_strings(one_time_pad, encrypted_csrf_token)
|
353
373
|
end
|
354
374
|
|
375
|
+
def mask_token(raw_token) # :doc:
|
376
|
+
one_time_pad = SecureRandom.random_bytes(AUTHENTICITY_TOKEN_LENGTH)
|
377
|
+
encrypted_csrf_token = xor_byte_strings(one_time_pad, raw_token)
|
378
|
+
masked_token = one_time_pad + encrypted_csrf_token
|
379
|
+
Base64.strict_encode64(masked_token)
|
380
|
+
end
|
381
|
+
|
355
382
|
def compare_with_real_token(token, session) # :doc:
|
356
|
-
ActiveSupport::SecurityUtils.
|
383
|
+
ActiveSupport::SecurityUtils.fixed_length_secure_compare(token, real_csrf_token(session))
|
384
|
+
end
|
385
|
+
|
386
|
+
def compare_with_global_token(token, session) # :doc:
|
387
|
+
ActiveSupport::SecurityUtils.fixed_length_secure_compare(token, global_csrf_token(session))
|
357
388
|
end
|
358
389
|
|
359
390
|
def valid_per_form_csrf_token?(token, session) # :doc:
|
@@ -364,7 +395,7 @@ module ActionController #:nodoc:
|
|
364
395
|
request.request_method
|
365
396
|
)
|
366
397
|
|
367
|
-
ActiveSupport::SecurityUtils.
|
398
|
+
ActiveSupport::SecurityUtils.fixed_length_secure_compare(token, correct_token)
|
368
399
|
else
|
369
400
|
false
|
370
401
|
end
|
@@ -376,10 +407,21 @@ module ActionController #:nodoc:
|
|
376
407
|
end
|
377
408
|
|
378
409
|
def per_form_csrf_token(session, action_path, method) # :doc:
|
410
|
+
csrf_token_hmac(session, [action_path, method.downcase].join("#"))
|
411
|
+
end
|
412
|
+
|
413
|
+
GLOBAL_CSRF_TOKEN_IDENTIFIER = "!real_csrf_token"
|
414
|
+
private_constant :GLOBAL_CSRF_TOKEN_IDENTIFIER
|
415
|
+
|
416
|
+
def global_csrf_token(session) # :doc:
|
417
|
+
csrf_token_hmac(session, GLOBAL_CSRF_TOKEN_IDENTIFIER)
|
418
|
+
end
|
419
|
+
|
420
|
+
def csrf_token_hmac(session, identifier) # :doc:
|
379
421
|
OpenSSL::HMAC.digest(
|
380
422
|
OpenSSL::Digest::SHA256.new,
|
381
423
|
real_csrf_token(session),
|
382
|
-
|
424
|
+
identifier
|
383
425
|
)
|
384
426
|
end
|
385
427
|
|
@@ -399,11 +441,21 @@ module ActionController #:nodoc:
|
|
399
441
|
allow_forgery_protection
|
400
442
|
end
|
401
443
|
|
444
|
+
NULL_ORIGIN_MESSAGE = <<-MSG.strip_heredoc
|
445
|
+
The browser returned a 'null' origin for a request with origin-based forgery protection turned on. This usually
|
446
|
+
means you have the 'no-referrer' Referrer-Policy header enabled, or that the request came from a site that
|
447
|
+
refused to give its origin. This makes it impossible for Rails to verify the source of the requests. Likely the
|
448
|
+
best solution is to change your referrer policy to something less strict like same-origin or strict-same-origin.
|
449
|
+
If you cannot change the referrer policy, you can disable origin checking with the
|
450
|
+
Rails.application.config.action_controller.forgery_protection_origin_check setting.
|
451
|
+
MSG
|
452
|
+
|
402
453
|
# Checks if the request originated from the same origin by looking at the
|
403
454
|
# Origin header.
|
404
455
|
def valid_request_origin? # :doc:
|
405
456
|
if forgery_protection_origin_check
|
406
457
|
# We accept blank origin headers because some user agents don't send it.
|
458
|
+
raise InvalidAuthenticityToken, NULL_ORIGIN_MESSAGE if request.origin == "null"
|
407
459
|
request.origin.nil? || request.origin == request.base_url
|
408
460
|
else
|
409
461
|
true
|
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActionController #:nodoc:
|
2
|
-
# This module is responsible for providing
|
4
|
+
# This module is responsible for providing +rescue_from+ helpers
|
3
5
|
# to controllers and configuring when detailed exceptions must be
|
4
6
|
# shown.
|
5
7
|
module Rescue
|
@@ -8,8 +10,8 @@ module ActionController #:nodoc:
|
|
8
10
|
|
9
11
|
# Override this method if you want to customize when detailed
|
10
12
|
# exceptions must be shown. This method is only called when
|
11
|
-
# consider_all_requests_local is false
|
12
|
-
# false
|
13
|
+
# +consider_all_requests_local+ is +false+. By default, it returns
|
14
|
+
# +false+, but someone may set it to <tt>request.local?</tt> so local
|
13
15
|
# requests in production still show the detailed exception pages.
|
14
16
|
def show_detailed_exceptions?
|
15
17
|
false
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "rack/chunked"
|
2
4
|
|
3
5
|
module ActionController #:nodoc:
|
@@ -181,7 +183,7 @@ module ActionController #:nodoc:
|
|
181
183
|
# unicorn_rails --config-file unicorn.config.rb
|
182
184
|
#
|
183
185
|
# You may also want to configure other parameters like <tt>:tcp_nodelay</tt>.
|
184
|
-
# Please check its documentation for more information:
|
186
|
+
# Please check its documentation for more information: https://bogomips.org/unicorn/Unicorn/Configurator.html#method-i-listen
|
185
187
|
#
|
186
188
|
# If you are using Unicorn with NGINX, you may need to tweak NGINX.
|
187
189
|
# Streaming should work out of the box on Rainbows.
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/hash/indifferent_access"
|
2
4
|
require "active_support/core_ext/hash/transform_values"
|
3
5
|
require "active_support/core_ext/array/wrap"
|
@@ -119,8 +121,7 @@ module ActionController
|
|
119
121
|
# params[:key] # => "value"
|
120
122
|
# params["key"] # => "value"
|
121
123
|
class Parameters
|
122
|
-
cattr_accessor :permit_all_parameters, instance_accessor: false
|
123
|
-
self.permit_all_parameters = false
|
124
|
+
cattr_accessor :permit_all_parameters, instance_accessor: false, default: false
|
124
125
|
|
125
126
|
cattr_accessor :action_on_unpermitted_parameters, instance_accessor: false
|
126
127
|
|
@@ -185,6 +186,7 @@ module ActionController
|
|
185
186
|
#
|
186
187
|
# :call-seq:
|
187
188
|
# to_s()
|
189
|
+
#
|
188
190
|
# Returns the content of the parameters as a string.
|
189
191
|
|
190
192
|
##
|
@@ -212,8 +214,7 @@ module ActionController
|
|
212
214
|
# config. For instance:
|
213
215
|
#
|
214
216
|
# config.always_permitted_parameters = %w( controller action format )
|
215
|
-
cattr_accessor :always_permitted_parameters
|
216
|
-
self.always_permitted_parameters = %w( controller action )
|
217
|
+
cattr_accessor :always_permitted_parameters, default: %w( controller action )
|
217
218
|
|
218
219
|
# Returns a new instance of <tt>ActionController::Parameters</tt>.
|
219
220
|
# Also, sets the +permitted+ attribute to the default value of
|
@@ -254,7 +255,7 @@ module ActionController
|
|
254
255
|
# oddity: "Heavy stone crab"
|
255
256
|
# })
|
256
257
|
# params.to_h
|
257
|
-
# # => ActionController::UnfilteredParameters: unable to convert
|
258
|
+
# # => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash
|
258
259
|
#
|
259
260
|
# safe_params = params.permit(:name)
|
260
261
|
# safe_params.to_h # => {"name"=>"Senjougahara Hitagi"}
|
@@ -274,7 +275,7 @@ module ActionController
|
|
274
275
|
# oddity: "Heavy stone crab"
|
275
276
|
# })
|
276
277
|
# params.to_hash
|
277
|
-
# # => ActionController::UnfilteredParameters: unable to convert
|
278
|
+
# # => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash
|
278
279
|
#
|
279
280
|
# safe_params = params.permit(:name)
|
280
281
|
# safe_params.to_hash # => {"name"=>"Senjougahara Hitagi"}
|
@@ -290,6 +291,10 @@ module ActionController
|
|
290
291
|
# nationality: "Danish"
|
291
292
|
# })
|
292
293
|
# params.to_query
|
294
|
+
# # => ActionController::UnfilteredParameters: unable to convert unpermitted parameters to hash
|
295
|
+
#
|
296
|
+
# safe_params = params.permit(:name, :nationality)
|
297
|
+
# safe_params.to_query
|
293
298
|
# # => "name=David&nationality=Danish"
|
294
299
|
#
|
295
300
|
# An optional namespace can be passed to enclose key names:
|
@@ -298,7 +303,8 @@ module ActionController
|
|
298
303
|
# name: "David",
|
299
304
|
# nationality: "Danish"
|
300
305
|
# })
|
301
|
-
# params.
|
306
|
+
# safe_params = params.permit(:name, :nationality)
|
307
|
+
# safe_params.to_query("user")
|
302
308
|
# # => "user%5Bname%5D=David&user%5Bnationality%5D=Danish"
|
303
309
|
#
|
304
310
|
# The string pairs "key=value" that conform the query string
|
@@ -329,8 +335,10 @@ module ActionController
|
|
329
335
|
# the same way as <tt>Hash#each_pair</tt>.
|
330
336
|
def each_pair(&block)
|
331
337
|
@parameters.each_pair do |key, value|
|
332
|
-
yield key, convert_hashes_to_parameters(key, value)
|
338
|
+
yield [key, convert_hashes_to_parameters(key, value)]
|
333
339
|
end
|
340
|
+
|
341
|
+
self
|
334
342
|
end
|
335
343
|
alias_method :each, :each_pair
|
336
344
|
|
@@ -369,7 +377,7 @@ module ActionController
|
|
369
377
|
# Person.new(params) # => #<Person id: nil, name: "Francesco">
|
370
378
|
def permit!
|
371
379
|
each_pair do |key, value|
|
372
|
-
Array.wrap(value).each do |v|
|
380
|
+
Array.wrap(value).flatten.each do |v|
|
373
381
|
v.permit! if v.respond_to? :permit!
|
374
382
|
end
|
375
383
|
end
|
@@ -555,12 +563,14 @@ module ActionController
|
|
555
563
|
# Returns a parameter for the given +key+. If the +key+
|
556
564
|
# can't be found, there are several options: With no other arguments,
|
557
565
|
# it will raise an <tt>ActionController::ParameterMissing</tt> error;
|
558
|
-
# if
|
566
|
+
# if a second argument is given, then that is returned (converted to an
|
567
|
+
# instance of ActionController::Parameters if possible); if a block
|
559
568
|
# is given, then that will be run and its result returned.
|
560
569
|
#
|
561
570
|
# params = ActionController::Parameters.new(person: { name: "Francesco" })
|
562
571
|
# params.fetch(:person) # => <ActionController::Parameters {"name"=>"Francesco"} permitted: false>
|
563
572
|
# params.fetch(:none) # => ActionController::ParameterMissing: param is missing or the value is empty: none
|
573
|
+
# params.fetch(:none, {}) # => <ActionController::Parameters {} permitted: false>
|
564
574
|
# params.fetch(:none, "Francesco") # => "Francesco"
|
565
575
|
# params.fetch(:none) { "Francesco" } # => "Francesco"
|
566
576
|
def fetch(key, *args)
|
@@ -586,7 +596,8 @@ module ActionController
|
|
586
596
|
# params2 = ActionController::Parameters.new(foo: [10, 11, 12])
|
587
597
|
# params2.dig(:foo, 1) # => 11
|
588
598
|
def dig(*keys)
|
589
|
-
|
599
|
+
convert_hashes_to_parameters(keys.first, @parameters[keys.first])
|
600
|
+
@parameters.dig(*keys)
|
590
601
|
end
|
591
602
|
end
|
592
603
|
|
@@ -633,20 +644,18 @@ module ActionController
|
|
633
644
|
# params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
|
634
645
|
# params.transform_values { |x| x * 2 }
|
635
646
|
# # => <ActionController::Parameters {"a"=>2, "b"=>4, "c"=>6} permitted: false>
|
636
|
-
def transform_values
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
else
|
642
|
-
@parameters.transform_values
|
643
|
-
end
|
647
|
+
def transform_values
|
648
|
+
return to_enum(:transform_values) unless block_given?
|
649
|
+
new_instance_with_inherited_permitted_status(
|
650
|
+
@parameters.transform_values { |v| yield convert_value_to_parameters(v) }
|
651
|
+
)
|
644
652
|
end
|
645
653
|
|
646
654
|
# Performs values transformation and returns the altered
|
647
655
|
# <tt>ActionController::Parameters</tt> instance.
|
648
|
-
def transform_values!
|
649
|
-
|
656
|
+
def transform_values!
|
657
|
+
return to_enum(:transform_values!) unless block_given?
|
658
|
+
@parameters.transform_values! { |v| yield convert_value_to_parameters(v) }
|
650
659
|
self
|
651
660
|
end
|
652
661
|
|
@@ -669,10 +678,10 @@ module ActionController
|
|
669
678
|
self
|
670
679
|
end
|
671
680
|
|
672
|
-
# Deletes
|
673
|
-
#
|
674
|
-
#
|
675
|
-
#
|
681
|
+
# Deletes a key-value pair from +Parameters+ and returns the value. If
|
682
|
+
# +key+ is not found, returns +nil+ (or, with optional code block, yields
|
683
|
+
# +key+ and returns the result). Cf. +#extract!+, which returns the
|
684
|
+
# corresponding +ActionController::Parameters+ object.
|
676
685
|
def delete(key, &block)
|
677
686
|
convert_value_to_parameters(@parameters.delete(key, &block))
|
678
687
|
end
|
@@ -731,6 +740,7 @@ module ActionController
|
|
731
740
|
other_hash.to_h.merge(@parameters)
|
732
741
|
)
|
733
742
|
end
|
743
|
+
alias_method :with_defaults, :reverse_merge
|
734
744
|
|
735
745
|
# Returns current <tt>ActionController::Parameters</tt> instance with
|
736
746
|
# current hash merged into +other_hash+.
|
@@ -738,6 +748,7 @@ module ActionController
|
|
738
748
|
@parameters.merge!(other_hash.to_h) { |key, left, right| left }
|
739
749
|
self
|
740
750
|
end
|
751
|
+
alias_method :with_defaults!, :reverse_merge!
|
741
752
|
|
742
753
|
# This is required by ActiveModel attribute assignment, so that user can
|
743
754
|
# pass +Parameters+ to a mass assignment methods in a model. It should not
|