Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-11-07 03:09:23 +00:00
parent b45d30ab76
commit ce5fc4c88d
6 changed files with 27 additions and 74 deletions

View File

@ -1,5 +0,0 @@
---
title: Handle nullbytes in auth headers
merge_request: 46985
author:
type: fixed

View File

@ -636,7 +636,9 @@ Group SAML on a self-managed instance is limited when compared to the recommende
## Troubleshooting ## Troubleshooting
You can find the base64-encoded SAML Response in the [`production_json.log`](../administration/logs.md#production_jsonlog). ### SAML Response
You can find the base64-encoded SAML Response in the [`production_json.log`](../administration/logs.md#production_jsonlog). This response is sent from the IdP, and contains user information that is consumed by GitLab. Many errors in the SAML integration can be solved by decoding this response and comparing it to the SAML settings in the GitLab configuration file.
### GitLab+SAML Testing Environments ### GitLab+SAML Testing Environments
@ -682,7 +684,7 @@ This error means that the IdP doesn't recognize GitLab as a valid sender and
receiver of SAML requests. Make sure to add the GitLab callback URL to the approved receiver of SAML requests. Make sure to add the GitLab callback URL to the approved
audiences of the IdP server. audiences of the IdP server.
### Missing claims ### Missing claims, or `Email can't be blank` errors
The IdP server needs to pass certain information in order for GitLab to either The IdP server needs to pass certain information in order for GitLab to either
create an account, or match the login information to an existing account. `email` create an account, or match the login information to an existing account. `email`
@ -710,3 +712,10 @@ For this you need take the following into account:
Make sure that one of the above described scenarios is valid, or the requests will Make sure that one of the above described scenarios is valid, or the requests will
fail with one of the mentioned errors. fail with one of the mentioned errors.
### User is blocked when signing in through SAML
The following are the most likely reasons that a user is blocked when signing in through SAML:
- In the configuration, `gitlab_rails['omniauth_block_auto_created_users'] = true` is set and this is the user's first time signing in.
- There are [`required_groups`](#required-groups) configured, but the user is not a member of one.

View File

@ -5,8 +5,6 @@ module Gitlab
# There is no valid reason for a request to contain a malformed string # There is no valid reason for a request to contain a malformed string
# so just return HTTP 400 (Bad Request) if we receive one # so just return HTTP 400 (Bad Request) if we receive one
class HandleMalformedStrings class HandleMalformedStrings
include ActionController::HttpAuthentication::Basic
NULL_BYTE_REGEX = Regexp.new(Regexp.escape("\u0000")).freeze NULL_BYTE_REGEX = Regexp.new(Regexp.escape("\u0000")).freeze
attr_reader :app attr_reader :app
@ -23,26 +21,16 @@ module Gitlab
private private
def request_contains_malformed_string?(env) def request_contains_malformed_string?(request)
return false if ENV['DISABLE_REQUEST_VALIDATION'] == '1' return false if ENV['DISABLE_REQUEST_VALIDATION'] == '1'
# Duplicate the env, so it is not modified when accessing the parameters request = Rack::Request.new(request)
# https://github.com/rails/rails/blob/34991a6ae2fc68347c01ea7382fa89004159e019/actionpack/lib/action_dispatch/http/parameters.rb#L59
# The modification causes problems with our multipart middleware
request = ActionDispatch::Request.new(env.dup)
return true if malformed_path?(request.path) return true if malformed_path?(request.path)
return true if credentials_malformed?(request)
request.params.values.any? do |value| request.params.values.any? do |value|
param_has_null_byte?(value) param_has_null_byte?(value)
end end
rescue ActionController::BadRequest
# If we can't build an ActionDispatch::Request something's wrong
# This would also happen if `#params` contains invalid UTF-8
# in this case we'll return a 400
#
true
end end
def malformed_path?(path) def malformed_path?(path)
@ -52,13 +40,6 @@ module Gitlab
true true
end end
def credentials_malformed?(request)
credentials = decode_credentials(request).presence
return false unless credentials
string_malformed?(credentials)
end
def param_has_null_byte?(value, depth = 0) def param_has_null_byte?(value, depth = 0)
# Guard against possible attack sending large amounts of nested params # Guard against possible attack sending large amounts of nested params
# Should be safe as deeply nested params are highly uncommon. # Should be safe as deeply nested params are highly uncommon.

View File

@ -22,13 +22,13 @@ RSpec.describe 'Invalid uploads that must be rejected', :api, :js do
) )
end end
RSpec.shared_examples 'rejecting invalid keys' do |key_name:, message: nil, status: 500| RSpec.shared_examples 'rejecting invalid keys' do |key_name:, message: nil|
context "with invalid key #{key_name}" do context "with invalid key #{key_name}" do
let(:body) { { key_name => file, 'package[test][name]' => 'test' } } let(:body) { { key_name => file, 'package[test][name]' => 'test' } }
it { expect { subject }.not_to change { Packages::Package.nuget.count } } it { expect { subject }.not_to change { Packages::Package.nuget.count } }
it { expect(subject.code).to eq(status) } it { expect(subject.code).to eq(500) }
it { expect(subject.body).to include(message.presence || "invalid field: \"#{key_name}\"") } it { expect(subject.body).to include(message.presence || "invalid field: \"#{key_name}\"") }
end end
@ -45,7 +45,7 @@ RSpec.describe 'Invalid uploads that must be rejected', :api, :js do
# These keys are rejected directly by rack itself. # These keys are rejected directly by rack itself.
# The request will not be received by multipart.rb (can't use the 'handling file uploads' shared example) # The request will not be received by multipart.rb (can't use the 'handling file uploads' shared example)
it_behaves_like 'rejecting invalid keys', key_name: 'x' * 11000, message: 'Puma caught this error: exceeded available parameter key space (RangeError)' it_behaves_like 'rejecting invalid keys', key_name: 'x' * 11000, message: 'Puma caught this error: exceeded available parameter key space (RangeError)'
it_behaves_like 'rejecting invalid keys', key_name: 'package[]test', status: 400, message: 'Bad Request' it_behaves_like 'rejecting invalid keys', key_name: 'package[]test', message: 'Puma caught this error: expected Hash (got Array)'
it_behaves_like 'handling file uploads', 'by rejecting uploads with an invalid key' it_behaves_like 'handling file uploads', 'by rejecting uploads with an invalid key'
end end

View File

@ -4,8 +4,6 @@ require 'spec_helper'
require "rack/test" require "rack/test"
RSpec.describe Gitlab::Middleware::HandleMalformedStrings do RSpec.describe Gitlab::Middleware::HandleMalformedStrings do
include GitHttpHelpers
let(:null_byte) { "\u0000" } let(:null_byte) { "\u0000" }
let(:escaped_null_byte) { "%00" } let(:escaped_null_byte) { "%00" }
let(:invalid_string) { "mal\xC0formed" } let(:invalid_string) { "mal\xC0formed" }
@ -59,22 +57,6 @@ RSpec.describe Gitlab::Middleware::HandleMalformedStrings do
end end
end end
context 'in authorization headers' do
let(:problematic_input) { null_byte }
it 'rejects problematic input in the password' do
env = env_for.merge(auth_env("username", "password#{problematic_input}encoded", nil))
expect(subject.call(env)).to eq error_400
end
it 'rejects problematic input in the password' do
env = env_for.merge(auth_env("username#{problematic_input}", "password#{problematic_input}encoded", nil))
expect(subject.call(env)).to eq error_400
end
end
context 'in params' do context 'in params' do
shared_examples_for 'checks params' do shared_examples_for 'checks params' do
it 'rejects bad params in a top level param' do it 'rejects bad params in a top level param' do
@ -104,24 +86,24 @@ RSpec.describe Gitlab::Middleware::HandleMalformedStrings do
expect(subject.call(env)).to eq error_400 expect(subject.call(env)).to eq error_400
end end
end
context 'with null byte' do
let(:problematic_input) { null_byte }
it_behaves_like 'checks params'
it "gives up and does not reject too deeply nested params" do it "gives up and does not reject too deeply nested params" do
env = env_for(name: [ env = env_for(name: [
{ {
inner_key: { deeper_key: [{ hash_inside_array_key: "I am #{problematic_input} bad" }] } inner_key: { deeper_key: [{ hash_inside_array_key: "I am #{problematic_input} bad" }] }
} }
]) ])
expect(subject.call(env)).not_to eq error_400 expect(subject.call(env)).not_to eq error_400
end end
end end
context 'with null byte' do
it_behaves_like 'checks params' do
let(:problematic_input) { null_byte }
end
end
context 'with malformed strings' do context 'with malformed strings' do
it_behaves_like 'checks params' do it_behaves_like 'checks params' do
let(:problematic_input) { invalid_string } let(:problematic_input) { invalid_string }
@ -142,10 +124,4 @@ RSpec.describe Gitlab::Middleware::HandleMalformedStrings do
expect(subject.call(env)).not_to eq error_400 expect(subject.call(env)).not_to eq error_400
end end
end end
it 'does not modify the env' do
env = env_for
expect { subject.call(env) }.not_to change { env }
end
end end

View File

@ -2,9 +2,7 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe 'User sends malformed strings' do RSpec.describe 'User sends malformed strings as params' do
include GitHttpHelpers
let(:null_byte) { "\u0000" } let(:null_byte) { "\u0000" }
let(:invalid_string) { "mal\xC0formed" } let(:invalid_string) { "mal\xC0formed" }
@ -19,10 +17,4 @@ RSpec.describe 'User sends malformed strings' do
expect(response).to have_gitlab_http_status(:bad_request) expect(response).to have_gitlab_http_status(:bad_request)
end end
it 'raises a 400 error with null bytes in the auth headers' do
clone_get("project/path", user: "hello#{null_byte}", password: "nothing to see")
expect(response).to have_gitlab_http_status(:bad_request)
end
end end