diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/api/ci/pipeline_schedules.rb | 2 | ||||
-rw-r--r-- | lib/api/helpers/packages/conan/api_helpers.rb | 26 | ||||
-rw-r--r-- | lib/api/pypi_packages.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/auth/request_authenticator.rb | 7 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/chain/helpers.rb | 11 | ||||
-rw-r--r-- | lib/gitlab/ci/pipeline/chain/validate/abilities.rb | 2 | ||||
-rw-r--r-- | lib/gitlab/conan_token.rb | 4 | ||||
-rw-r--r-- | lib/gitlab/git_access_wiki.rb | 14 | ||||
-rw-r--r-- | lib/gitlab/import_export/project/import_export.yml | 1 | ||||
-rw-r--r-- | lib/gitlab/import_export/project/relation_factory.rb | 6 | ||||
-rw-r--r-- | lib/gitlab/markdown_cache.rb | 4 | ||||
-rw-r--r-- | lib/gitlab/metrics/subscribers/rack_attack.rb | 12 | ||||
-rw-r--r-- | lib/gitlab/rack_attack.rb | 10 | ||||
-rw-r--r-- | lib/gitlab/rack_attack/request.rb | 28 | ||||
-rw-r--r-- | lib/gitlab/regex.rb | 4 |
15 files changed, 99 insertions, 34 deletions
diff --git a/lib/api/ci/pipeline_schedules.rb b/lib/api/ci/pipeline_schedules.rb index 8a9ba2cbe0f..6030fe86f00 100644 --- a/lib/api/ci/pipeline_schedules.rb +++ b/lib/api/ci/pipeline_schedules.rb @@ -93,7 +93,7 @@ module API requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' end post ':id/pipeline_schedules/:pipeline_schedule_id/take_ownership' do - authorize! :update_pipeline_schedule, pipeline_schedule + authorize! :take_ownership_pipeline_schedule, pipeline_schedule if pipeline_schedule.own!(current_user) present pipeline_schedule, with: Entities::Ci::PipelineScheduleDetails diff --git a/lib/api/helpers/packages/conan/api_helpers.rb b/lib/api/helpers/packages/conan/api_helpers.rb index e92547890e8..994d3c4c473 100644 --- a/lib/api/helpers/packages/conan/api_helpers.rb +++ b/lib/api/helpers/packages/conan/api_helpers.rb @@ -153,7 +153,7 @@ module API def token strong_memoize(:token) do token = nil - token = ::Gitlab::ConanToken.from_personal_access_token(access_token) if access_token + token = ::Gitlab::ConanToken.from_personal_access_token(find_personal_access_token.user_id, access_token_from_request) if find_personal_access_token token = ::Gitlab::ConanToken.from_deploy_token(deploy_token_from_request) if deploy_token_from_request token = ::Gitlab::ConanToken.from_job(find_job_from_token) if find_job_from_token token @@ -224,9 +224,27 @@ module API forbidden! end + # We override this method from auth_finders because we need to + # extract the token from the Conan JWT which is specific to the Conan API def find_personal_access_token - find_personal_access_token_from_conan_jwt || - find_personal_access_token_from_http_basic_auth + strong_memoize(:find_personal_access_token) do + PersonalAccessToken.find_by_token(access_token_from_request) + end + end + + def access_token_from_request + strong_memoize(:access_token_from_request) do + find_personal_access_token_from_conan_jwt || + find_password_from_basic_auth + end + end + + def find_password_from_basic_auth + return unless route_authentication_setting[:basic_auth_personal_access_token] + return unless has_basic_credentials?(current_request) + + _username, password = user_name_and_password(current_request) + password end def find_user_from_job_token @@ -256,7 +274,7 @@ module API return unless token - PersonalAccessToken.find_by_id_and_user_id(token.access_token_id, token.user_id) + token.access_token_id end def find_deploy_token_from_conan_jwt diff --git a/lib/api/pypi_packages.rb b/lib/api/pypi_packages.rb index 706c0702fce..6f308b2aca0 100644 --- a/lib/api/pypi_packages.rb +++ b/lib/api/pypi_packages.rb @@ -174,7 +174,7 @@ module API requires :name, type: String requires :version, type: String optional :md5_digest, type: String - optional :sha256_digest, type: String + optional :sha256_digest, type: String, regexp: Gitlab::Regex.sha256_regex end route_setting :authentication, deploy_token_allowed: true, basic_auth_personal_access_token: true, job_token_allowed: :basic_auth diff --git a/lib/gitlab/auth/request_authenticator.rb b/lib/gitlab/auth/request_authenticator.rb index b6ed6bbf2df..ea9626d7f5c 100644 --- a/lib/gitlab/auth/request_authenticator.rb +++ b/lib/gitlab/auth/request_authenticator.rb @@ -13,6 +13,10 @@ module Gitlab @request = request end + def find_authenticated_requester(request_formats) + user(request_formats) || deploy_token_from_request + end + def user(request_formats) request_formats.each do |format| user = find_sessionless_user(format) @@ -80,7 +84,8 @@ module Gitlab def route_authentication_setting @route_authentication_setting ||= { job_token_allowed: api_request?, - basic_auth_personal_access_token: api_request? || git_request? + basic_auth_personal_access_token: api_request? || git_request?, + deploy_token_allowed: api_request? || git_request? } end diff --git a/lib/gitlab/ci/pipeline/chain/helpers.rb b/lib/gitlab/ci/pipeline/chain/helpers.rb index 09158bf8bfd..343a189f773 100644 --- a/lib/gitlab/ci/pipeline/chain/helpers.rb +++ b/lib/gitlab/ci/pipeline/chain/helpers.rb @@ -6,25 +6,28 @@ module Gitlab module Chain module Helpers def error(message, config_error: false, drop_reason: nil) + sanitized_message = ActionController::Base.helpers.sanitize(message, tags: []) + if config_error drop_reason = :config_error - pipeline.yaml_errors = message + pipeline.yaml_errors = sanitized_message end - pipeline.add_error_message(message) + pipeline.add_error_message(sanitized_message) drop_pipeline!(drop_reason) # TODO: consider not to rely on AR errors directly as they can be # polluted with other unrelated errors (e.g. state machine) # https://gitlab.com/gitlab-org/gitlab/-/issues/220823 - pipeline.errors.add(:base, message) + pipeline.errors.add(:base, sanitized_message) pipeline.errors.full_messages end def warning(message) - pipeline.add_warning_message(message) + sanitized_message = ActionController::Base.helpers.sanitize(message, tags: []) + pipeline.add_warning_message(sanitized_message) end private diff --git a/lib/gitlab/ci/pipeline/chain/validate/abilities.rb b/lib/gitlab/ci/pipeline/chain/validate/abilities.rb index 1c1f7abb6f6..035167f1a74 100644 --- a/lib/gitlab/ci/pipeline/chain/validate/abilities.rb +++ b/lib/gitlab/ci/pipeline/chain/validate/abilities.rb @@ -23,7 +23,7 @@ module Gitlab end unless allowed_to_write_ref? - error("You do not have sufficient permission to run a pipeline on '#{command.ref}'. Please select a different branch or contact your administrator for assistance. <a href=https://docs.gitlab.com/ee/ci/pipelines/#pipeline-security-on-protected-branches>Learn more</a>".html_safe) + error("You do not have sufficient permission to run a pipeline on '#{command.ref}'. Please select a different branch or contact your administrator for assistance.") end end diff --git a/lib/gitlab/conan_token.rb b/lib/gitlab/conan_token.rb index d0560807f45..87a085461bc 100644 --- a/lib/gitlab/conan_token.rb +++ b/lib/gitlab/conan_token.rb @@ -13,8 +13,8 @@ module Gitlab attr_reader :access_token_id, :user_id class << self - def from_personal_access_token(access_token) - new(access_token_id: access_token.id, user_id: access_token.user_id) + def from_personal_access_token(user_id, token) + new(access_token_id: token, user_id: user_id) end def from_job(job) diff --git a/lib/gitlab/git_access_wiki.rb b/lib/gitlab/git_access_wiki.rb index f8f61511265..fdd7e8a8c4a 100644 --- a/lib/gitlab/git_access_wiki.rb +++ b/lib/gitlab/git_access_wiki.rb @@ -31,7 +31,8 @@ module Gitlab def check_download_access! super - raise ForbiddenError, download_forbidden_message if deploy_token && !deploy_token.can?(:download_wiki_code, container) + raise ForbiddenError, download_forbidden_message if build_cannot_download? + raise ForbiddenError, download_forbidden_message if deploy_token_cannot_download? end override :check_change_access! @@ -52,6 +53,17 @@ module Gitlab def not_found_message error_message(:not_found) end + + private + + # when accessing via the CI_JOB_TOKEN + def build_cannot_download? + build_can_download_code? && !user_access.can_do_action?(download_ability) + end + + def deploy_token_cannot_download? + deploy_token && !deploy_token.can?(download_ability, container) + end end end diff --git a/lib/gitlab/import_export/project/import_export.yml b/lib/gitlab/import_export/project/import_export.yml index 059f6bd42e3..6f64bf741a5 100644 --- a/lib/gitlab/import_export/project/import_export.yml +++ b/lib/gitlab/import_export/project/import_export.yml @@ -638,7 +638,6 @@ included_attributes: - :build_allow_git_fetch - :build_coverage_regex - :build_timeout - - :ci_config_path - :delete_error - :description - :disable_overriding_approvers_per_merge_request diff --git a/lib/gitlab/import_export/project/relation_factory.rb b/lib/gitlab/import_export/project/relation_factory.rb index c391f86b47b..8110720fb46 100644 --- a/lib/gitlab/import_export/project/relation_factory.rb +++ b/lib/gitlab/import_export/project/relation_factory.rb @@ -87,6 +87,8 @@ module Gitlab when *BUILD_MODELS then setup_build when :issues then setup_issue when :'Ci::PipelineSchedule' then setup_pipeline_schedule + when :'ProtectedBranch::MergeAccessLevel' then setup_protected_branch_access_level + when :'ProtectedBranch::PushAccessLevel' then setup_protected_branch_access_level end update_project_references @@ -152,6 +154,10 @@ module Gitlab @relation_hash['active'] = false end + def setup_protected_branch_access_level + @relation_hash['access_level'] = Gitlab::Access::MAINTAINER + end + def compute_relative_position return unless max_relative_position diff --git a/lib/gitlab/markdown_cache.rb b/lib/gitlab/markdown_cache.rb index d6371732624..283502d90c1 100644 --- a/lib/gitlab/markdown_cache.rb +++ b/lib/gitlab/markdown_cache.rb @@ -11,8 +11,8 @@ module Gitlab # this if the change to the renderer output is a new feature or a # minor bug fix. # See: https://gitlab.com/gitlab-org/gitlab/-/issues/330313 - CACHE_COMMONMARK_VERSION = 29 - CACHE_COMMONMARK_VERSION_START = 10 + CACHE_COMMONMARK_VERSION = 30 + CACHE_COMMONMARK_VERSION_START = 10 BaseError = Class.new(StandardError) UnsupportedClassError = Class.new(BaseError) diff --git a/lib/gitlab/metrics/subscribers/rack_attack.rb b/lib/gitlab/metrics/subscribers/rack_attack.rb index d86c0f83c6c..70dcc6fad90 100644 --- a/lib/gitlab/metrics/subscribers/rack_attack.rb +++ b/lib/gitlab/metrics/subscribers/rack_attack.rb @@ -73,12 +73,16 @@ module Gitlab matched: req.env['rack.attack.matched'] } - if THROTTLES_WITH_USER_INFORMATION.include? req.env['rack.attack.matched'].to_sym - user_id = req.env['rack.attack.match_discriminator'] - user = User.find_by(id: user_id) # rubocop:disable CodeReuse/ActiveRecord + discriminator = req.env['rack.attack.match_discriminator'].to_s + discriminator_id = discriminator.split(':').last - rack_attack_info[:user_id] = user_id + if discriminator.starts_with?('user:') + user = User.find_by(id: discriminator_id) # rubocop:disable CodeReuse/ActiveRecord + + rack_attack_info[:user_id] = discriminator_id.to_i rack_attack_info['meta.user'] = user.username unless user.nil? + elsif discriminator.starts_with?('deploy_token:') + rack_attack_info[:deploy_token_id] = discriminator_id.to_i end Gitlab::InstrumentationHelper.add_instrumentation_data(rack_attack_info) diff --git a/lib/gitlab/rack_attack.rb b/lib/gitlab/rack_attack.rb index 3f4c0fa45aa..b2664f87306 100644 --- a/lib/gitlab/rack_attack.rb +++ b/lib/gitlab/rack_attack.rb @@ -95,7 +95,7 @@ module Gitlab authenticated_options = Gitlab::Throttle.options(throttle, authenticated: true) throttle_or_track(rack_attack, "throttle_authenticated_#{throttle}", authenticated_options) do |req| if req.throttle?(throttle, authenticated: true) - req.throttled_user_id([:api]) + req.throttled_identifer([:api]) end end end @@ -117,7 +117,7 @@ module Gitlab throttle_or_track(rack_attack, 'throttle_authenticated_web', Gitlab::Throttle.authenticated_web_options) do |req| if req.throttle_authenticated_web? - req.throttled_user_id([:api, :rss, :ics]) + req.throttled_identifer([:api, :rss, :ics]) end end @@ -129,19 +129,19 @@ module Gitlab throttle_or_track(rack_attack, 'throttle_authenticated_protected_paths_api', Gitlab::Throttle.protected_paths_options) do |req| if req.throttle_authenticated_protected_paths_api? - req.throttled_user_id([:api]) + req.throttled_identifer([:api]) end end throttle_or_track(rack_attack, 'throttle_authenticated_protected_paths_web', Gitlab::Throttle.protected_paths_options) do |req| if req.throttle_authenticated_protected_paths_web? - req.throttled_user_id([:api, :rss, :ics]) + req.throttled_identifer([:api, :rss, :ics]) end end throttle_or_track(rack_attack, 'throttle_authenticated_git_lfs', Gitlab::Throttle.throttle_authenticated_git_lfs_options) do |req| if req.throttle_authenticated_git_lfs? - req.throttled_user_id([:api]) + req.throttled_identifer([:api]) end end diff --git a/lib/gitlab/rack_attack/request.rb b/lib/gitlab/rack_attack/request.rb index b24afd28dd7..08a5ddb6ad1 100644 --- a/lib/gitlab/rack_attack/request.rb +++ b/lib/gitlab/rack_attack/request.rb @@ -9,18 +9,22 @@ module Gitlab GROUP_PATH_REGEX = %r{^/api/v\d+/groups/[^/]+/?$}.freeze def unauthenticated? - !(authenticated_user_id([:api, :rss, :ics]) || authenticated_runner_id) + !(authenticated_identifier([:api, :rss, :ics]) || authenticated_runner_id) end - def throttled_user_id(request_formats) - user_id = authenticated_user_id(request_formats) + def throttled_identifer(request_formats) + identifier = authenticated_identifier(request_formats) + return unless identifier - if Gitlab::RackAttack.user_allowlist.include?(user_id) + identifier_type = identifier[:identifier_type] + identifier_id = identifier[:identifier_id] + + if identifier_type == :user && Gitlab::RackAttack.user_allowlist.include?(identifier_id) Gitlab::Instrumentation::Throttle.safelist = 'throttle_user_allowlist' return end - user_id + "#{identifier_type}:#{identifier_id}" end def authenticated_runner_id @@ -169,8 +173,18 @@ module Gitlab private - def authenticated_user_id(request_formats) - request_authenticator.user(request_formats)&.id + def authenticated_identifier(request_formats) + requester = request_authenticator.find_authenticated_requester(request_formats) + + return unless requester + + identifier_type = if requester.is_a?(DeployToken) + :deploy_token + else + :user + end + + { identifier_type: identifier_type, identifier_id: requester.id } end def request_authenticator diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb index a6491d23bf5..7b3590e8707 100644 --- a/lib/gitlab/regex.rb +++ b/lib/gitlab/regex.rb @@ -237,6 +237,10 @@ module Gitlab generic_package_name_regex end + def sha256_regex + @sha256_regex ||= /\A[0-9a-f]{64}\z/i.freeze + end + private def conan_name_regex |