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
 |