New upstream version 14.9.5+ds1

This commit is contained in:
Pirate Praveen 2022-06-02 21:05:25 +05:30
parent 514ffadb92
commit cee083333e
25 changed files with 173 additions and 37 deletions

View file

@ -280,7 +280,9 @@ coverage-frontend:
paths: paths:
- coverage-frontend/ - coverage-frontend/
reports: reports:
cobertura: coverage-frontend/cobertura-coverage.xml coverage_report:
coverage_format: cobertura
path: coverage-frontend/cobertura-coverage.xml
.qa-frontend-node: .qa-frontend-node:
extends: extends:

View file

@ -602,7 +602,9 @@ rspec:coverage:
- coverage/assets/ - coverage/assets/
- coverage/lcov/ - coverage/lcov/
reports: reports:
cobertura: coverage/coverage.xml coverage_report:
coverage_format: cobertura
path: coverage/coverage.xml
rspec:undercoverage: rspec:undercoverage:
extends: extends:

View file

@ -87,12 +87,6 @@ gemnasium-dependency_scanning:
- apk add git-lfs - apk add git-lfs
rules: !reference [".reports:rules:gemnasium-dependency_scanning", rules] rules: !reference [".reports:rules:gemnasium-dependency_scanning", rules]
bundler-audit-dependency_scanning:
rules: !reference [".reports:rules:bundler-audit-dependency_scanning", rules]
retire-js-dependency_scanning:
rules: !reference [".reports:rules:retire-js-dependency_scanning", rules]
gemnasium-python-dependency_scanning: gemnasium-python-dependency_scanning:
rules: !reference [".reports:rules:gemnasium-python-dependency_scanning", rules] rules: !reference [".reports:rules:gemnasium-python-dependency_scanning", rules]

View file

@ -77,7 +77,7 @@ review-build-cng:
variables: variables:
HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}" HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}"
DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}" DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}"
GITLAB_HELM_CHART_REF: "v5.5.0" GITLAB_HELM_CHART_REF: "41d7632d9eba84f5816d808b98ccf3f5623e9fb5"
environment: environment:
name: review/${CI_COMMIT_REF_SLUG}${FREQUENCY} name: review/${CI_COMMIT_REF_SLUG}${FREQUENCY}
url: https://gitlab-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN} url: https://gitlab-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}

View file

@ -1450,18 +1450,6 @@
when: never when: never
- changes: *dependency-patterns - changes: *dependency-patterns
.reports:rules:bundler-audit-dependency_scanning:
rules:
- if: '$DEPENDENCY_SCANNING_DISABLED || $GITLAB_FEATURES !~ /\bdependency_scanning\b/ || $DS_EXCLUDED_ANALYZERS =~ /bundler-audit/ || $DS_DEFAULT_ANALYZERS !~ /bundler-audit/'
when: never
- changes: *bundler-patterns
.reports:rules:retire-js-dependency_scanning:
rules:
- if: '$DEPENDENCY_SCANNING_DISABLED || $GITLAB_FEATURES !~ /\bdependency_scanning\b/ || $DS_EXCLUDED_ANALYZERS =~ /retire.js/ || $DS_DEFAULT_ANALYZERS !~ /retire.js/'
when: never
- changes: *nodejs-patterns
.reports:rules:gemnasium-python-dependency_scanning: .reports:rules:gemnasium-python-dependency_scanning:
rules: rules:
- if: '$DEPENDENCY_SCANNING_DISABLED || $GITLAB_FEATURES !~ /\bdependency_scanning\b/ || $DS_EXCLUDED_ANALYZERS =~ /gemnasium-python/ || $DS_DEFAULT_ANALYZERS !~ /gemnasium-python/' - if: '$DEPENDENCY_SCANNING_DISABLED || $GITLAB_FEATURES !~ /\bdependency_scanning\b/ || $DS_EXCLUDED_ANALYZERS =~ /gemnasium-python/ || $DS_DEFAULT_ANALYZERS !~ /gemnasium-python/'

View file

