Add outbound allowlist to allowed URIs for SSRF filter
Context
https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4137+ introduced the SSRF filtering for the packages dependency proxy.
https://gitlab.com/gitlab-com/request-for-help/-/issues/2233#note_2439576170 revealed that, when the private host is used to fetch the dependencies, such requests won't be allowed by SSRF filter in the workhorse.
What does this MR do and why?
Add outbound_local_requests_whitelist
from the settings to the list of
allowed endpoints for SSRF filter for the packages dependency proxy and
virtual registries.
Since the outbound_local_requests_whitelist
is a user input in the free form. I've chosen to rename allowed_uris
to allowed_endpoints
since the later better covers the various formats we're supporting (URLs, host combinations, and plain hostnames).
References
https://gitlab.com/gitlab-org/gitlab/-/issues/534288+s
Screenshots or screen recordings
No.
How to set up and validate locally
Packages dependency proxy
- To simplify the verification allow local IP addresses in the dependency proxy settings and not allow local IP addressed for SSRF filtering in the workhorse.
diff
diff --git a/ee/app/models/dependency_proxy/packages/setting.rb b/ee/app/models/dependency_proxy/packages/setting.rb
index 7b92e386e4b3..cbbc1877f8d7 100644
--- a/ee/app/models/dependency_proxy/packages/setting.rb
+++ b/ee/app/models/dependency_proxy/packages/setting.rb
@@ -40,7 +40,7 @@ class Setting < ApplicationRecord
# maven
validates :maven_external_registry_url,
- addressable_url: { allow_localhost: false, allow_local_network: false },
+ addressable_url: { allow_localhost: true, allow_local_network: true },
if: :maven_external_registry_url?
validates :maven_external_registry_username, presence: true, if: :maven_external_registry_password?
validates :maven_external_registry_password, presence: true, if: :maven_external_registry_username?
diff --git a/ee/lib/api/concerns/dependency_proxy/packages_helpers.rb b/ee/lib/api/concerns/dependency_proxy/packages_helpers.rb
index d322bf7abe9d..23193557eaf2 100644
--- a/ee/lib/api/concerns/dependency_proxy/packages_helpers.rb
+++ b/ee/lib/api/concerns/dependency_proxy/packages_helpers.rb
@@ -199,7 +199,7 @@ def require_non_web_browser!
end
def allow_localhost
- Gitlab.dev_or_test_env? || Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services?
+ false # Gitlab.dev_or_test_env? || Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services?
end
def allowed_uris
-
Prepare the third party server
$ mkdir simple-server $ cd simple-server $ touch Gemfile $ touch server.rb
# Gemfile source 'https://rubygems.org' gem 'rackup', '~> 2.1' gem 'sinatra', '~> 4.0' # server.rb require 'sinatra' get '/foo/1/bar' do 'Hello world!' end
$ bundle install $ ruby server.rb
Copy the server URL with port
-
Enable maven dependency proxy for the chosen project
Visit the packages and registries settings of your project http://gdk.test:3000/gitlab-org/gitlab-test/-/settings/packages_and_registries Use the URL of the third party server as a URL for the maven dependency proxy and save the configuration.
-
Add the third party server IP to the list of allowed outbound IPs
Visit http://gdk.test:3000/admin/application_settings/network#js-outbound-settings Add the IP to the list of allowed outbound IPs.
-
Test maven dependency proxy
$ curl -v http://<maintainer-username>:<maintainer-pat>@gdk.test:3000/api/v4/projects/<project-id>/dependency_proxy/packages/maven/foo/1/bar
The response is expected to be
200
and the workhorse logs will have the corresponding similar entry:{"backend_id":"rails","content_type":"text/html;charset=utf-8","correlation_id":"01JSH9A272FSKRWGX26RR7QJ2R","duration_ms":1377,"host":"gdk.test:3000","level":"info","method":"GET","msg":"access","proto":"HTTP/1.1","read_bytes":232,"referrer":"","remote_addr":"172.16.123.1:61029","remote_ip":"172.16.123.1","route":"^/api/","route_id":"api","status":200,"system":"http","time":"2025-04-23T14:17:37+02:00","ttfb_ms":1048,"uri":"/api/v4/projects/1/dependency_proxy/packages/maven/foo/1/bar","user_agent":"curl/8.11.1","written_bytes":12}
Now, remove the third party server IP from the list of allowed outbound IPs and repeat the request.
The server should respond with the error.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Related to #534288