Commit ac766192 authored by George Koltsov's avatar George Koltsov

Update security/webhooks.md doc page & specs

Updating security/webhooks.md to match new behaviour
as well as drying up few specs to extract shared
examples
parent 5a19a43a
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# SystemHookUrlValidator # SystemHookUrlValidator
# #
# Custom validator specifically for SystemHook URLs. This validator works like AddressableUrlValidator but # Custom validator specific to SystemHook URLs. This validator works like AddressableUrlValidator but
# it blocks urls pointing to localhost or the local network depending on # it blocks urls pointing to localhost or the local network depending on
# ApplicationSetting.allow_local_requests_from_system_hooks # ApplicationSetting.allow_local_requests_from_system_hooks
# #
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
# #
class SystemHookUrlValidator < AddressableUrlValidator class SystemHookUrlValidator < AddressableUrlValidator
DEFAULT_OPTIONS = { DEFAULT_OPTIONS = {
allow_localhost: true, allow_localhost: false,
allow_local_network: true allow_local_network: false
}.freeze }.freeze
def initialize(options) def initialize(options)
......
...@@ -34,15 +34,15 @@ to 127.0.0.1, ::1 and 0.0.0.0, as well as IPv4 10.0.0.0/8, 172.16.0.0/12, ...@@ -34,15 +34,15 @@ to 127.0.0.1, ::1 and 0.0.0.0, as well as IPv4 10.0.0.0/8, 172.16.0.0/12,
192.168.0.0/16 and IPv6 site-local (ffc0::/10) addresses won't be allowed. 192.168.0.0/16 and IPv6 site-local (ffc0::/10) addresses won't be allowed.
This behavior can be overridden by enabling the option *"Allow requests to the This behavior can be overridden by enabling the option *"Allow requests to the
local network from hooks and services"* in the *"Outbound requests"* section local network from web hooks and services"* in the *"Outbound requests"* section
inside the Admin area under **Settings** inside the Admin area under **Settings**
(`/admin/application_settings/network`): (`/admin/application_settings/network`):
![Outbound requests admin settings](img/outbound_requests_section.png) ![Outbound requests admin settings](img/outbound_requests_section_v2.png)
>**Note:** >**Note:**
*System hooks* are exempt from this protection because they are set up by *System hooks* are enabled to make requests to local network by default since they are set up by admins.
admins. However, it can be turned off by disabling *"Allow requests to the local network from system hooks"* option.
<!-- ## Troubleshooting <!-- ## Troubleshooting
......
...@@ -19,44 +19,36 @@ describe WebHookService do ...@@ -19,44 +19,36 @@ describe WebHookService do
let(:service_instance) { described_class.new(project_hook, data, :push_hooks) } let(:service_instance) { described_class.new(project_hook, data, :push_hooks) }
describe '#initialize' do describe '#initialize' do
context 'when SystemHook' do before do
context 'when allow_local_requests_from_system_hooks application setting is true' do stub_application_setting(setting_name => setting)
it 'allows local requests' do end
stub_application_setting(allow_local_requests_from_system_hooks: true)
instance = described_class.new(build(:system_hook), data, :system_hook)
expect(instance.request_options[:allow_local_requests]).to be_truthy shared_examples_for 'respecting outbound network setting' do
end context 'local requests are allowed' do
let(:setting) { true }
it { expect(hook.request_options[:allow_local_requests]).to be_truthy }
end end
context 'when allow_local_requests_from_system_hooks application setting is false' do context 'local requests are not allowed' do
it 'denies local requests' do let(:setting) { false }
stub_application_setting(allow_local_requests_from_system_hooks: false)
instance = described_class.new(build(:system_hook), data, :system_hook)
expect(instance.request_options[:allow_local_requests]).to be_falsey it { expect(hook.request_options[:allow_local_requests]).to be_falsey }
end
end end
end
context 'when ProjectHook' do context 'when SystemHook' do
context 'when allow_local_requests_from_web_hooks_and_services application setting is true' do let(:setting_name) { :allow_local_requests_from_system_hooks }
it 'allows local requests' do let(:hook) { described_class.new(build(:system_hook), data, :system_hook) }
stub_application_setting(allow_local_requests_from_web_hooks_and_services: true)
instance = described_class.new(build(:project_hook), data, :project_hook)
expect(instance.request_options[:allow_local_requests]).to be_truthy include_examples 'respecting outbound network setting'
end end
end
context 'when allow_local_requests_from_system_hooks application setting is false' do context 'when ProjectHook' do
it 'denies local requests' do let(:setting_name) { :allow_local_requests_from_web_hooks_and_services }
stub_application_setting(allow_local_requests_from_web_hooks_and_services: false) let(:hook) { described_class.new(build(:project_hook), data, :project_hook) }
instance = described_class.new(build(:project_hook), data, :project_hook)
expect(instance.request_options[:allow_local_requests]).to be_falsey include_examples 'respecting outbound network setting'
end
end
end
end end
end end
......
...@@ -11,43 +11,48 @@ describe SystemHookUrlValidator do ...@@ -11,43 +11,48 @@ describe SystemHookUrlValidator do
subject { validator.validate(badge) } subject { validator.validate(badge) }
it 'does not block urls pointing to localhost' do it 'blocks urls pointing to localhost' do
badge.link_url = 'https://127.0.0.1' badge.link_url = 'https://127.0.0.1'
subject subject
expect(badge.errors).not_to be_present expect(badge.errors).to be_present
end end
it 'does not block urls pointing to the local network' do it 'blocks urls pointing to the local network' do
badge.link_url = 'https://192.168.1.1' badge.link_url = 'https://192.168.1.1'
subject subject
expect(badge.errors).not_to be_present expect(badge.errors).to be_present
end end
end end
context 'when local requests are not allowed' do context 'when local requests are allowed' do
let(:validator) { described_class.new(attributes: [:link_url], allow_localhost: false, allow_local_network: false) } let(:validator) { described_class.new(attributes: [:link_url]) }
let!(:badge) { build(:badge, link_url: 'http://www.example.com') } let!(:badge) { build(:badge, link_url: 'http://www.example.com') }
let!(:settings) { create(:application_setting) }
subject { validator.validate(badge) } subject { validator.validate(badge) }
it 'blocks urls pointing to localhost' do before do
stub_application_setting(allow_local_requests_from_system_hooks: true)
end
it 'does not block urls pointing to localhost' do
badge.link_url = 'https://127.0.0.1' badge.link_url = 'https://127.0.0.1'
subject subject
expect(badge.errors).to be_present expect(badge.errors).not_to be_present
end end
it 'blocks urls pointing to the local network' do it 'does not block urls pointing to the local network' do
badge.link_url = 'https://192.168.1.1' badge.link_url = 'https://192.168.1.1'
subject subject
expect(badge.errors).to be_present expect(badge.errors).not_to be_present
end end
end end
end end
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