Add latest changes from gitlab-org/security/gitlab@15-7-stable-ee

This commit is contained in:
GitLab Bot 2023-03-01 18:37:59 +00:00
parent f5d158fe8b
commit f4349b83ea
17 changed files with 139 additions and 33 deletions

View File

@ -15,6 +15,7 @@ module Integrations
TAG_KEY_VALUE_RE = %r{\A [\w-]+ : .*\S.* \z}x.freeze
field :datadog_site,
exposes_secrets: true,
placeholder: DEFAULT_DOMAIN,
help: -> do
ERB::Util.html_escape(

View File

@ -3,6 +3,7 @@
module Integrations
class Prometheus < BaseMonitoring
include PrometheusAdapter
include Gitlab::Utils::StrongMemoize
field :manual_configuration,
type: 'checkbox',
@ -81,7 +82,7 @@ module Integrations
allow_local_requests: allow_local_api_url?
)
if behind_iap?
if behind_iap? && iap_client
# Adds the Authorization header
options[:headers] = iap_client.apply({})
end
@ -106,6 +107,22 @@ module Integrations
should_return_client?
end
alias_method :google_iap_service_account_json_raw, :google_iap_service_account_json
private :google_iap_service_account_json_raw
MASKED_VALUE = '*' * 8
def google_iap_service_account_json
json = google_iap_service_account_json_raw
return json unless json.present?
Gitlab::Json.parse(json)
.then { |hash| hash.transform_values { MASKED_VALUE } }
.then { |hash| Gitlab::Json.generate(hash) }
rescue Gitlab::Json.parser_error
json
end
private
delegate :allow_local_requests_from_web_hooks_and_services?, to: :current_settings, private: true
@ -155,17 +172,21 @@ module Integrations
end
def clean_google_iap_service_account
return unless google_iap_service_account_json
json = google_iap_service_account_json_raw
return unless json.present?
google_iap_service_account_json
.then { |json| Gitlab::Json.parse(json) }
.except('token_credential_uri')
Gitlab::Json.parse(json).except('token_credential_uri')
rescue Gitlab::Json.parser_error
{}
end
def iap_client
@iap_client ||= Google::Auth::Credentials
.new(clean_google_iap_service_account, target_audience: google_iap_audience_client_id)
.client
rescue StandardError
nil
end
strong_memoize_attr :iap_client
end
end

View File

