Don't show error messages that could contain private information.

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>
This commit is contained in:
evazion
2022-02-06 17:02:07 -06:00
parent 8b5d687b7a
commit 7bed81812d
11 changed files with 74 additions and 41 deletions

View File

@@ -109,7 +109,7 @@ class SessionLoader
elsif params[:login].present? && params[:api_key].present?
authenticate_api_key(params[:login], params[:api_key])
else
raise AuthenticationFailure
raise AuthenticationFailure, "Missing `login` or `api_key`"
end
end
@@ -129,7 +129,7 @@ class SessionLoader
# permissions for this endpoint
def authenticate_api_key(name, key)
user, api_key = User.find_by_name(name)&.authenticate_api_key(key)
raise AuthenticationFailure if user.blank?
raise AuthenticationFailure, "Invalid API key" if user.blank?
update_api_key(api_key)
raise User::PrivilegeError if !api_key.has_permission?(request.remote_ip, request.params[:controller], request.params[:action])
CurrentUser.user = user