diff options
Diffstat (limited to 'lib/gitlab/rack_attack/request.rb')
-rw-r--r-- | lib/gitlab/rack_attack/request.rb | 49 |
1 files changed, 33 insertions, 16 deletions
diff --git a/lib/gitlab/rack_attack/request.rb b/lib/gitlab/rack_attack/request.rb index 94ae29af3d0..b24afd28dd7 100644 --- a/lib/gitlab/rack_attack/request.rb +++ b/lib/gitlab/rack_attack/request.rb @@ -3,6 +3,8 @@ module Gitlab module RackAttack module Request + include ::Gitlab::Utils::StrongMemoize + FILES_PATH_REGEX = %r{^/api/v\d+/projects/[^/]+/repository/files/.+}.freeze GROUP_PATH_REGEX = %r{^/api/v\d+/groups/[^/]+/?$}.freeze @@ -26,23 +28,31 @@ module Gitlab end def api_request? - path.start_with?('/api') + logical_path.start_with?('/api') + end + + def logical_path + @logical_path ||= path.delete_prefix(Gitlab.config.gitlab.relative_url_root) + end + + def matches?(regex) + logical_path.match?(regex) end def api_internal_request? - path =~ %r{^/api/v\d+/internal/} + matches?(%r{^/api/v\d+/internal/}) end def health_check_request? - path =~ %r{^/-/(health|liveness|readiness|metrics)} + matches?(%r{^/-/(health|liveness|readiness|metrics)}) end def container_registry_event? - path =~ %r{^/api/v\d+/container_registry_event/} + matches?(%r{^/api/v\d+/container_registry_event/}) end def product_analytics_collector_request? - path.start_with?('/-/collector/i') + logical_path.start_with?('/-/collector/i') end def should_be_skipped? @@ -54,11 +64,7 @@ module Gitlab end def protected_path? - !protected_path_regex.nil? - end - - def protected_path_regex - path =~ protected_paths_regex + matches?(protected_paths_regex) end def throttle?(throttle, authenticated:) @@ -70,6 +76,7 @@ module Gitlab def throttle_unauthenticated_api? api_request? && !should_be_skipped? && + !frontend_request? && !throttle_unauthenticated_packages_api? && !throttle_unauthenticated_files_api? && !throttle_unauthenticated_deprecated_api? && @@ -78,7 +85,7 @@ module Gitlab end def throttle_unauthenticated_web? - web_request? && + (web_request? || frontend_request?) && !should_be_skipped? && # TODO: Column will be renamed in https://gitlab.com/gitlab-org/gitlab/-/issues/340031 Gitlab::Throttle.settings.throttle_unauthenticated_enabled && @@ -87,6 +94,7 @@ module Gitlab def throttle_authenticated_api? api_request? && + !frontend_request? && !throttle_authenticated_packages_api? && !throttle_authenticated_files_api? && !throttle_authenticated_deprecated_api? && @@ -94,7 +102,7 @@ module Gitlab end def throttle_authenticated_web? - web_request? && + (web_request? || frontend_request?) && !throttle_authenticated_git_lfs? && Gitlab::Throttle.settings.throttle_authenticated_web_enabled end @@ -178,15 +186,24 @@ module Gitlab end def packages_api_path? - path =~ ::Gitlab::Regex::Packages::API_PATH_REGEX + matches?(::Gitlab::Regex::Packages::API_PATH_REGEX) end def git_lfs_path? - path =~ Gitlab::PathRegex.repository_git_lfs_route_regex + matches?(::Gitlab::PathRegex.repository_git_lfs_route_regex) end def files_api_path? - path =~ FILES_PATH_REGEX + matches?(FILES_PATH_REGEX) + end + + def frontend_request? + strong_memoize(:frontend_request) do + next false unless env.include?('HTTP_X_CSRF_TOKEN') && session.include?(:_csrf_token) + + # CSRF tokens are not verified for GET/HEAD requests, so we pretend that we always have a POST request. + Gitlab::RequestForgeryProtection.verified?(env.merge('REQUEST_METHOD' => 'POST')) + end end def deprecated_api_request? @@ -195,7 +212,7 @@ module Gitlab with_projects = params['with_projects'] with_projects = true if with_projects.blank? - path =~ GROUP_PATH_REGEX && Gitlab::Utils.to_boolean(with_projects) + matches?(GROUP_PATH_REGEX) && Gitlab::Utils.to_boolean(with_projects) end end end |