Fix a potential exploit where private information could be leaked if
it was contained in the error message of an unexpected exception.
For example, NoMethodError contains a raw dump of the object in the
error message, which could leak private user data if you could force a
User object to raise a NoMethodError.
Fix the error page to only show known-safe error messages from expected
exceptions, not unknown error messages from unexpected exceptions.
API changes:
* JSON errors now have a `message` param. The message will be blank for unknown exceptions.
* XML errors have a new format. This is a breaking change. They now look like this:
<result>
<success type="boolean">false</success>
<error>PaginationExtension::PaginationError</error>
<message>You cannot go beyond page 5000.</message>
<backtrace type="array">
<backtrace>app/logical/pagination_extension.rb:54:in `paginate'</backtrace>
<backtrace>app/models/application_record.rb:17:in `paginate'</backtrace>
<backtrace>app/logical/post_query_builder.rb:529:in `paginated_posts'</backtrace>
<backtrace>app/logical/post_sets/post.rb:95:in `posts'</backtrace>
<backtrace>app/controllers/posts_controller.rb:22:in `index'</backtrace>
</backtrace>
</result>
instead of like this:
<result success="false">You cannot go beyond page 5000.</result>
38 lines
865 B
Ruby
38 lines
865 B
Ruby
# frozen_string_literal: true
|
|
|
|
class SessionsController < ApplicationController
|
|
respond_to :html, :json
|
|
skip_forgery_protection only: :create, if: -> { !request.format.html? }
|
|
|
|
rate_limit :create, rate: 1.0/1.minute, burst: 10
|
|
|
|
def new
|
|
@user = User.new
|
|
end
|
|
|
|
def confirm_password
|
|
end
|
|
|
|
def create
|
|
name, password, url = params.fetch(:session, params).slice(:name, :password, :url).values
|
|
user = SessionLoader.new(request).login(name, password)
|
|
url ||= posts_path
|
|
|
|
if user
|
|
respond_with(user, location: url)
|
|
else
|
|
flash.now[:notice] = "Password was incorrect"
|
|
raise SessionLoader::AuthenticationFailure, "Username or password incorrect"
|
|
end
|
|
end
|
|
|
|
def destroy
|
|
SessionLoader.new(request).logout
|
|
redirect_to(posts_path, :notice => "You are now logged out")
|
|
end
|
|
|
|
def sign_out
|
|
destroy
|
|
end
|
|
end
|