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

@@ -1,11 +0,0 @@
<%# backtrace %>
<ul class="backtrace font-monospace p-4 mb-4">
<% if defined?(exception) %>
<li><%= exception.class.to_s %> exception raised</li>
<% end %>
<% Rails.backtrace_cleaner.clean(backtrace).each do |b| %>
<li class="backtrace-line"><%= b %></li>
<% end %>
</ul>

View File

@@ -0,0 +1 @@
<%= raw @api_response.to_xml(root: "result") %>

View File

@@ -1,9 +1,19 @@
<% page_title "Error: #{@message}" %>
<% page_title "Error: #{@exception.class}" %>
<h1>Error</h1>
<p><%= @message %></p>
<% unless @expected %>
<% if @message.present? %>
<p><%= @message %></p>
<% else %>
<p>Unexpected error: <%= @exception.class %>.</p>
<h3>Details</h3>
<%= render "static/backtrace", exception: @exception, backtrace: @backtrace %>
<ul class="backtrace font-monospace p-4 mb-4">
<li><%= @exception.class.to_s %> exception raised</li>
<% Rails.backtrace_cleaner.clean(@backtrace).each do |b| %>
<li class="backtrace-line"><%= b %></li>
<% end %>
</ul>
<% end %>

View File

@@ -1,10 +1,7 @@
var klass = <%= raw @exception.class.to_s.to_json %>;
var message = <%= raw @message.to_json %>;
var backtrace = <%= raw @backtrace.to_json %>;
console.error(<%= raw @api_response.to_json %>);
<% if @expected %>
Danbooru.Utility.error(message);
<% if @message.present? %>
Danbooru.Utility.error("<%= j @message %>");
<% else %>
console.error(klass, message, backtrace);
Danbooru.Utility.error(message);
Danbooru.Utility.error("<%= j "Unexpected error: #{@exception.class}" %>");
<% end %>

View File

@@ -1,5 +1 @@
{
"success": false,
"message": <%= raw @message.to_json %>,
"backtrace": <%= raw @backtrace.to_json %>
}
<%= raw @api_response.to_json %>

View File

@@ -1,2 +1 @@
<?xml version="1.0" encoding="UTF-8"?>
<result success="false"><%= @message %></result>
<%= raw @api_response.to_xml(root: "result") %>