From e052fdb5520e03881c459e215ac70f57eccf48f6 Mon Sep 17 00:00:00 2001 From: Vasilii Iakliushin Date: Tue, 18 Nov 2025 11:08:58 +0100 Subject: [PATCH] Exclude Git HTTP requests from authenticated web throttle Contributes to https://gitlab.com/gitlab-org/gitlab/-/issues/581142 **Problem** Authenticated Git HTTP requests can be throttled by both Authenticated Web rate limit and Authenticated Git HTTP rate limit. Without this fix, authenticated users performing Git operations could hit rate limits faster than intended because their requests were being counted twice. **Solution** Exclude Authenticated Git HTTP requests from Authenticated Web rate limit to match [documentation](https://docs.gitlab.com/administration/settings/git_http_rate_limits/). Changelog: fixed --- ...exclude_git_http_from_web_rate_limiter.yml | 10 +++ lib/gitlab/rack_attack/request.rb | 1 + spec/lib/gitlab/rack_attack/request_spec.rb | 73 +++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 config/feature_flags/gitlab_com_derisk/exclude_git_http_from_web_rate_limiter.yml diff --git a/config/feature_flags/gitlab_com_derisk/exclude_git_http_from_web_rate_limiter.yml b/config/feature_flags/gitlab_com_derisk/exclude_git_http_from_web_rate_limiter.yml new file mode 100644 index 00000000000000..32fdae51d02492 --- /dev/null +++ b/config/feature_flags/gitlab_com_derisk/exclude_git_http_from_web_rate_limiter.yml @@ -0,0 +1,10 @@ +--- +name: exclude_git_http_from_web_rate_limiter +description: +feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/581142 +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/213141 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/581527 +milestone: '18.6' +group: group::source code +type: gitlab_com_derisk +default_enabled: false diff --git a/lib/gitlab/rack_attack/request.rb b/lib/gitlab/rack_attack/request.rb index fc1a50a78290ff..283772948e0a22 100644 --- a/lib/gitlab/rack_attack/request.rb +++ b/lib/gitlab/rack_attack/request.rb @@ -116,6 +116,7 @@ def throttle_authenticated_api? def throttle_authenticated_web? (web_request? || frontend_request?) && !throttle_authenticated_git_lfs? && + !(git_path? && !git_lfs_path? && Feature.enabled?(:exclude_git_http_from_web_rate_limiter, :instance)) && Gitlab::Throttle.settings.throttle_authenticated_web_enabled end diff --git a/spec/lib/gitlab/rack_attack/request_spec.rb b/spec/lib/gitlab/rack_attack/request_spec.rb index ce4ca9a1000d08..0de42dd42c0f56 100644 --- a/spec/lib/gitlab/rack_attack/request_spec.rb +++ b/spec/lib/gitlab/rack_attack/request_spec.rb @@ -218,6 +218,79 @@ end end + describe '#throttle_authenticated_web?' do + let_it_be(:project) { create(:project) } + + let(:git_info_refs_path) { "/#{project.full_path}.git/info/refs?service=git-upload-pack" } + let(:git_lfs_path) { "/#{project.full_path}.git/info/lfs/objects/batch" } + let(:web_path) { '/users/sign_in' } + + subject { request.throttle_authenticated_web? } + + where(:path, :throttle_authenticated_web_enabled, :throttle_authenticated_git_lfs_enabled, :expected) do + ref(:web_path) | true | false | true + ref(:web_path) | false | false | false + ref(:web_path) | true | true | true + ref(:web_path) | false | true | false + + # Git HTTP paths are always excluded regardless of settings + ref(:git_info_refs_path) | true | false | false + ref(:git_info_refs_path) | false | false | false + ref(:git_info_refs_path) | true | true | false + ref(:git_info_refs_path) | false | true | false + + # Git LFS paths are excluded when LFS throttle is enabled + ref(:git_lfs_path) | true | true | false + ref(:git_lfs_path) | false | true | false + ref(:git_lfs_path) | true | false | true + ref(:git_lfs_path) | false | false | false + end + + with_them do + before do + stub_application_setting( + throttle_authenticated_web_enabled: throttle_authenticated_web_enabled, + throttle_authenticated_git_lfs_enabled: throttle_authenticated_git_lfs_enabled + ) + end + + it { is_expected.to eq expected } + end + + context 'when exclude_git_http_from_web_rate_limiter is disabled' do + where(:path, :throttle_authenticated_web_enabled, :throttle_authenticated_git_lfs_enabled, :expected) do + ref(:web_path) | true | false | true + ref(:web_path) | false | false | false + ref(:web_path) | true | true | true + ref(:web_path) | false | true | false + + # Git HTTP paths are not excluded from web rate limiter + ref(:git_info_refs_path) | true | false | true + ref(:git_info_refs_path) | false | false | false + ref(:git_info_refs_path) | true | true | true + ref(:git_info_refs_path) | false | true | false + + # Git LFS paths are excluded when LFS throttle is enabled + ref(:git_lfs_path) | true | true | false + ref(:git_lfs_path) | false | true | false + ref(:git_lfs_path) | true | false | true + ref(:git_lfs_path) | false | false | false + end + + with_them do + before do + stub_feature_flags(exclude_git_http_from_web_rate_limiter: false) + stub_application_setting( + throttle_authenticated_web_enabled: throttle_authenticated_web_enabled, + throttle_authenticated_git_lfs_enabled: throttle_authenticated_git_lfs_enabled + ) + end + + it { is_expected.to eq expected } + end + end + end + describe '#throttle_unauthenticated_git_http?' do let_it_be(:project) { create(:project) } -- GitLab