Skip to content

Malformed Accept headers from bots cause 500 errors (Rollbar #549) #2873

Description

@mroderick

Description of the issue 📄

Rollbar shows recurring ActionDispatch::Http::MimeNegotiation::InvalidType errors, e.g.:
"../../../../../../../../../../etc/services{{" is not a valid MIME type
(Rollbar #549)

These are automated scanner probes that send path-traversal strings in the Accept header. Rails 8.1 raises InvalidType during MIME negotiation, and the class is not in the default rescue_responses map (verified in actionpack 8.1.3.1's exception_wrapper.rb), so each probe becomes a 500 and a Rollbar notification. There is nothing for the application to do with these requests — they should never reach it, or at worst return 4xx.

Options

1. Nginx edge blockconfig/nginx.conf.erb gets a map on the Accept/Content-Type headers and returns 406 when either contains ../:

map "$http_accept $content_type" $bad_mime {
    default 0;
    ~"\.\./" 1;
}

if ($bad_mime) { return 406; }

Pros: stops these requests before Rails, no app code. Cons: nginx config is baked into the dyno, so it's awkward to test locally; the rule only covers ../ patterns in those two headers.

2. App-level rescue — map the exception to 406 in config/application.rb:

config.action_dispatch.rescue_responses[
  "ActionDispatch::Http::MimeNegotiation::InvalidType"
] = :not_acceptable

Pros: one line, testable, uses the same mechanism Rails already uses for ActionController::UnknownFormat. Cons: the request still reaches the app (and its access logs), though Rollbar goes quiet.

3. Both — nginx rule as the primary block, rescue_responses as the safety net for anything nginx misses (other probe shapes hitting the same code path).

Recommendation

Option 3. The nginx rule blocks the current probe pattern cheaply, and the rescue mapping guarantees no 500 for this class of malformed request regardless of what pattern the bots use next.

Comments on the approach welcome — happy to open a PR once agreed.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions