diff options
Diffstat (limited to 'lib/gitlab/middleware/handle_ip_spoof_attack_error.rb')
-rw-r--r-- | lib/gitlab/middleware/handle_ip_spoof_attack_error.rb | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/lib/gitlab/middleware/handle_ip_spoof_attack_error.rb b/lib/gitlab/middleware/handle_ip_spoof_attack_error.rb new file mode 100644 index 00000000000..2fc08db9b4d --- /dev/null +++ b/lib/gitlab/middleware/handle_ip_spoof_attack_error.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module Gitlab + module Middleware + # ActionDispatch::RemoteIp tries to set the `request.ip` for controllers by + # looking at the request IP and headers. It needs to see through any reverse + # proxies to get the right answer, but there are some security issues with + # that. + # + # Proxies can specify `Client-Ip` or `X-Forwarded-For`, and the security of + # that is determined at the edge. If both headers are present, it's likely + # that the edge is securing one, but ignoring the other. Rails blocks this, + # which is correct, because we don't know which header is the safe one - but + # we want the block to be a 400, rather than 500, error. + # + # This middleware needs to go before ActionDispatch::RemoteIp in the chain. + class HandleIpSpoofAttackError + attr_reader :app + + def initialize(app) + @app = app + end + + def call(env) + app.call(env) + rescue ActionDispatch::RemoteIp::IpSpoofAttackError => err + Gitlab::ErrorTracking.track_exception(err) + + [400, { 'Content-Type' => 'text/plain' }, ['Bad Request']] + end + end + end +end |