Commit e5181ff4 authored by Thong Kuah's avatar Thong Kuah

Do not allow local urls in Kubernetes form

Use existing `public_url` validation to block various local urls. Note
that this validation will allow local urls if the "Allow requests to the
local network from hooks and services" admin setting is enabled.

Block KubeClient from using local addresses

It will also respect `allow_local_requests_from_hooks_and_services` so
if that is enabled KubeClinet will allow local addresses
parent b8b18dd6
......@@ -41,7 +41,7 @@ class Kubernetes < ActiveRecord::Base
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)
validates :api_url, url: true, presence: true
validates :api_url, public_url: true, presence: true
validates :token, presence: true
validate :prevent_modification, on: :update
......
---
title: Block local URLs for Kubernetes integration
merge_request:
author:
type: security
......@@ -82,6 +82,8 @@ class KubeClient
def initialize(api_prefix, **kubeclient_options)
@api_prefix = api_prefix
@kubeclient_options = kubeclient_options.merge(http_max_redirects: 0)
validate_url!
end
def create_or_update_cluster_role_binding(resource)
......@@ -118,6 +120,12 @@ def create_or_update_secret(resource)
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)
get_cluster_role_binding(resource.metadata.name)
rescue ::Kubeclient::ResourceNotFoundError
......
......@@ -50,6 +50,36 @@
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
subject { client.core_client }
......
......@@ -98,6 +98,22 @@
it { expect(kubernetes.save).to be_truthy }
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
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