@ -50,6 +50,7 @@ module Groups
publish_event(old_root_ancestor_id)
end
# Overridden in EE
def ensure_allowed_transfer
raise_transfer_error(:group_is_already_root) if group_is_already_root?
raise_transfer_error(:same_parent_as_current) if same_parent?
@ -207,6 +208,7 @@ module Groups
raise TransferError, localized_error_messages[message]
end
# Overridden in EE
def localized_error_messages
{
database_not_supported: s_('TransferGroup|Database is not supported.'),

View File

@ -14,7 +14,7 @@ module RestClient
self.hostname_override = hostname_override
rescue Gitlab::UrlBlocker::BlockedUrlError => e
raise ArgumentError, "URL '#{uri}' is blocked: #{e.message}"
raise ArgumentError, "URL is blocked: #{e.message}"
end
# Gitlab::UrlBlocker returns a Addressable::URI which we need to coerce

View File

@ -86,11 +86,15 @@ module API
get ':id/repository/commits', urgency: :low do
not_found! 'Repository' unless user_project.repository_exists?
page = params[:page] > 0 ? params[:page] : 1
per_page = params[:per_page] > 0 ? params[:per_page] : Kaminari.config.default_per_page
limit = [per_page, Kaminari.config.max_per_page].min
offset = (page - 1) * limit
path = params[:path]
before = params[:until]
after = params[:since]
ref = params[:ref_name].presence || user_project.default_branch unless params[:all]
offset = (params[:page] - 1) * params[:per_page]
all = params[:all]
with_stats = params[:with_stats]
first_parent = params[:first_parent]
@ -98,7 +102,7 @@ module API
commits = user_project.repository.commits(ref,
path: path,
limit: params[:per_page],
limit: limit,
offset: offset,
before: before,
after: after,

View File

@ -47,7 +47,7 @@ module Gitlab
dns_rebind_protection: dns_rebind_protection?,
schemes: %w[http https])
rescue Gitlab::UrlBlocker::BlockedUrlError => e
raise Gitlab::HTTP::BlockedUrlError, "URL '#{url}' is blocked: #{e.message}"
raise Gitlab::HTTP::BlockedUrlError, "URL is blocked: #{e.message}"
end
def allow_local_requests?

View File

@ -43734,6 +43734,9 @@ msgstr ""
msgid "TransferGroup|Group is already associated to the parent group."
msgstr ""
msgid "TransferGroup|SAML Provider or SCIM Token is configured for this group."
msgstr ""
msgid "TransferGroup|The parent group already has a subgroup or a project with the same path."
msgstr ""

View File

@ -184,7 +184,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Remote do
let(:location) { 'http://127.0.0.1/some/path/to/config.yaml' }
it 'includes details about blocked URL' do
expect(subject).to eq "Remote file could not be fetched because URL '#{location}' " \
expect(subject).to eq "Remote file could not be fetched because URL " \
'is blocked: Requests to localhost are not allowed!'
end
end

View File

@ -72,7 +72,7 @@ RSpec.describe Gitlab::FogbugzImport::Importer do
expect { subject.execute }
.to raise_error(
::Gitlab::HTTP::BlockedUrlError,
"URL 'https://localhost:3000/api.asp' is blocked: Requests to localhost are not allowed"
"URL is blocked: Requests to localhost are not allowed"
)
end
end
@ -84,7 +84,7 @@ RSpec.describe Gitlab::FogbugzImport::Importer do
expect { subject.execute }
.to raise_error(
::Gitlab::HTTP::BlockedUrlError,
"URL 'http://192.168.0.1/api.asp' is blocked: Requests to the local network are not allowed"
"URL is blocked: Requests to the local network are not allowed"
)
end
end

View File

@ -44,7 +44,7 @@ RSpec.describe Gitlab::HTTPConnectionAdapter do
it 'raises error' do
expect { subject }.to raise_error(
Gitlab::HTTP::BlockedUrlError,
"URL 'http://172.16.0.0/12' is blocked: Requests to the local network are not allowed"
"URL is blocked: Requests to the local network are not allowed"
)
end
@ -67,7 +67,7 @@ RSpec.describe Gitlab::HTTPConnectionAdapter do
it 'raises error' do
expect { subject }.to raise_error(
Gitlab::HTTP::BlockedUrlError,
"URL 'http://127.0.0.1' is blocked: Requests to localhost are not allowed"
"URL is blocked: Requests to localhost are not allowed"
)
end
@ -131,7 +131,7 @@ RSpec.describe Gitlab::HTTPConnectionAdapter do
it 'raises error' do
expect { subject }.to raise_error(
Gitlab::HTTP::BlockedUrlError,
"URL 'ssh://example.org' is blocked: Only allowed schemes are http, https"
"URL is blocked: Only allowed schemes are http, https"
)
end
end

View File

@ -88,7 +88,7 @@ RSpec.describe Gitlab::ImportExport::RemoteStreamUpload do
it 'raises error' do
expect { subject.execute }.to raise_error(
Gitlab::HTTP::BlockedUrlError,
"URL 'http://127.0.0.1/file.txt' is blocked: Requests to localhost are not allowed"
"URL is blocked: Requests to localhost are not allowed"
)
end
@ -114,7 +114,7 @@ RSpec.describe Gitlab::ImportExport::RemoteStreamUpload do
it 'raises error' do
expect { subject.execute }.to raise_error(
Gitlab::HTTP::BlockedUrlError,
"URL 'http://172.16.0.0/file.txt' is blocked: Requests to the local network are not allowed"
"URL is blocked: Requests to the local network are not allowed"
)
end
@ -142,7 +142,7 @@ RSpec.describe Gitlab::ImportExport::RemoteStreamUpload do
expect { subject.execute }.to raise_error(
Gitlab::HTTP::BlockedUrlError,
"URL 'http://127.0.0.1/file.txt' is blocked: Requests to localhost are not allowed"
"URL is blocked: Requests to localhost are not allowed"
)
end
@ -168,7 +168,7 @@ RSpec.describe Gitlab::ImportExport::RemoteStreamUpload do
it 'raises error' do
expect { subject.execute }.to raise_error(
Gitlab::HTTP::BlockedUrlError,
"URL 'http://172.16.0.0/file.txt' is blocked: Requests to the local network are not allowed"
"URL is blocked: Requests to the local network are not allowed"
)
end
@ -192,7 +192,7 @@ RSpec.describe Gitlab::ImportExport::RemoteStreamUpload do
expect { subject.execute }.to raise_error(
Gitlab::HTTP::BlockedUrlError,
"URL 'http://example.com/file.txt' is blocked: Requests to localhost are not allowed"
"URL is blocked: Requests to localhost are not allowed"
)
end
end

View File

@ -43,10 +43,7 @@ RSpec.describe Gitlab::Prometheus::Queries::ValidateQuery do
context 'Gitlab::HTTP::BlockedUrlError' do
let(:api_url) { 'http://192.168.1.1' }
let(:message) do
"URL 'http://192.168.1.1/api/v1/query?query=avg%28metric%29&time=#{Time.now.to_f}'" \
" is blocked: Requests to the local network are not allowed"
end
let(:message) { "URL is blocked: Requests to the local network are not allowed" }
before do
stub_application_setting(allow_local_requests_from_web_hooks_and_services: false)

View File

@ -3,7 +3,7 @@ require 'securerandom'
require 'spec_helper'
RSpec.describe Integrations::Datadog do
RSpec.describe Integrations::Datadog, feature_category: :integrations do
let_it_be(:project) { create(:project) }
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
let_it_be(:build) { create(:ci_build, pipeline: pipeline) }

View File

@ -239,6 +239,7 @@ RSpec.describe Integrations::Prometheus, :use_clean_rails_memory_store_caching,
context 'behind IAP' do
let(:manual_configuration) { true }
let(:google_iap_service_account_json) { Gitlab::Json.generate(google_iap_service_account) }
let(:google_iap_service_account) do
{
@ -259,7 +260,7 @@ RSpec.describe Integrations::Prometheus, :use_clean_rails_memory_store_caching,
end
def stub_iap_request
integration.google_iap_service_account_json = Gitlab::Json.generate(google_iap_service_account)
integration.google_iap_service_account_json = google_iap_service_account_json
integration.google_iap_audience_client_id = 'IAP_CLIENT_ID.apps.googleusercontent.com'
stub_request(:post, 'https://oauth2.googleapis.com/token')
@ -278,6 +279,17 @@ RSpec.describe Integrations::Prometheus, :use_clean_rails_memory_store_caching,
expect(integration.prometheus_client.send(:options)[:headers]).to eq(authorization: "Bearer FOO")
end
context 'with invalid IAP JSON' do
let(:google_iap_service_account_json) { 'invalid json' }
it 'does not include authorization header' do
stub_iap_request
expect(integration.prometheus_client).not_to be_nil
expect(integration.prometheus_client.send(:options)).not_to have_key(:headers)
end
end
context 'when passed with token_credential_uri', issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/284819' do
let(:malicious_host) { 'http://example.com' }
@ -477,4 +489,45 @@ RSpec.describe Integrations::Prometheus, :use_clean_rails_memory_store_caching,
end
end
end
describe '#google_iap_service_account_json' do
subject(:iap_details) { integration.google_iap_service_account_json }
before do
integration.google_iap_service_account_json = value
end
context 'with valid JSON' do
let(:masked_value) { described_class::MASKED_VALUE }
let(:json) { Gitlab::Json.parse(iap_details) }
let(:value) do
Gitlab::Json.generate({
type: 'service_account',
private_key: 'SECRET',
foo: 'secret',
nested: {
key: 'value'
}
})
end
it 'masks all JSON values', issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/384580' do
expect(json).to eq(
'type' => masked_value,
'private_key' => masked_value,
'foo' => masked_value,
'nested' => masked_value
)
end
end
context 'with invalid JSON' do
where(:value) { [nil, '', ' ', 'invalid json'] }
with_them do
it { is_expected.to eq(value) }
end
end
end
end

View File

@ -249,6 +249,18 @@ RSpec.describe API::Commits, feature_category: :source_code_management do
end
end
context 'when per_page is over 100' do
let(:per_page) { 101 }
it 'returns 100 commits (maximum)' do
expect(Gitlab::Git::Commit).to receive(:where).with(
hash_including(ref: ref_name, limit: 100, offset: 0)
)
request
end
end
context 'when pagination params are invalid' do
let_it_be(:project) { create(:project, :repository) }
@ -279,7 +291,7 @@ RSpec.describe API::Commits, feature_category: :source_code_management do
where(:page, :per_page, :error_message, :status) do
0 | nil | nil | :success
-10 | nil | nil | :internal_server_error
-10 | nil | nil | :success
'a' | nil | 'page is invalid' | :bad_request
nil | 0 | 'per_page has a value not allowed' | :bad_request
nil | -1 | nil | :success
@ -297,6 +309,18 @@ RSpec.describe API::Commits, feature_category: :source_code_management do
end
end
end
context 'when per_page is below 0' do
let(:per_page) { -100 }
it 'returns 20 commits (default)' do
expect(Gitlab::Git::Commit).to receive(:where).with(
hash_including(ref: ref_name, limit: 20, offset: 0)
)
request
end
end
end
end
end

View File

@ -87,6 +87,7 @@ Integration.available_integration_names.each do |integration|
def initialize_integration(integration, attrs = {})
record = project.find_or_initialize_integration(integration)
record.reset_updated_properties if integration == 'datadog'
record.attributes = attrs
record.properties = integration_attrs
record.save!

View File

@ -33,7 +33,7 @@ RSpec.shared_examples 'a request using Gitlab::UrlBlocker' do
expect { make_request('https://example.com') }
.to raise_error(url_blocked_error_class,
"URL 'https://example.com' is blocked: Requests to the local network are not allowed")
"URL is blocked: Requests to the local network are not allowed")
end
it 'raises error when it is a request that resolves to a localhost address' do
@ -41,19 +41,19 @@ RSpec.shared_examples 'a request using Gitlab::UrlBlocker' do
expect { make_request('https://example.com') }
.to raise_error(url_blocked_error_class,
"URL 'https://example.com' is blocked: Requests to localhost are not allowed")
"URL is blocked: Requests to localhost are not allowed")
end
it 'raises error when it is a request to local address' do
expect { make_request('http://172.16.0.0') }
.to raise_error(url_blocked_error_class,
"URL 'http://172.16.0.0' is blocked: Requests to the local network are not allowed")
"URL is blocked: Requests to the local network are not allowed")
end
it 'raises error when it is a request to localhost address' do
expect { make_request('http://127.0.0.1') }
.to raise_error(url_blocked_error_class,
"URL 'http://127.0.0.1' is blocked: Requests to localhost are not allowed")
"URL is blocked: Requests to localhost are not allowed")
end
end
@ -69,13 +69,13 @@ RSpec.shared_examples 'a request using Gitlab::UrlBlocker' do
it 'raises error when it is a request to local address' do
expect { make_request('https://172.16.0.0:8080') }
.to raise_error(url_blocked_error_class,
"URL 'https://172.16.0.0:8080' is blocked: Requests to the local network are not allowed")
"URL is blocked: Requests to the local network are not allowed")
end
it 'raises error when it is a request to localhost address' do
expect { make_request('https://127.0.0.1:8080') }
.to raise_error(url_blocked_error_class,
"URL 'https://127.0.0.1:8080' is blocked: Requests to localhost are not allowed")
"URL is blocked: Requests to localhost are not allowed")
end
end