@ -2,6 +2,18 @@
documentation](doc/development/changelog.md) for instructions on adding your own documentation](doc/development/changelog.md) for instructions on adding your own
entry. entry.
## 14.9.5 (2022-06-01)
### Security (7 changes)
- [Fix IP restrictions not applying to deploy tokens](gitlab-org/security/gitlab@b429997e253110ea5eb4d20a8b90e9879be97300) ([merge request](gitlab-org/security/gitlab!2472))
- [Trigger token should respect group IP restrictions](gitlab-org/security/gitlab@326993794bba8659208cde212433a5a19fd3e5a9) ([merge request](gitlab-org/security/gitlab!2477))
- [Fix content injection in Jira issue title](gitlab-org/security/gitlab@c968f7be35d829bfefbf089794343d2d20cdd078) ([merge request](gitlab-org/security/gitlab!2465))
- [Subgroup member can list members of parent group](gitlab-org/security/gitlab@1606689819eeae574bd5d65c8c971c2d4eb19e41) ([merge request](gitlab-org/security/gitlab!2481))
- [Do not allow project member import when membership is locked](gitlab-org/security/gitlab@e8324068c61c4c58d50646d4fa8dff77c4d147ae) ([merge request](gitlab-org/security/gitlab!2448))
- [Disable changing user attributes when updating SCIM provisioned user](gitlab-org/security/gitlab@9d5aca002edb2e0ab3c7d5b6eb00ea781d3dde9f) ([merge request](gitlab-org/security/gitlab!2455))
- [Allow only job owner to run interactive terminal](gitlab-org/security/gitlab@c9fe31e3a963c421db3d9c47c65dd98a2867a699) ([merge request](gitlab-org/security/gitlab!2434))
## 14.9.4 (2022-04-29) ## 14.9.4 (2022-04-29)
### Security (15 changes) ### Security (15 changes)

View file

@ -1 +1 @@
14.9.4 14.9.5

View file

@ -1 +1 @@
14.9.4 14.9.5

View file

@ -67,6 +67,12 @@ class Groups::ApplicationController < ApplicationController
end end
end end
def authorize_read_group_member!
unless can?(current_user, :read_group_member, group)
render_403
end
end
def build_canonical_path(group) def build_canonical_path(group)
params[:group_id] = group.to_param params[:group_id] = group.to_param

View file

@ -14,6 +14,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
# Authorize # Authorize
before_action :authorize_admin_group_member!, except: admin_not_required_endpoints before_action :authorize_admin_group_member!, except: admin_not_required_endpoints
before_action :authorize_read_group_member!, only: :index
skip_before_action :check_two_factor_requirement, only: :leave skip_before_action :check_two_factor_requirement, only: :leave
skip_cross_project_access_check :index, :update, :destroy, :request_access, skip_cross_project_access_check :index, :update, :destroy, :request_access,

View file

@ -84,7 +84,7 @@ module Ci
enable :update_commit_status enable :update_commit_status
end end
rule { can?(:update_build) & terminal }.enable :create_build_terminal rule { can?(:update_build) & terminal & owner_of_job }.enable :create_build_terminal
rule { can?(:update_build) }.enable :play_job rule { can?(:update_build) }.enable :play_job

View file

@ -22,6 +22,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
condition(:share_with_group_locked, scope: :subject) { @subject.share_with_group_lock? } condition(:share_with_group_locked, scope: :subject) { @subject.share_with_group_lock? }
condition(:parent_share_with_group_locked, scope: :subject) { @subject.parent&.share_with_group_lock? } condition(:parent_share_with_group_locked, scope: :subject) { @subject.parent&.share_with_group_lock? }
condition(:can_change_parent_share_with_group_lock) { can?(:change_share_with_group_lock, @subject.parent) } condition(:can_change_parent_share_with_group_lock) { can?(:change_share_with_group_lock, @subject.parent) }
condition(:can_read_group_member) { can_read_group_member? }
desc "User is a project bot" desc "User is a project bot"
condition(:project_bot) { user.project_bot? && access_level >= GroupMember::GUEST } condition(:project_bot) { user.project_bot? && access_level >= GroupMember::GUEST }
@ -127,6 +128,10 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
rule { ~public_group & ~has_access }.prevent :read_counts rule { ~public_group & ~has_access }.prevent :read_counts
rule { ~can_read_group_member }.policy do
prevent :read_group_member
end
rule { ~can?(:read_group) }.policy do rule { ~can?(:read_group) }.policy do
prevent :read_design_activity prevent :read_design_activity
end end
@ -308,6 +313,10 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
true true
end end
def can_read_group_member?
!(@subject.private? && access_level == GroupMember::NO_ACCESS)
end
def resource_access_token_creation_allowed? def resource_access_token_creation_allowed?
resource_access_token_feature_available? && group.root_ancestor.namespace_settings.resource_access_token_creation_allowed? resource_access_token_feature_available? && group.root_ancestor.namespace_settings.resource_access_token_creation_allowed?
end end

View file

@ -744,6 +744,10 @@ class ProjectPolicy < BasePolicy
prevent :register_project_runners prevent :register_project_runners
end end
rule { can?(:admin_project_member) }.policy do
enable :import_project_members_from_another_project
end
private private
def user_is_user? def user_is_user?

View file

@ -26,6 +26,7 @@ module Ci
def create_pipeline_from_trigger(trigger) def create_pipeline_from_trigger(trigger)
# this check is to not leak the presence of the project if user cannot read it # this check is to not leak the presence of the project if user cannot read it
return unless trigger.project == project return unless trigger.project == project
return unless can?(trigger.owner, :read_project, project)
response = Ci::CreatePipelineService response = Ci::CreatePipelineService
.new(project, trigger.owner, ref: params[:ref], variables_attributes: variables) .new(project, trigger.owner, ref: params[:ref], variables_attributes: variables)

View file

@ -29,7 +29,7 @@ module Members
def import_project_team def import_project_team
return false unless target_project.present? && source_project.present? && current_user.present? return false unless target_project.present? && source_project.present? && current_user.present?
return false unless can?(current_user, :read_project_member, source_project) return false unless can?(current_user, :read_project_member, source_project)
return false unless can?(current_user, :admin_project_member, target_project) return false unless can?(current_user, :import_project_members_from_another_project, target_project)
target_project.team.import(source_project, current_user) target_project.team.import(source_project, current_user)
end end

View file

@ -170,13 +170,13 @@ Returns a `201` status code if successful.
Fields that can be updated are: Fields that can be updated are:
| SCIM/IdP field | GitLab field | | SCIM/IdP field | GitLab field |
|:---------------------------------|:---------------------------------------| |:---------------------------------|:-----------------------------------------------------------------------------|
| `id/externalId` | `extern_uid` | | `id/externalId` | `extern_uid` |
| `name.formatted` | `name` | | `name.formatted` | `name` ([Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/363058)) |
| `emails\[type eq "work"\].value` | `email` | | `emails\[type eq "work"\].value` | `email` ([Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/363058)) |
| `active` | Identity removal if `active` = `false` | | `active` | Identity removal if `active` = `false` |
| `userName` | `username` | | `userName` | `username` ([Removed](https://gitlab.com/gitlab-org/gitlab/-/issues/363058)) |
```plaintext ```plaintext
PATCH /api/scim/v2/groups/:group_path/Users/:id PATCH /api/scim/v2/groups/:group_path/Users/:id

View file

@ -86,6 +86,9 @@ For more information, view the [permissions table](../../permissions.md#group-me
## Subgroup membership ## Subgroup membership
NOTE:
There is a bug that causes some pages in the parent group to be accessible by subgroup members. For more details, see [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/340421).
When you add a member to a group, that member is also added to all subgroups. The user's permissions are inherited from When you add a member to a group, that member is also added to all subgroups. The user's permissions are inherited from
the group's parent. the group's parent.

View file

@ -15,6 +15,10 @@ module API
public_send("find_#{source_type}!", id) # rubocop:disable GitlabSecurity/PublicSend public_send("find_#{source_type}!", id) # rubocop:disable GitlabSecurity/PublicSend
end end
def authorize_read_source_member!(source_type, source)
authorize! :"read_#{source_type}_member", source
end
def authorize_admin_source!(source_type, source) def authorize_admin_source!(source_type, source)
authorize! :"admin_#{source_type}", source authorize! :"admin_#{source_type}", source
end end

View file

@ -29,6 +29,8 @@ module API
get ":id/members" do get ":id/members" do
source = find_source(source_type, params[:id]) source = find_source(source_type, params[:id])
authorize_read_source_member!(source_type, source)
members = paginate(retrieve_members(source, params: params)) members = paginate(retrieve_members(source, params: params))
present_members members present_members members
@ -48,6 +50,8 @@ module API
get ":id/members/all" do get ":id/members/all" do
source = find_source(source_type, params[:id]) source = find_source(source_type, params[:id])
authorize_read_source_member!(source_type, source)
members = paginate(retrieve_members(source, params: params, deep: true)) members = paginate(retrieve_members(source, params: params, deep: true))
present_members members present_members members
@ -63,6 +67,8 @@ module API
get ":id/members/:user_id" do get ":id/members/:user_id" do
source = find_source(source_type, params[:id]) source = find_source(source_type, params[:id])
authorize_read_source_member!(source_type, source)
members = source_members(source) members = source_members(source)
member = members.find_by!(user_id: params[:user_id]) member = members.find_by!(user_id: params[:user_id])
@ -80,6 +86,8 @@ module API
get ":id/members/all/:user_id" do get ":id/members/all/:user_id" do
source = find_source(source_type, params[:id]) source = find_source(source_type, params[:id])
authorize_read_source_member!(source_type, source)
members = find_all_members(source) members = find_all_members(source)
member = members.find_by!(user_id: params[:user_id]) member = members.find_by!(user_id: params[:user_id])

View file

@ -183,7 +183,7 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
end end
context 'with web terminal' do context 'with web terminal' do
let(:job) { create(:ci_build, :running, :with_runner_session, pipeline: pipeline) } let(:job) { create(:ci_build, :running, :with_runner_session, pipeline: pipeline, user: user) }
it 'exposes the terminal path' do it 'exposes the terminal path' do
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
@ -1284,7 +1284,7 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
context 'when job exists' do context 'when job exists' do
context 'and it has a terminal' do context 'and it has a terminal' do
let!(:job) { create(:ci_build, :running, :with_runner_session, pipeline: pipeline) } let!(:job) { create(:ci_build, :running, :with_runner_session, pipeline: pipeline, user: user) }
it 'has a job' do it 'has a job' do
get_terminal(id: job.id) get_terminal(id: job.id)
@ -1295,7 +1295,7 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
end end
context 'and does not have a terminal' do context 'and does not have a terminal' do
let!(:job) { create(:ci_build, :running, pipeline: pipeline) } let!(:job) { create(:ci_build, :running, pipeline: pipeline, user: user) }
it 'returns not_found' do it 'returns not_found' do
get_terminal(id: job.id) get_terminal(id: job.id)
@ -1324,7 +1324,7 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
end end
describe 'GET #terminal_websocket_authorize' do describe 'GET #terminal_websocket_authorize' do
let!(:job) { create(:ci_build, :running, :with_runner_session, pipeline: pipeline) } let!(:job) { create(:ci_build, :running, :with_runner_session, pipeline: pipeline, user: user) }
before do before do
project.add_developer(user) project.add_developer(user)

View file

@ -97,7 +97,7 @@ RSpec.describe 'Private Group access' do
it { is_expected.to be_allowed_for(:developer).of(group) } it { is_expected.to be_allowed_for(:developer).of(group) }
it { is_expected.to be_allowed_for(:reporter).of(group) } it { is_expected.to be_allowed_for(:reporter).of(group) }
it { is_expected.to be_allowed_for(:guest).of(group) } it { is_expected.to be_allowed_for(:guest).of(group) }
it { is_expected.to be_allowed_for(project_guest) } it { is_expected.to be_denied_for(project_guest) }
it { is_expected.to be_denied_for(:user) } it { is_expected.to be_denied_for(:user) }
it { is_expected.to be_denied_for(:external) } it { is_expected.to be_denied_for(:external) }
it { is_expected.to be_denied_for(:visitor) } it { is_expected.to be_denied_for(:visitor) }

View file

@ -405,4 +405,52 @@ RSpec.describe Ci::BuildPolicy do
end end
end end
end end
describe 'ability :create_build_terminal' do
let(:project) { create(:project, :private) }
subject { described_class.new(user, build) }
context 'when user can update_build' do
before do
project.add_maintainer(user)
end
context 'when job has terminal' do
before do
allow(build).to receive(:has_terminal?).and_return(true)
end
context 'when current user is the job owner' do
before do
build.update!(user: user)
end
it { expect_allowed(:create_build_terminal) }
end
context 'when current user is not the job owner' do
it { expect_disallowed(:create_build_terminal) }
end
end
context 'when job does not have terminal' do
before do
allow(build).to receive(:has_terminal?).and_return(false)
build.update!(user: user)
end
it { expect_disallowed(:create_build_terminal) }
end
end
context 'when user cannot update build' do
before do
project.add_guest(user)
allow(build).to receive(:has_terminal?).and_return(true)
end
it { expect_disallowed(:create_build_terminal) }
end
end
end end

View file

@ -346,6 +346,36 @@ RSpec.describe ProjectPolicy do
end end
end end
context 'importing members from another project' do
%w(maintainer owner).each do |role|
context "with #{role}" do
let(:current_user) { send(role) }
it { is_expected.to be_allowed(:import_project_members_from_another_project) }
end
end
%w(guest reporter developer anonymous).each do |role|
context "with #{role}" do
let(:current_user) { send(role) }
it { is_expected.to be_disallowed(:import_project_members_from_another_project) }
end
end
context 'with an admin' do
let(:current_user) { admin }
context 'when admin mode is enabled', :enable_admin_mode do
it { expect_allowed(:import_project_members_from_another_project) }
end
context 'when admin mode is disabled' do
it { expect_disallowed(:import_project_members_from_another_project) }
end
end
end
it_behaves_like 'clusterable policies' do it_behaves_like 'clusterable policies' do
let_it_be(:clusterable) { create(:project, :repository) } let_it_be(:clusterable) { create(:project, :repository) }
let_it_be(:cluster) do let_it_be(:cluster) do

View file

@ -180,6 +180,21 @@ RSpec.describe API::Members do
expect(json_response).to be_an Array expect(json_response).to be_an Array
expect(json_response.map { |u| u['id'] }).to match_array [maintainer.id, developer.id, nested_user.id] expect(json_response.map { |u| u['id'] }).to match_array [maintainer.id, developer.id, nested_user.id]
end end
context 'with a subgroup' do
let(:group) { create(:group, :private)}
let(:subgroup) { create(:group, :private, parent: group)}
let(:project) { create(:project, group: subgroup) }
before do
subgroup.add_developer(developer)
end
it 'subgroup member cannot get parent group members list' do
get api("/groups/#{group.id}/members/all", developer)
expect(response).to have_gitlab_http_status(:forbidden)
end
end
end end
shared_examples 'GET /:source_type/:id/members/(all/):user_id' do |source_type, all| shared_examples 'GET /:source_type/:id/members/(all/):user_id' do |source_type, all|

View file

@ -56,6 +56,15 @@ RSpec.describe Ci::PipelineTriggerService do
end end
end end
context 'when trigger owner does not have a permission to read a project' do
let(:params) { { token: trigger.token, ref: 'master', variables: nil } }
let(:trigger) { create(:ci_trigger, project: project, owner: create(:user)) }
it 'does nothing' do
expect { result }.not_to change { Ci::Pipeline.count }
end
end
context 'when params have an existing trigger token' do context 'when params have an existing trigger token' do
context 'when params have an existing ref' do context 'when params have an existing ref' do
let(:params) { { token: trigger.token, ref: 'master', variables: nil } } let(:params) { { token: trigger.token, ref: 'master', variables: nil } }