Fix uncaught query param encoding errors (#12741)
This commit is contained in:
parent
9edab7afaf
commit
09d54d1f62
18
app/middleware/handle_bad_encoding_middleware.rb
Normal file
18
app/middleware/handle_bad_encoding_middleware.rb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
# See: https://jamescrisp.org/2018/05/28/fixing-invalid-query-parameters-invalid-encoding-in-a-rails-app/
|
||||||
|
|
||||||
|
class HandleBadEncodingMiddleware
|
||||||
|
def initialize(app)
|
||||||
|
@app = app
|
||||||
|
end
|
||||||
|
|
||||||
|
def call(env)
|
||||||
|
begin
|
||||||
|
Rack::Utils.parse_nested_query(env['QUERY_STRING'].to_s)
|
||||||
|
rescue Rack::Utils::InvalidParameterError
|
||||||
|
env['QUERY_STRING'] = ''
|
||||||
|
end
|
||||||
|
|
||||||
|
@app.call(env)
|
||||||
|
end
|
||||||
|
end
|
|
@ -7,6 +7,7 @@ require 'rails/all'
|
||||||
Bundler.require(*Rails.groups)
|
Bundler.require(*Rails.groups)
|
||||||
|
|
||||||
require_relative '../app/lib/exceptions'
|
require_relative '../app/lib/exceptions'
|
||||||
|
require_relative '../app/middleware/handle_bad_encoding_middleware'
|
||||||
require_relative '../lib/paperclip/lazy_thumbnail'
|
require_relative '../lib/paperclip/lazy_thumbnail'
|
||||||
require_relative '../lib/paperclip/gif_transcoder'
|
require_relative '../lib/paperclip/gif_transcoder'
|
||||||
require_relative '../lib/paperclip/video_transcoder'
|
require_relative '../lib/paperclip/video_transcoder'
|
||||||
|
@ -118,6 +119,7 @@ module Mastodon
|
||||||
|
|
||||||
config.active_job.queue_adapter = :sidekiq
|
config.active_job.queue_adapter = :sidekiq
|
||||||
|
|
||||||
|
config.middleware.insert_before Rack::Runtime, HandleBadEncodingMiddleware
|
||||||
config.middleware.use Rack::Attack
|
config.middleware.use Rack::Attack
|
||||||
config.middleware.use Rack::Deflater
|
config.middleware.use Rack::Deflater
|
||||||
|
|
||||||
|
|
|
@ -46,10 +46,7 @@ class Rack::Attack
|
||||||
|
|
||||||
PROTECTED_PATHS_REGEX = Regexp.union(PROTECTED_PATHS.map { |path| /\A#{Regexp.escape(path)}/ })
|
PROTECTED_PATHS_REGEX = Regexp.union(PROTECTED_PATHS.map { |path| /\A#{Regexp.escape(path)}/ })
|
||||||
|
|
||||||
# Always allow requests from localhost
|
|
||||||
# (blocklist & throttles are skipped)
|
|
||||||
Rack::Attack.safelist('allow from localhost') do |req|
|
Rack::Attack.safelist('allow from localhost') do |req|
|
||||||
# Requests are allowed if the return value is truthy
|
|
||||||
req.remote_ip == '127.0.0.1' || req.remote_ip == '::1'
|
req.remote_ip == '127.0.0.1' || req.remote_ip == '::1'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
21
spec/middleware/handle_bad_encoding_middleware_spec.rb
Normal file
21
spec/middleware/handle_bad_encoding_middleware_spec.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe HandleBadEncodingMiddleware do
|
||||||
|
let(:app) { double() }
|
||||||
|
let(:middleware) { HandleBadEncodingMiddleware.new(app) }
|
||||||
|
|
||||||
|
it "request with query string is unchanged" do
|
||||||
|
expect(app).to receive(:call).with("PATH" => "/some/path", "QUERY_STRING" => "name=fred")
|
||||||
|
middleware.call("PATH" => "/some/path", "QUERY_STRING" => "name=fred")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "request with no query string is unchanged" do
|
||||||
|
expect(app).to receive(:call).with("PATH" => "/some/path")
|
||||||
|
middleware.call("PATH" => "/some/path")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "request with invalid encoding in query string drops query string" do
|
||||||
|
expect(app).to receive(:call).with("QUERY_STRING" => "", "PATH" => "/some/path")
|
||||||
|
middleware.call("QUERY_STRING" => "q=%2Fsearch%2Fall%Forder%3Ddescending%26page%3D5%26sort%3Dcreated_at", "PATH" => "/some/path")
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue