Commit 03340f09 authored by Yorick Peterse's avatar Yorick Peterse

Merge branch 'security-kubernetes-local-ssrf' into 'master'

Block local URLs for Kubernetes integration

See merge request gitlab/gitlabhq!2901
parents 6412a3e0 af16fd68
...@@ -41,7 +41,7 @@ class Kubernetes < ActiveRecord::Base ...@@ -41,7 +41,7 @@ class Kubernetes < ActiveRecord::Base
validate :no_namespace, unless: :allow_user_defined_namespace? validate :no_namespace, unless: :allow_user_defined_namespace?
# We expect to be `active?` only when enabled and cluster is created (the api_url is assigned) # We expect to be `active?` only when enabled and cluster is created (the api_url is assigned)
validates :api_url, url: true, presence: true validates :api_url, public_url: true, presence: true
validates :token, presence: true validates :token, presence: true
validates :ca_cert, certificate: true, allow_blank: true, if: :ca_cert_changed? validates :ca_cert, certificate: true, allow_blank: true, if: :ca_cert_changed?
......
---
title: Block local URLs for Kubernetes integration
merge_request:
author:
type: security
...@@ -82,6 +82,8 @@ class KubeClient ...@@ -82,6 +82,8 @@ class KubeClient
def initialize(api_prefix, **kubeclient_options) def initialize(api_prefix, **kubeclient_options)
@api_prefix = api_prefix @api_prefix = api_prefix
@kubeclient_options = kubeclient_options.merge(http_max_redirects: 0) @kubeclient_options = kubeclient_options.merge(http_max_redirects: 0)
validate_url!
end end
def create_or_update_cluster_role_binding(resource) def create_or_update_cluster_role_binding(resource)
...@@ -118,6 +120,12 @@ def create_or_update_secret(resource) ...@@ -118,6 +120,12 @@ def create_or_update_secret(resource)
private private
def validate_url!
return if Gitlab::CurrentSettings.allow_local_requests_from_hooks_and_services?
Gitlab::UrlBlocker.validate!(api_prefix, allow_local_network: false)
end
def cluster_role_binding_exists?(resource) def cluster_role_binding_exists?(resource)
get_cluster_role_binding(resource.metadata.name) get_cluster_role_binding(resource.metadata.name)
rescue ::Kubeclient::ResourceNotFoundError rescue ::Kubeclient::ResourceNotFoundError
......
...@@ -50,6 +50,36 @@ ...@@ -50,6 +50,36 @@
end end
end end
describe '#initialize' do
shared_examples 'local address' do
it 'blocks local addresses' do
expect { client }.to raise_error(Gitlab::UrlBlocker::BlockedUrlError)
end
context 'when local requests are allowed' do
before do
stub_application_setting(allow_local_requests_from_hooks_and_services: true)
end
it 'allows local addresses' do
expect { client }.not_to raise_error
end
end
end
context 'localhost address' do
let(:api_url) { 'http://localhost:22' }
it_behaves_like 'local address'
end
context 'private network address' do
let(:api_url) { 'http://192.168.1.2:3003' }
it_behaves_like 'local address'
end
end
describe '#core_client' do describe '#core_client' do
subject { client.core_client } subject { client.core_client }
......
...@@ -98,6 +98,22 @@ ...@@ -98,6 +98,22 @@
it { expect(kubernetes.save).to be_truthy } it { expect(kubernetes.save).to be_truthy }
end end
context 'when api_url is localhost' do
let(:api_url) { 'http://localhost:22' }
it { expect(kubernetes.save).to be_falsey }
context 'Application settings allows local requests' do
before do
allow(ApplicationSetting)
.to receive(:current)
.and_return(ApplicationSetting.build_from_defaults(allow_local_requests_from_hooks_and_services: true))
end
it { expect(kubernetes.save).to be_truthy }
end
end
end end
context 'when validates token' do context 'when validates token' do
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment