New upstream version 13.5.6

This commit is contained in:
Pirate Praveen 2021-01-08 16:13:35 +05:30
parent 30798b500b
commit 041695fe74
21 changed files with 196 additions and 16 deletions

View file

@ -2,6 +2,19 @@
documentation](doc/development/changelog.md) for instructions on adding your own documentation](doc/development/changelog.md) for instructions on adding your own
entry. entry.
## 13.5.6 (2021-01-07)
### Security (7 changes)
- Forbid public cache for private repos.
- Deny implicit flow for confidential apps.
- Update NuGet regular expression to protect against ReDoS.
- Fix regular expression backtracking issue in package name validation.
- Upgrade GitLab Pages to 1.28.2.
- Update trusted OAuth applications to set them as confidential.
- Upgrade Workhorse to 8.51.2.
## 13.5.5 (2020-12-07) ## 13.5.5 (2020-12-07)
### Security (10 changes) ### Security (10 changes)

View file

@ -1 +1 @@
13.5.5 13.5.6

View file

@ -1 +1 @@
1.28.0 1.28.2

View file

@ -1 +1 @@
8.51.0 8.51.2

View file

@ -1 +1 @@
13.5.5 13.5.6

View file

@ -24,6 +24,17 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
end end
end end
def create
# Confidential apps require the client_secret to be sent with the request.
# Doorkeeper allows implicit grant flow requests (response_type=token) to
# work without client_secret regardless of the confidential setting.
if pre_auth.authorizable? && pre_auth.response_type == 'token' && pre_auth.client.application.confidential
render "doorkeeper/authorizations/error"
else
super
end
end
private private
def verify_confirmed_email! def verify_confirmed_email!

View file

@ -20,7 +20,7 @@ class Projects::RawController < Projects::ApplicationController
def show def show
@blob = @repository.blob_at(@commit.id, @path) @blob = @repository.blob_at(@commit.id, @path)
send_blob(@repository, @blob, inline: (params[:inline] != 'false'), allow_caching: @project.public?) send_blob(@repository, @blob, inline: (params[:inline] != 'false'), allow_caching: Guest.can?(:download_code, @project))
end end
private private

View file

@ -51,7 +51,7 @@ class Projects::RepositoriesController < Projects::ApplicationController
end end
def set_cache_headers def set_cache_headers
expires_in cache_max_age(archive_metadata['CommitId']), public: project.public? expires_in cache_max_age(archive_metadata['CommitId']), public: Guest.can?(:download_code, project)
fresh_when(etag: archive_metadata['ArchivePath']) fresh_when(etag: archive_metadata['ArchivePath'])
end end

View file

@ -0,0 +1,23 @@
# frozen_string_literal: true
class UpdateTrustedAppsToConfidential < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
INDEX_NAME = 'tmp_index_oauth_applications_on_id_where_trusted'
disable_ddl_transaction!
def up
add_concurrent_index :oauth_applications, :id, where: 'trusted = true', name: INDEX_NAME
execute('UPDATE oauth_applications SET confidential = true WHERE trusted = true')
end
def down
# We won't be able to tell which trusted applications weren't confidential before the migration
# and setting all trusted applications are not confidential would introduce security issues
remove_concurrent_index_by_name :oauth_applications, INDEX_NAME
end
end

View file

@ -0,0 +1 @@
d3af120a74b4c55345ac7fb524395251cd3c1b3cd9685f711196a134f427845c

View file

@ -21962,6 +21962,8 @@ CREATE INDEX tmp_idx_index_issues_with_outdate_blocking_count ON issues USING bt
CREATE INDEX tmp_index_for_email_unconfirmation_migration ON emails USING btree (id) WHERE (confirmed_at IS NOT NULL); CREATE INDEX tmp_index_for_email_unconfirmation_migration ON emails USING btree (id) WHERE (confirmed_at IS NOT NULL);
CREATE INDEX tmp_index_oauth_applications_on_id_where_trusted ON oauth_applications USING btree (id) WHERE (trusted = true);
CREATE UNIQUE INDEX unique_merge_request_metrics_by_merge_request_id ON merge_request_metrics USING btree (merge_request_id); CREATE UNIQUE INDEX unique_merge_request_metrics_by_merge_request_id ON merge_request_metrics USING btree (merge_request_id);
CREATE UNIQUE INDEX users_security_dashboard_projects_unique_index ON users_security_dashboard_projects USING btree (project_id, user_id); CREATE UNIQUE INDEX users_security_dashboard_projects_unique_index ON users_security_dashboard_projects USING btree (project_id, user_id);

View file

@ -11,7 +11,7 @@ module API
helpers ::API::Helpers::Packages::BasicAuthHelpers helpers ::API::Helpers::Packages::BasicAuthHelpers
POSITIVE_INTEGER_REGEX = %r{\A[1-9]\d*\z}.freeze POSITIVE_INTEGER_REGEX = %r{\A[1-9]\d*\z}.freeze
NON_NEGATIVE_INTEGER_REGEX = %r{\A0|[1-9]\d*\z}.freeze NON_NEGATIVE_INTEGER_REGEX = %r{\A(0|[1-9]\d*)\z}.freeze
PACKAGE_FILENAME = 'package.nupkg' PACKAGE_FILENAME = 'package.nupkg'

View file

@ -23,7 +23,18 @@ module Gitlab
end end
def package_name_regex def package_name_regex
@package_name_regex ||= %r{\A\@?(([\w\-\.\+]*)\/)*([\w\-\.]+)@?(([\w\-\.\+]*)\/)*([\w\-\.]*)\z}.freeze @package_name_regex ||=
%r{
\A\@?
(?> # atomic group to prevent backtracking
(([\w\-\.\+]*)\/)*([\w\-\.]+)
)
@?
(?> # atomic group to prevent backtracking
(([\w\-\.\+]*)\/)*([\w\-\.]*)
)
\z
}x.freeze
end end
def maven_file_name_regex def maven_file_name_regex

View file

@ -180,12 +180,10 @@ module Gitlab
end end
def weekly_redis_keys(events:, start_date:, end_date:) def weekly_redis_keys(events:, start_date:, end_date:)
weeks = end_date.to_date.cweek - start_date.to_date.cweek end_date = end_date.end_of_week - 1.week
weeks = 1 if weeks == 0 (start_date.to_date..end_date.to_date).map do |date|
events.map { |event| redis_key(event, date) }
(0..(weeks - 1)).map do |week_increment| end.flatten.uniq
events.map { |event| redis_key(event, start_date + week_increment * 7.days) }
end.flatten
end end
end end
end end

View file

@ -95,6 +95,20 @@ RSpec.describe Oauth::AuthorizationsController do
subject { post :create, params: params } subject { post :create, params: params }
include_examples 'OAuth Authorizations require confirmed user' include_examples 'OAuth Authorizations require confirmed user'
context 'when application is confidential' do
before do
application.update(confidential: true)
params[:response_type] = 'token'
end
it 'does not allow the implicit flow' do
subject
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template('doorkeeper/authorizations/error')
end
end
end end
describe 'DELETE #destroy' do describe 'DELETE #destroy' do

View file

@ -225,6 +225,25 @@ RSpec.describe Projects::RawController do
end end
end end
end end
describe 'caching' do
def request_file
get(:show, params: { namespace_id: project.namespace, project_id: project, id: 'master/README.md' })
end
context 'when a public project has private repo' do
let(:project) { create(:project, :public, :repository, :repository_private) }
let(:user) { create(:user, maintainer_projects: [project]) }
it 'does not set public caching header' do
sign_in user
request_file
expect(response.cache_control[:public]).to eq(false)
expect(response.cache_control[:max_age]).to eq(60)
end
end
end
end end
def execute_raw_requests(requests:, project:, file_path:, **params) def execute_raw_requests(requests:, project:, file_path:, **params)

View file

@ -135,6 +135,18 @@ RSpec.describe Projects::RepositoriesController do
expect(response.header['ETag']).to be_present expect(response.header['ETag']).to be_present
expect(response.header['Cache-Control']).to include('max-age=60, public') expect(response.header['Cache-Control']).to include('max-age=60, public')
end end
context 'and repo is private' do
let(:project) { create(:project, :repository, :public, :repository_private) }
it 'sets appropriate caching headers' do
get_archive
expect(response).to have_gitlab_http_status(:ok)
expect(response.header['ETag']).to be_present
expect(response.header['Cache-Control']).to include('max-age=60, private')
end
end
end end
context 'when ref is a commit SHA' do context 'when ref is a commit SHA' do

View file

@ -283,6 +283,12 @@ RSpec.describe Gitlab::Regex do
it { is_expected.not_to match('my package name') } it { is_expected.not_to match('my package name') }
it { is_expected.not_to match('!!()()') } it { is_expected.not_to match('!!()()') }
it { is_expected.not_to match("..\n..\foo") } it { is_expected.not_to match("..\n..\foo") }
it 'has no backtracking issue' do
Timeout.timeout(1) do
expect(subject).not_to match("-" * 50000 + ";")
end
end
end end
describe '.maven_file_name_regex' do describe '.maven_file_name_regex' do

View file

@ -210,6 +210,50 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
context 'when no slot is set' do context 'when no slot is set' do
it { expect(described_class.unique_events(event_names: no_slot, start_date: 7.days.ago, end_date: Date.current)).to eq(1) } it { expect(described_class.unique_events(event_names: no_slot, start_date: 7.days.ago, end_date: Date.current)).to eq(1) }
end end
context 'when data crosses into new year' do
it 'does not raise error' do
expect { described_class.unique_events(event_names: [weekly_event], start_date: DateTime.parse('2020-12-26'), end_date: DateTime.parse('2021-02-01')) }
.not_to raise_error
end
end
end
end
describe '.weekly_redis_keys' do
using RSpec::Parameterized::TableSyntax
let(:weekly_event) { 'g_compliance_dashboard' }
let(:redis_event) { described_class.send(:event_for, weekly_event) }
subject(:weekly_redis_keys) { described_class.send(:weekly_redis_keys, events: [redis_event], start_date: DateTime.parse(start_date), end_date: DateTime.parse(end_date)) }
where(:start_date, :end_date, :keys) do
'2020-12-21' | '2020-12-21' | []
'2020-12-21' | '2020-12-20' | []
'2020-12-21' | '2020-11-21' | []
'2021-01-01' | '2020-12-28' | []
'2020-12-21' | '2020-12-28' | ['g_{compliance}_dashboard-2020-52']
'2020-12-21' | '2021-01-01' | ['g_{compliance}_dashboard-2020-52']
'2020-12-27' | '2021-01-01' | ['g_{compliance}_dashboard-2020-52']
'2020-12-26' | '2021-01-04' | ['g_{compliance}_dashboard-2020-52', 'g_{compliance}_dashboard-2020-53']
'2020-12-26' | '2021-01-11' | ['g_{compliance}_dashboard-2020-52', 'g_{compliance}_dashboard-2020-53', 'g_{compliance}_dashboard-2021-01']
'2020-12-26' | '2021-01-17' | ['g_{compliance}_dashboard-2020-52', 'g_{compliance}_dashboard-2020-53', 'g_{compliance}_dashboard-2021-01']
'2020-12-26' | '2021-01-18' | ['g_{compliance}_dashboard-2020-52', 'g_{compliance}_dashboard-2020-53', 'g_{compliance}_dashboard-2021-01', 'g_{compliance}_dashboard-2021-02']
end
with_them do
it "returns the correct keys" do
expect(subject).to match(keys)
end
end
it 'returns 1 key for last for week' do
expect(described_class.send(:weekly_redis_keys, events: [redis_event], start_date: 7.days.ago.to_date, end_date: Date.current).size).to eq 1
end
it 'returns 4 key for last for weeks' do
expect(described_class.send(:weekly_redis_keys, events: [redis_event], start_date: 4.weeks.ago.to_date, end_date: Date.current).size).to eq 4
end end
end end

View file

@ -50,6 +50,32 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
expect { described_class.uncached_data }.to raise_error('Stopped calculating recorded_at') expect { described_class.uncached_data }.to raise_error('Stopped calculating recorded_at')
end end
context 'when generating usage ping in critical weeks' do
it 'does not raise error when generated in last week of the year' do
travel_to(DateTime.parse('2020-12-29')) do
expect { subject }.not_to raise_error
end
end
it 'does not raise error when generated in first week of the year' do
travel_to(DateTime.parse('2021-01-01')) do
expect { subject }.not_to raise_error
end
end
it 'does not raise error when generated in second week of the year' do
travel_to(DateTime.parse('2021-01-07')) do
expect { subject }.not_to raise_error
end
end
it 'does not raise error when generated in 3rd week of the year' do
travel_to(DateTime.parse('2021-01-14')) do
expect { subject }.not_to raise_error
end
end
end
end end
describe 'usage_activity_by_stage_package' do describe 'usage_activity_by_stage_package' do

View file

@ -3,8 +3,8 @@
RSpec.shared_examples 'an incident management tracked event' do |event| RSpec.shared_examples 'an incident management tracked event' do |event|
describe ".track_event", :clean_gitlab_redis_shared_state do describe ".track_event", :clean_gitlab_redis_shared_state do
let(:counter) { Gitlab::UsageDataCounters::HLLRedisCounter } let(:counter) { Gitlab::UsageDataCounters::HLLRedisCounter }
let(:start_time) { 1.minute.ago } let(:start_time) { 1.week.ago }
let(:end_time) { 1.minute.from_now } let(:end_time) { 1.week.from_now }
it "tracks the event using redis" do it "tracks the event using redis" do
# Allow other subsequent calls # Allow other subsequent calls