Merge branch '41293-fix-command-injection-vulnerability-on-system_hook_push-queue-through-web-hook' into 'security-10-3'

Don't allow line breaks on HTTP headers

See merge request gitlab/gitlabhq!2277

(cherry picked from commit 7fc0a6fc096768a5604d6dd24d7d952e53300c82)

073b8f9c Don't allow line breaks on HTTP headers
This commit is contained in:
Robert Speicher 2018-01-05 21:36:18 +00:00 committed by Stan Hu
parent 536a47b4b7
commit 791ca43f3f
5 changed files with 28 additions and 1 deletions

View file

@ -4,6 +4,7 @@ class WebHook < ActiveRecord::Base
has_many :web_hook_logs, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent has_many :web_hook_logs, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
validates :url, presence: true, url: true validates :url, presence: true, url: true
validates :token, format: { without: /\n/ }
def execute(data, hook_name) def execute(data, hook_name)
WebHookService.new(self, data, hook_name).execute WebHookService.new(self, data, hook_name).execute

View file

@ -113,7 +113,7 @@ class WebHookService
'Content-Type' => 'application/json', 'Content-Type' => 'application/json',
'X-Gitlab-Event' => hook_name.singularize.titleize 'X-Gitlab-Event' => hook_name.singularize.titleize
}.tap do |hash| }.tap do |hash|
hash['X-Gitlab-Token'] = hook.token if hook.token.present? hash['X-Gitlab-Token'] = Gitlab::Utils.remove_line_breaks(hook.token) if hook.token.present?
end end
end end
end end

View file

@ -27,6 +27,10 @@ module Gitlab
.gsub(/(\A-+|-+\z)/, '') .gsub(/(\A-+|-+\z)/, '')
end end
def remove_line_breaks(str)
str.gsub(/\r?\n/, '')
end
def to_boolean(value) def to_boolean(value)
return value if [true, false].include?(value) return value if [true, false].include?(value)
return true if value =~ /^(true|t|yes|y|1|on)$/i return true if value =~ /^(true|t|yes|y|1|on)$/i

View file

@ -17,6 +17,22 @@ describe Gitlab::Utils do
end end
end end
describe '.remove_line_breaks' do
using RSpec::Parameterized::TableSyntax
where(:original, :expected) do
"foo\nbar\nbaz" | "foobarbaz"
"foo\r\nbar\r\nbaz" | "foobarbaz"
"foobar" | "foobar"
end
with_them do
it "replace line breaks with an empty string" do
expect(described_class.remove_line_breaks(original)).to eq(expected)
end
end
end
describe '.to_boolean' do describe '.to_boolean' do
it 'accepts booleans' do it 'accepts booleans' do
expect(to_boolean(true)).to be(true) expect(to_boolean(true)).to be(true)

View file

@ -29,6 +29,12 @@ describe WebHook do
expect(hook.url).to eq('https://example.com') expect(hook.url).to eq('https://example.com')
end end
end end
describe 'token' do
it { is_expected.to allow_value("foobar").for(:token) }
it { is_expected.not_to allow_values("foo\nbar", "foo\r\nbar").for(:token) }
end
end end
describe 'execute' do describe 'execute' do