a9bcddee4c
Gitlab::HTTP now resolves the hostname only once, verifies the IP is not blocked, and then uses the same IP to perform the actual request, while passing the original hostname in the `Host` header and SSL SNI field.
40 lines
1.1 KiB
Ruby
40 lines
1.1 KiB
Ruby
module StubRequests
|
|
IP_ADDRESS_STUB = '8.8.8.9'.freeze
|
|
|
|
# Fully stubs a request using WebMock class. This class also
|
|
# stubs the IP address the URL is translated to (DNS lookup).
|
|
#
|
|
# It expects the final request to go to the `ip_address` instead the given url.
|
|
# That's primarily a DNS rebind attack prevention of Gitlab::HTTP
|
|
# (see: Gitlab::UrlBlocker).
|
|
#
|
|
def stub_full_request(url, ip_address: IP_ADDRESS_STUB, port: 80, method: :get)
|
|
stub_dns(url, ip_address: ip_address, port: port)
|
|
|
|
url = stubbed_hostname(url, hostname: ip_address)
|
|
WebMock.stub_request(method, url)
|
|
end
|
|
|
|
def stub_dns(url, ip_address:, port: 80)
|
|
url = parse_url(url)
|
|
socket = Socket.sockaddr_in(port, ip_address)
|
|
addr = Addrinfo.new(socket)
|
|
|
|
# See Gitlab::UrlBlocker
|
|
allow(Addrinfo).to receive(:getaddrinfo)
|
|
.with(url.hostname, url.port, nil, :STREAM)
|
|
.and_return([addr])
|
|
end
|
|
|
|
def stubbed_hostname(url, hostname: IP_ADDRESS_STUB)
|
|
url = parse_url(url)
|
|
url.hostname = hostname
|
|
url.to_s
|
|
end
|
|
|
|
private
|
|
|
|
def parse_url(url)
|
|
url.is_a?(URI) ? url : URI(url)
|
|
end
|
|
end
|