Skip to content

Commit

Permalink
[#162105] Handle mime type errors (#4819)
Browse files Browse the repository at this point in the history
* Add middleware to fix mime type errors

* Refactor middleware
  • Loading branch information
diebas authored Jan 8, 2025
1 parent 8944007 commit f5bcef3
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
2 changes: 2 additions & 0 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
require "rails/all"
require "will_paginate/array"
require "active_storage/engine"
require_relative "../lib/middlewares/sanitize_headers_middleware"

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Expand Down Expand Up @@ -79,6 +80,7 @@ class Application < Rails::Application

# Prevent invalid (usually malicious) URLs from causing exceptions/issues
config.middleware.insert 0, Rack::UTF8Sanitizer
config.middleware.insert_before Rack::UTF8Sanitizer, SanitizeHeadersMiddleware

config.active_storage.variant_processor = :vips

Expand Down
21 changes: 21 additions & 0 deletions lib/middlewares/sanitize_headers_middleware.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class SanitizeHeadersMiddleware
def initialize(app)
@app = app
end

def call(env)
request = ActionDispatch::Request.new(env)

fallback_to_html_format_if_invalid_mime_type(request)

@app.call(env)
end

private
def fallback_to_html_format_if_invalid_mime_type(request)
request.formats
rescue ActionDispatch::Http::MimeNegotiation::InvalidType
request.set_header "CONTENT_TYPE", "text/html"
end
end

37 changes: 37 additions & 0 deletions spec/middlewares/sanitize_headers_middleware_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
require "rack/mock"
require "rails_helper"

RSpec.describe SanitizeHeadersMiddleware do
let(:app) { ->(env) { [200, env, "OK"] } }
let(:middleware) { described_class.new(app) }

context "when HTTP_ACCEPT header is valid" do
it "does not alter the headers" do
env = Rack::MockRequest.env_for("/", "HTTP_ACCEPT" => "text/html,application/json")
status, headers, _body = middleware.call(env)

expect(env["HTTP_ACCEPT"]).to eq("text/html,application/json")
expect(status).to eq(200)
end
end

context "when HTTP_ACCEPT header is invalid" do
it "sets CONTENT_TYPE to text/html" do
env = Rack::MockRequest.env_for("/", "HTTP_ACCEPT" => "../../../../../etc/passwd{{")
status, headers, _body = middleware.call(env)

expect(env["CONTENT_TYPE"]).to eq("text/html")
expect(status).to eq(200)
end
end

context "when HTTP_ACCEPT header is missing" do
it "does not alter the headers" do
env = Rack::MockRequest.env_for("/")
status, headers, _body = middleware.call(env)

expect(env["CONTENT_TYPE"]).to be_nil
expect(status).to eq(200)
end
end
end

0 comments on commit f5bcef3

Please sign in to comment.