Skip to content

Commit

Permalink
Block loopback addresses in UrlBlocker
Browse files Browse the repository at this point in the history
  • Loading branch information
stanhu committed Sep 6, 2018
1 parent ab22dae commit b1d04cf
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 1 deletion.
5 changes: 5 additions & 0 deletions changelogs/unreleased/sh-block-other-localhost.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
title: Block loopback addresses in UrlBlocker
merge_request:
author:
type: security
7 changes: 7 additions & 0 deletions lib/gitlab/url_blocker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def validate!(url, allow_localhost: false, allow_local_network: true, enforce_us
end

validate_localhost!(addrs_info) unless allow_localhost
validate_loopback!(addrs_info) unless allow_localhost
validate_local_network!(addrs_info) unless allow_local_network
validate_link_local!(addrs_info) unless allow_local_network

Expand Down Expand Up @@ -84,6 +85,12 @@ def validate_localhost!(addrs_info)
raise BlockedUrlError, "Requests to localhost are not allowed"
end

def validate_loopback!(addrs_info)
return unless addrs_info.any? { |addr| addr.ipv4_loopback? || addr.ipv6_loopback? }

raise BlockedUrlError, "Requests to loopback addresses are not allowed"
end

def validate_local_network!(addrs_info)
return unless addrs_info.any? { |addr| addr.ipv4_private? || addr.ipv6_sitelocal? }

Expand Down
22 changes: 21 additions & 1 deletion spec/lib/gitlab/url_blocker_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@
expect(described_class.blocked_url?('https://gitlab.com/foo/foo.git', protocols: ['http'])).to be true
end

it 'returns true for localhost IPs' do
expect(described_class.blocked_url?('https://0.0.0.0/foo/foo.git')).to be true
expect(described_class.blocked_url?('https://[::1]/foo/foo.git')).to be true
expect(described_class.blocked_url?('https://127.0.0.1/foo/foo.git')).to be true
end

it 'returns true for loopback IP' do
expect(described_class.blocked_url?('https://127.0.0.2/foo/foo.git')).to be true
end

it 'returns true for alternative version of 127.0.0.1 (0177.1)' do
expect(described_class.blocked_url?('https://0177.1:65535/foo/foo.git')).to be true
end
Expand Down Expand Up @@ -84,6 +94,16 @@
end
end

it 'allows localhost endpoints' do
expect(described_class).not_to be_blocked_url('http://0.0.0.0', allow_localhost: true)
expect(described_class).not_to be_blocked_url('http://localhost', allow_localhost: true)
expect(described_class).not_to be_blocked_url('http://127.0.0.1', allow_localhost: true)
end

it 'allows loopback endpoints' do
expect(described_class).not_to be_blocked_url('http://127.0.0.2', allow_localhost: true)
end

it 'allows IPv4 link-local endpoints' do
expect(described_class).not_to be_blocked_url('http://169.254.169.254')
expect(described_class).not_to be_blocked_url('http://169.254.168.100')
Expand Down Expand Up @@ -122,7 +142,7 @@
end

def stub_domain_resolv(domain, ip)
allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([double(ip_address: ip, ipv4_private?: true, ipv6_link_local?: false)])
allow(Addrinfo).to receive(:getaddrinfo).with(domain, any_args).and_return([double(ip_address: ip, ipv4_private?: true, ipv6_link_local?: false, ipv4_loopback?: false, ipv6_loopback?: false)])
end

def unstub_domain_resolv
Expand Down

0 comments on commit b1d04cf

Please sign in to comment.