34 lines
1.1 KiB
Ruby
34 lines
1.1 KiB
Ruby
# 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
|