controllers: don't allow GET requests with params in the body.
Don't allow GET requests to pass the request params in the body instead of in the URL. While Rails can handle GET params passed in the body, it goes against spec and it may cause problems if the response is a redirect and the client doesn't send the body params when following the redirect. This may be a breaking change for broken API clients who were sending GET params in the body instead of in the URL. This can happen when people use HTTP libraries incorrectly.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
class ApplicationController < ActionController::Base
|
||||
class PageRemovedError < StandardError; end
|
||||
class RequestBodyNotAllowedError < StandardError; end
|
||||
|
||||
include Pundit::Authorization
|
||||
helper_method :search_params, :permitted_attributes
|
||||
@@ -9,6 +10,7 @@ class ApplicationController < ActionController::Base
|
||||
self.responder = ApplicationResponder
|
||||
|
||||
skip_forgery_protection if: -> { SessionLoader.new(request).has_api_authentication? }
|
||||
before_action :check_get_body
|
||||
before_action :reset_current_user
|
||||
before_action :set_current_user
|
||||
before_action :normalize_search
|
||||
@@ -120,6 +122,8 @@ class ApplicationController < ActionController::Base
|
||||
render_error_page(401, exception, message: exception.message, template: "sessions/new")
|
||||
when ActionController::InvalidAuthenticityToken, ActionController::UnpermittedParameters, ActionController::InvalidCrossOriginRequest, ActionController::Redirecting::UnsafeRedirectError
|
||||
render_error_page(403, exception, message: exception.message)
|
||||
when RequestBodyNotAllowedError
|
||||
render_error_page(403, exception, message: "Request body not allowed for #{request.method} request")
|
||||
when ActiveSupport::MessageVerifier::InvalidSignature, # raised by `find_signed!`
|
||||
User::PrivilegeError,
|
||||
Pundit::NotAuthorizedError
|
||||
@@ -193,6 +197,10 @@ class ApplicationController < ActionController::Base
|
||||
request.variant = params[:variant].try(:to_sym)
|
||||
end
|
||||
|
||||
def check_get_body
|
||||
raise RequestBodyNotAllowedError if request.method.in?(%w[GET HEAD OPTIONS]) && request.body.size > 0
|
||||
end
|
||||
|
||||
# allow api clients to force errors for testing purposes.
|
||||
def cause_error
|
||||
return unless params[:cause_error].present?
|
||||
|
||||
Reference in New Issue
Block a user