On ശനി 10 മാർച്ച് 2018 11:25 വൈകു, Pirate Praveen wrote: > I will attach a debdiff tomorrow with the CVEs we already backported.
debdiff attached.
diff -Nru gitlab-8.13.11+dfsg/debian/changelog gitlab-8.13.11+dfsg/debian/changelog --- gitlab-8.13.11+dfsg/debian/changelog 2017-03-23 17:16:50.000000000 +0530 +++ gitlab-8.13.11+dfsg/debian/changelog 2018-03-11 20:13:17.000000000 +0530 @@ -1,3 +1,10 @@ +gitlab (8.13.11+dfsg-8+deb9u1) stretch-security; urgency=high + + * Fixes multiple security vulnerabilities (backported from 10.3.4 release) + CVE-2017-0916, CVE-2017-0918, CVE-2017-0925, CVE-2017-0926, CVE-2017-3710 + + -- Pirate Praveen <prav...@debian.org> Sun, 11 Mar 2018 20:13:17 +0530 + gitlab (8.13.11+dfsg-8) unstable; urgency=medium * Don't fail if gitlab-debian.defaults not found (to support upgrading diff -Nru gitlab-8.13.11+dfsg/debian/patches/cve-2017-0916.patch gitlab-8.13.11+dfsg/debian/patches/cve-2017-0916.patch --- gitlab-8.13.11+dfsg/debian/patches/cve-2017-0916.patch 1970-01-01 05:30:00.000000000 +0530 +++ gitlab-8.13.11+dfsg/debian/patches/cve-2017-0916.patch 2018-03-11 20:07:30.000000000 +0530 @@ -0,0 +1,32 @@ +--- a/app/models/hooks/web_hook.rb ++++ b/app/models/hooks/web_hook.rb +@@ -19,6 +19,7 @@ + default_timeout Gitlab.config.gitlab.webhook_timeout + + validates :url, presence: true, url: true ++ validates :token, format: { without: /\n/ } + + def execute(data, hook_name) + parsed_url = URI.parse(url) +@@ -57,7 +58,7 @@ + 'Content-Type' => 'application/json', + 'X-Gitlab-Event' => hook_name.singularize.titleize + } +- headers['X-Gitlab-Token'] = token if token.present? ++ headers['X-Gitlab-Token'] = Gitlab::Utils.remove_line_breaks(token) if token.present? + headers + end + end +--- a/lib/gitlab/utils.rb ++++ b/lib/gitlab/utils.rb +@@ -14,6 +14,10 @@ + str.force_encoding(Encoding::UTF_8) + end + ++ def remove_line_breaks(str) ++ str.gsub(/\r?\n/, '') ++ end ++ + def to_boolean(value) + return value if [true, false].include?(value) + return true if value =~ /^(true|t|yes|y|1|on)$/i diff -Nru gitlab-8.13.11+dfsg/debian/patches/cve-2017-0918.patch gitlab-8.13.11+dfsg/debian/patches/cve-2017-0918.patch --- gitlab-8.13.11+dfsg/debian/patches/cve-2017-0918.patch 1970-01-01 05:30:00.000000000 +0530 +++ gitlab-8.13.11+dfsg/debian/patches/cve-2017-0918.patch 2018-03-11 20:07:30.000000000 +0530 @@ -0,0 +1,28 @@ +--- a/lib/gitlab/ci/config/node/validators.rb ++++ b/lib/gitlab/ci/config/node/validators.rb +@@ -48,10 +48,24 @@ + include LegacyValidationHelpers + + def validate_each(record, attribute, value) +- unless validate_string(value) ++ if validate_string(value) ++ validate_path(record, attribute, value) ++ else + record.errors.add(attribute, 'should be a string or symbol') + end + end ++ ++ private ++ ++ def validate_path(record, attribute, value) ++ path = CGI.unescape(value.to_s) ++ ++ if path.include?('/') ++ record.errors.add(attribute, 'cannot contain the "/" character') ++ elsif path == '.' || path == '..' ++ record.errors.add(attribute, 'cannot be "." or ".."') ++ end ++ end + end + + class TypeValidator < ActiveModel::EachValidator diff -Nru gitlab-8.13.11+dfsg/debian/patches/cve-2017-0925.patch gitlab-8.13.11+dfsg/debian/patches/cve-2017-0925.patch --- gitlab-8.13.11+dfsg/debian/patches/cve-2017-0925.patch 1970-01-01 05:30:00.000000000 +0530 +++ gitlab-8.13.11+dfsg/debian/patches/cve-2017-0925.patch 2018-03-11 20:07:30.000000000 +0530 @@ -0,0 +1,39 @@ +--- a/app/models/service.rb ++++ b/app/models/service.rb +@@ -98,6 +98,11 @@ + nil + end + ++ def api_field_names ++ fields.map { |field| field[:name] } ++ .reject { |field_name| field_name =~ /(password|token|key)/ } ++ end ++ + def global_fields + fields + end +--- a/lib/api/entities.rb ++++ b/lib/api/entities.rb +@@ -411,10 +411,7 @@ + expose :tag_push_events, :note_events, :build_events, :pipeline_events + # Expose serialized properties + expose :properties do |service, options| +- field_names = service.fields. +- select { |field| options[:include_passwords] || field[:type] != 'password' }. +- map { |field| field[:name] } +- service.properties.slice(*field_names) ++ service.properties.slice(*service.api_field_names) + end + end + +--- a/lib/api/services.rb ++++ b/lib/api/services.rb +@@ -56,7 +56,7 @@ + # GET /project/:id/services/gitlab-ci + # + get ':id/services/:service_slug' do +- present project_service, with: Entities::ProjectService, include_passwords: current_user.is_admin? ++ present project_service, with: Entities::ProjectService + end + end + end diff -Nru gitlab-8.13.11+dfsg/debian/patches/cve-2017-0926.patch gitlab-8.13.11+dfsg/debian/patches/cve-2017-0926.patch --- gitlab-8.13.11+dfsg/debian/patches/cve-2017-0926.patch 1970-01-01 05:30:00.000000000 +0530 +++ gitlab-8.13.11+dfsg/debian/patches/cve-2017-0926.patch 2018-03-11 20:07:30.000000000 +0530 @@ -0,0 +1,171 @@ +From d2536bf5a683098f4077cf644e8344cc7ea8e13a Mon Sep 17 00:00:00 2001 +From: Robert Speicher <rob...@gitlab.com> +Date: Tue, 9 Jan 2018 16:47:31 +0000 +Subject: [PATCH] Merge branch 'jej/fix-disabled-oauth-access-10-3' into 'security-10-3' + +[10.3] Prevent login with disabled OAuth providers + +See merge request gitlab/gitlabhq!2296 + +(cherry picked from commit 4936650427ffc88e6ee927aedbb2c724d24b094c) + +a0f9d222 Prevents login with disabled OAuth providers +--- + app/controllers/omniauth_callbacks_controller.rb | 9 +++++++++ + changelogs/unreleased/jej-fix-disabled-oauth-access.yml | 5 +++++ + lib/gitlab/o_auth.rb | 6 ++++++ + lib/gitlab/o_auth/user.rb | 11 ++++++----- + spec/controllers/omniauth_callbacks_controller_spec.rb | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + spec/features/oauth_login_spec.rb | 3 +-- + spec/support/devise_helpers.rb | 15 +++++++++------ + spec/support/login_helpers.rb | 7 +++++++ + 8 files changed, 118 insertions(+), 13 deletions(-) + create mode 100644 changelogs/unreleased/jej-fix-disabled-oauth-access.yml + create mode 100644 lib/gitlab/o_auth.rb + create mode 100644 spec/controllers/omniauth_callbacks_controller_spec.rb + +--- a/app/controllers/omniauth_callbacks_controller.rb ++++ b/app/controllers/omniauth_callbacks_controller.rb +@@ -93,6 +93,8 @@ + + continue_login_process + end ++ rescue Gitlab::OAuth::SigninDisabledForProviderError ++ handle_disabled_provider + rescue Gitlab::OAuth::SignupDisabledError + handle_signup_error + end +@@ -136,6 +138,13 @@ + @oauth ||= request.env['omniauth.auth'] + end + ++ def handle_disabled_provider ++ label = Gitlab::OAuth::Provider.label_for(oauth['provider']) ++ flash[:alert] = "Signing in using #{label} has been disabled" ++ ++ redirect_to new_user_session_path ++ end ++ + def log_audit_event(user, options = {}) + AuditEventService.new(user, user, options). + for_authentication.security_event +--- /dev/null ++++ b/changelogs/unreleased/jej-fix-disabled-oauth-access.yml +@@ -0,0 +1,5 @@ ++--- ++title: Prevent OAuth login POST requests when a provider has been disabled ++merge_request: ++author: ++type: security +--- /dev/null ++++ b/lib/gitlab/o_auth.rb +@@ -0,0 +1,6 @@ ++module Gitlab ++ module OAuth ++ SignupDisabledError = Class.new(StandardError) ++ SigninDisabledForProviderError = Class.new(StandardError) ++ end ++end +--- a/lib/gitlab/o_auth/user.rb ++++ b/lib/gitlab/o_auth/user.rb +@@ -27,7 +27,8 @@ + end + + def save(provider = 'OAuth') +- unauthorized_to_create unless gl_user ++ raise SigninDisabledForProviderError if oauth_provider_disabled? ++ raise SignupDisabledError unless gl_user + + if needs_blocking? + gl_user.save! +@@ -181,8 +182,10 @@ + Gitlab::AppLogger + end + +- def unauthorized_to_create +- raise SignupDisabledError ++ def oauth_provider_disabled? ++ Gitlab::CurrentSettings.current_application_settings ++ .disabled_oauth_sign_in_sources ++ .include?(auth_hash.provider) + end + end + end +--- /dev/null ++++ b/spec/controllers/omniauth_callbacks_controller_spec.rb +@@ -0,0 +1,75 @@ ++require 'spec_helper' ++ ++describe OmniauthCallbacksController do ++ include LoginHelpers ++ ++ let(:user) { create(:omniauth_user, extern_uid: 'my-uid', provider: provider) } ++ let(:provider) { :github } ++ ++ before do ++ mock_auth_hash(provider.to_s, 'my-uid', user.email) ++ stub_omniauth_provider(provider, context: request) ++ end ++ ++ it 'allows sign in' do ++ post provider ++ ++ expect(request.env['warden']).to be_authenticated ++ end ++ ++ shared_context 'sign_up' do ++ let(:user) { double(email: 'n...@example.com') } ++ ++ before do ++ stub_omniauth_setting(block_auto_created_users: false) ++ end ++ end ++ ++ context 'sign up' do ++ include_context 'sign_up' ++ ++ it 'is allowed' do ++ post provider ++ ++ expect(request.env['warden']).to be_authenticated ++ end ++ end ++ ++ context 'when OAuth is disabled' do ++ before do ++ stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') ++ settings = Gitlab::CurrentSettings.current_application_settings ++ settings.update(disabled_oauth_sign_in_sources: [provider.to_s]) ++ end ++ ++ it 'prevents login via POST' do ++ post provider ++ ++ expect(request.env['warden']).not_to be_authenticated ++ end ++ ++ it 'shows warning when attempting login' do ++ post provider ++ ++ expect(response).to redirect_to new_user_session_path ++ expect(flash[:alert]).to eq('Signing in using GitHub has been disabled') ++ end ++ ++ it 'allows linking the disabled provider' do ++ user.identities.destroy_all ++ sign_in(user) ++ ++ expect { post provider }.to change { user.reload.identities.count }.by(1) ++ end ++ ++ context 'sign up' do ++ include_context 'sign_up' ++ ++ it 'is prevented' do ++ post provider ++ ++ expect(request.env['warden']).not_to be_authenticated ++ end ++ end ++ end ++end diff -Nru gitlab-8.13.11+dfsg/debian/patches/cve-2017-3710.patch gitlab-8.13.11+dfsg/debian/patches/cve-2017-3710.patch --- gitlab-8.13.11+dfsg/debian/patches/cve-2017-3710.patch 1970-01-01 05:30:00.000000000 +0530 +++ gitlab-8.13.11+dfsg/debian/patches/cve-2017-3710.patch 2018-03-11 20:07:30.000000000 +0530 @@ -0,0 +1,128 @@ +From 056d35cad0e09a59fdf44cb6bd7063f73a970f01 Mon Sep 17 00:00:00 2001 +From: James Lopez <ja...@gitlab.com> +Date: Mon, 8 Jan 2018 15:42:41 +0000 +Subject: [PATCH] Merge branch 'fix/import-rce-10-3' into 'security-10-3' + +[10.3] Fix RCE via project import mechanism + +See merge request gitlab/gitlabhq!2294 + +(cherry picked from commit dcfec507d6f9ee119d65a832393e7c593af1d3b2) + +86d75812 Fix RCE via project import mechanism +--- + changelogs/unreleased/fix-import-rce.yml | 5 +++++ + lib/gitlab/import_export/file_importer.rb | 6 +++++- + lib/gitlab/import_export/saver.rb | 2 +- + lib/gitlab/import_export/shared.rb | 14 +++++++++++++- + spec/lib/gitlab/import_export/file_importer_spec.rb | 57 ++++++++++++++++++++++++++++++++++++++++++++------------- + 5 files changed, 68 insertions(+), 16 deletions(-) + create mode 100644 changelogs/unreleased/fix-import-rce.yml + +--- /dev/null ++++ b/changelogs/unreleased/fix-import-rce.yml +@@ -0,0 +1,5 @@ ++--- ++title: Fix RCE via project import mechanism ++merge_request: ++author: ++type: security +--- a/lib/gitlab/import_export/file_importer.rb ++++ b/lib/gitlab/import_export/file_importer.rb +@@ -17,12 +17,16 @@ + def import + mkdir_p(@shared.export_path) + ++ remove_symlinks! ++ + wait_for_archived_file do + decompress_archive + end + rescue => e + @shared.error(e) + false ++ ensure ++ remove_symlinks! + end + + private +@@ -43,7 +47,7 @@ + + raise Projects::ImportService::Error.new("Unable to decompress #{@archive_file} into #{@shared.export_path}") unless result + +- remove_symlinks! ++ result + end + + def remove_symlinks! +--- a/lib/gitlab/import_export/saver.rb ++++ b/lib/gitlab/import_export/saver.rb +@@ -37,7 +37,7 @@ + end + + def archive_file +- @archive_file ||= File.join(@shared.export_path, '..', Gitlab::ImportExport.export_filename(project: @project)) ++ @archive_file ||= File.join(@shared.archive_path, Gitlab::ImportExport.export_filename(project: @project)) + end + end + end +--- a/lib/gitlab/import_export/shared.rb ++++ b/lib/gitlab/import_export/shared.rb +@@ -9,7 +9,11 @@ + end + + def export_path +- @export_path ||= Gitlab::ImportExport.export_path(relative_path: opts[:relative_path]) ++ @export_path ||= Gitlab::ImportExport.export_path(relative_path: relative_path) ++ end ++ ++ def archive_path ++ @archive_path ||= Gitlab::ImportExport.export_path(relative_path: relative_archive_path) + end + + def error(error) +@@ -21,6 +25,14 @@ + + private + ++ def relative_path ++ File.join(opts[:relative_path], SecureRandom.hex) ++ end ++ ++ def relative_archive_path ++ File.join(opts[:relative_path], '..') ++ end ++ + def error_out(message, caller) + Rails.logger.error("Import/Export error raised on #{caller}: #{message}") + end +--- a/spec/lib/gitlab/import_export/file_importer_spec.rb ++++ b/spec/lib/gitlab/import_export/file_importer_spec.rb +@@ -11,21 +11,20 @@ + stub_const('Gitlab::ImportExport::FileImporter::MAX_RETRIES', 0) + allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path) + allow_any_instance_of(Gitlab::ImportExport::CommandLineUtil).to receive(:untar_zxf).and_return(true) +- ++ allow(SecureRandom).to receive(:hex).and_return('abcd') + setup_files +- +- described_class.import(archive_file: '', shared: shared) + end + + after do + FileUtils.rm_rf(export_path) + end + +- it 'removes symlinks in root folder' do +- expect(File.exist?(symlink_file)).to be false +- end ++ context 'normal run' do ++ before do ++ described_class.import(archive_file: '', shared: shared) ++ end + +- it 'removes symlinks in subfolders' do ++ it 'removes symlinks in subfolders' do + expect(File.exist?(subfolder_symlink_file)).to be false + end + diff -Nru gitlab-8.13.11+dfsg/debian/patches/sec-release-8-13-12.patch gitlab-8.13.11+dfsg/debian/patches/sec-release-8-13-12.patch --- gitlab-8.13.11+dfsg/debian/patches/sec-release-8-13-12.patch 1970-01-01 05:30:00.000000000 +0530 +++ gitlab-8.13.11+dfsg/debian/patches/sec-release-8-13-12.patch 2018-03-11 20:07:30.000000000 +0530 @@ -0,0 +1,431 @@ +--- a/app/models/namespace.rb ++++ b/app/models/namespace.rb +@@ -111,6 +111,8 @@ + + Gitlab::UploadsTransfer.new.rename_namespace(path_was, path) + ++ remove_exports! ++ + # If repositories moved successfully we need to + # send update instructions to users. + # However we cannot allow rollback since we moved namespace dir +@@ -174,5 +176,15 @@ + GitlabShellWorker.perform_in(5.minutes, :rm_namespace, repository_storage_path, new_path) + end + end ++ ++ remove_exports! ++ end ++ ++ def remove_exports! ++ Gitlab::Popen.popen(%W(find #{export_path} -not -path #{export_path} -delete)) ++ end ++ ++ def export_path ++ File.join(Gitlab::ImportExport.storage_path, path_was) + end + end +--- a/lib/api/deploy_keys.rb ++++ b/lib/api/deploy_keys.rb +@@ -100,15 +100,19 @@ + present key.deploy_key, with: Entities::SSHKey + end + +- desc 'Delete existing deploy key of currently authenticated user' do ++ desc 'Delete deploy key for a project' do + success Key + end + params do + requires :key_id, type: Integer, desc: 'The ID of the deploy key' + end + delete ":id/#{path}/:key_id" do +- key = user_project.deploy_keys.find(params[:key_id]) +- key.destroy ++ key = user_project.deploy_keys_projects.find_by(deploy_key_id: params[:key_id]) ++ if key ++ key.destroy ++ else ++ not_found!('Deploy Key') ++ end + end + end + end +--- a/lib/api/helpers.rb ++++ b/lib/api/helpers.rb +@@ -97,6 +97,12 @@ + IssuesFinder.new(current_user, project_id: user_project.id).find(id) + end + ++ def find_merge_request_with_access(id, access_level = :read_merge_request) ++ merge_request = user_project.merge_requests.find(id) ++ authorize! access_level, merge_request ++ merge_request ++ end ++ + def paginate(relation) + relation.page(params[:page]).per(params[:per_page].to_i).tap do |data| + add_pagination_headers(data) +--- a/lib/api/merge_request_diffs.rb ++++ b/lib/api/merge_request_diffs.rb +@@ -15,10 +15,8 @@ + end + + get ":id/merge_requests/:merge_request_id/versions" do +- merge_request = user_project.merge_requests. +- find(params[:merge_request_id]) ++ merge_request = find_merge_request_with_access(params[:merge_request_id]) + +- authorize! :read_merge_request, merge_request + present merge_request.merge_request_diffs, with: Entities::MergeRequestDiff + end + +@@ -34,10 +32,8 @@ + end + + get ":id/merge_requests/:merge_request_id/versions/:version_id" do +- merge_request = user_project.merge_requests. +- find(params[:merge_request_id]) ++ merge_request = find_merge_request_with_access(params[:merge_request_id]) + +- authorize! :read_merge_request, merge_request + present merge_request.merge_request_diffs.find(params[:version_id]), with: Entities::MergeRequestDiffFull + end + end +--- a/lib/api/merge_requests.rb ++++ b/lib/api/merge_requests.rb +@@ -121,9 +121,7 @@ + # GET /projects/:id/merge_requests/:merge_request_id + # + get path do +- merge_request = user_project.merge_requests.find(params[:merge_request_id]) +- +- authorize! :read_merge_request, merge_request ++ merge_request = find_merge_request_with_access(params[:merge_request_id]) + + present merge_request, with: Entities::MergeRequest, current_user: current_user + end +@@ -138,9 +136,8 @@ + # GET /projects/:id/merge_requests/:merge_request_id/commits + # + get "#{path}/commits" do +- merge_request = user_project.merge_requests. +- find(params[:merge_request_id]) +- authorize! :read_merge_request, merge_request ++ merge_request = find_merge_request_with_access(params[:merge_request_id]) ++ + present merge_request.commits, with: Entities::RepoCommit + end + +@@ -154,9 +151,8 @@ + # GET /projects/:id/merge_requests/:merge_request_id/changes + # + get "#{path}/changes" do +- merge_request = user_project.merge_requests. +- find(params[:merge_request_id]) +- authorize! :read_merge_request, merge_request ++ merge_request = find_merge_request_with_access(params[:merge_request_id]) ++ + present merge_request, with: Entities::MergeRequestChanges, current_user: current_user + end + +@@ -174,8 +170,7 @@ + optional :milestone_id, type: Integer, desc: 'The ID of the new milestone' + end + put path do +- merge_request = user_project.merge_requests.find(params[:merge_request_id]) +- authorize! :update_merge_request, merge_request ++ merge_request = find_merge_request_with_access(params.delete(:merge_request_id), :update_merge_request) + + # Ensure source_branch is not specified + if params[:source_branch].present? +@@ -262,10 +257,7 @@ + # GET /projects/:id/merge_requests/:merge_request_id/comments + # + get "#{path}/comments" do +- merge_request = user_project.merge_requests.find(params[:merge_request_id]) +- +- authorize! :read_merge_request, merge_request +- ++ merge_request = find_merge_request_with_access(params[:merge_request_id]) + present paginate(merge_request.notes.fresh), with: Entities::MRNote + end + +@@ -284,9 +276,7 @@ + post "#{path}/comments" do + required_attributes! [:note] + +- merge_request = user_project.merge_requests.find(params[:merge_request_id]) +- +- authorize! :create_note, merge_request ++ merge_request = find_merge_request_with_access(params[:merge_request_id], :create_note) + + opts = { + note: params[:note], +@@ -311,7 +301,7 @@ + # Examples: + # GET /projects/:id/merge_requests/:merge_request_id/closes_issues + get "#{path}/closes_issues" do +- merge_request = user_project.merge_requests.find(params[:merge_request_id]) ++ merge_request = find_merge_request_with_access(params[:merge_request_id]) + issues = ::Kaminari.paginate_array(merge_request.closes_issues(current_user)) + present paginate(issues), with: issue_entity(user_project), current_user: current_user + end +--- a/lib/api/notes.rb ++++ b/lib/api/notes.rb +@@ -74,21 +74,27 @@ + required_attributes! [:body] + + opts = { +- note: params[:body], +- noteable_type: noteables_str.classify, +- noteable_id: params[noteable_id_str] ++ note: params[:body], ++ noteable_type: noteables_str.classify, ++ noteable_id: params[noteable_id_str] + } + +- if params[:created_at] && (current_user.is_admin? || user_project.owner == current_user) +- opts[:created_at] = params[:created_at] +- end ++ noteable = user_project.send(noteables_str.to_sym).find(opts[:noteable_id]) ++ ++ if can?(current_user, noteable_read_ability_name(noteable), noteable) ++ if params[:created_at] && (current_user.is_admin? || user_project.owner == current_user) ++ opts[:created_at] = params[:created_at] ++ end + +- note = ::Notes::CreateService.new(user_project, current_user, opts).execute ++ note = ::Notes::CreateService.new(user_project, current_user, opts).execute + +- if note.valid? +- present note, with: Entities::const_get(note.class.name) ++ if note.valid? ++ present note, with: Entities::const_get(note.class.name) ++ else ++ not_found!("Note #{note.errors.messages}") ++ end + else +- not_found!("Note #{note.errors.messages}") ++ not_found!("Note") + end + end + +--- a/lib/api/subscriptions.rb ++++ b/lib/api/subscriptions.rb +@@ -3,8 +3,8 @@ + before { authenticate! } + + subscribable_types = { +- 'merge_request' => proc { |id| user_project.merge_requests.find(id) }, +- 'merge_requests' => proc { |id| user_project.merge_requests.find(id) }, ++ 'merge_request' => proc { |id| find_merge_request_with_access(id, :update_merge_request) }, ++ 'merge_requests' => proc { |id| find_merge_request_with_access(id, :update_merge_request) }, + 'issues' => proc { |id| find_project_issue(id) }, + 'labels' => proc { |id| find_project_label(id) }, + } +--- a/lib/api/todos.rb ++++ b/lib/api/todos.rb +@@ -4,7 +4,7 @@ + before { authenticate! } + + ISSUABLE_TYPES = { +- 'merge_requests' => ->(id) { user_project.merge_requests.find(id) }, ++ 'merge_requests' => ->(id) { find_merge_request_with_access(id) }, + 'issues' => ->(id) { find_project_issue(id) } + } + +--- /dev/null ++++ b/spec/features/projects/import_export/namespace_export_file_spec.rb +@@ -0,0 +1,62 @@ ++require 'spec_helper' ++ ++feature 'Import/Export - Namespace export file cleanup', feature: true, js: true do ++ let(:export_path) { "#{Dir::tmpdir}/import_file_spec" } ++ let(:config_hash) { YAML.load_file(Gitlab::ImportExport.config_file).deep_stringify_keys } ++ ++ let(:project) { create(:empty_project) } ++ ++ background do ++ allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path) ++ end ++ ++ after do ++ FileUtils.rm_rf(export_path, secure: true) ++ end ++ ++ context 'admin user' do ++ before do ++ login_as(:admin) ++ end ++ ++ context 'moving the namespace' do ++ scenario 'removes the export file' do ++ setup_export_project ++ ++ old_export_path = project.export_path.dup ++ ++ expect(File).to exist(old_export_path) ++ ++ project.namespace.update(path: 'new_path') ++ ++ expect(File).not_to exist(old_export_path) ++ end ++ end ++ ++ context 'deleting the namespace' do ++ scenario 'removes the export file' do ++ setup_export_project ++ ++ old_export_path = project.export_path.dup ++ ++ expect(File).to exist(old_export_path) ++ ++ project.namespace.destroy ++ ++ expect(File).not_to exist(old_export_path) ++ end ++ end ++ ++ def setup_export_project ++ visit edit_namespace_project_path(project.namespace, project) ++ ++ expect(page).to have_content('Export project') ++ ++ click_link 'Export project' ++ ++ visit edit_namespace_project_path(project.namespace, project) ++ ++ expect(page).to have_content('Download export') ++ end ++ end ++end +--- a/spec/models/namespace_spec.rb ++++ b/spec/models/namespace_spec.rb +@@ -69,6 +69,7 @@ + new_path = @namespace.path + "_new" + allow(@namespace).to receive(:path_was).and_return(@namespace.path) + allow(@namespace).to receive(:path).and_return(new_path) ++ expect(@namespace).to receive(:remove_exports!) + expect(@namespace.move_dir).to be_truthy + end + +@@ -91,11 +92,17 @@ + let!(:project) { create(:project, namespace: namespace) } + let!(:path) { File.join(Gitlab.config.repositories.storages.default, namespace.path) } + +- before { namespace.destroy } +- + it "removes its dirs when deleted" do ++ namespace.destroy ++ + expect(File.exist?(path)).to be(false) + end ++ ++ it 'removes the exports folder' do ++ expect(namespace).to receive(:remove_exports!) ++ ++ namespace.destroy ++ end + end + + describe '.find_by_path_or_name' do +--- a/spec/requests/api/merge_requests_spec.rb ++++ b/spec/requests/api/merge_requests_spec.rb +@@ -597,6 +597,15 @@ + expect(json_response.first['title']).to eq(issue.title) + expect(json_response.first['id']).to eq(issue.id) + end ++ ++ it 'returns 403 if the user has no access to the merge request' do ++ guest = create(:user) ++ project.team << [guest, :guest] ++ ++ get api("/projects/#{project.id}/merge_requests/#{merge_request.id}/closes_issues", guest) ++ ++ expect(response).to have_http_status(403) ++ end + end + + describe 'POST :id/merge_requests/:merge_request_id/subscription' do +@@ -618,6 +627,15 @@ + + expect(response).to have_http_status(404) + end ++ ++ it 'returns 403 if user has no access to read code' do ++ guest = create(:user) ++ project.team << [guest, :guest] ++ ++ post api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", guest) ++ ++ expect(response).to have_http_status(403) ++ end + end + + describe 'DELETE :id/merge_requests/:merge_request_id/subscription' do +@@ -639,6 +657,15 @@ + + expect(response).to have_http_status(404) + end ++ ++ it 'returns 403 if user has no access to read code' do ++ guest = create(:user) ++ project.team << [guest, :guest] ++ ++ delete api("/projects/#{project.id}/merge_requests/#{merge_request.id}/subscription", guest) ++ ++ expect(response).to have_http_status(403) ++ end + end + + def mr_with_later_created_and_updated_at_time +--- a/spec/requests/api/notes_spec.rb ++++ b/spec/requests/api/notes_spec.rb +@@ -253,6 +253,18 @@ + end + end + ++ context 'when user does not have access to read the noteable' do ++ it 'responds with 404' do ++ project = create(:empty_project, :private) { |p| p.team << [user, :guest] } ++ issue = create(:issue, :confidential, project: project) ++ ++ post api("/projects/#{project.id}/issues/#{issue.id}/notes", user), ++ body: 'Foo' ++ ++ expect(response).to have_http_status(404) ++ end ++ end ++ + context 'when user does not have access to create noteable' do + let(:private_issue) { create(:issue, project: create(:project, :private)) } + +--- a/spec/requests/api/todos_spec.rb ++++ b/spec/requests/api/todos_spec.rb +@@ -183,12 +183,25 @@ + + expect(response.status).to eq(404) + end ++ ++ it 'returns an error if the issuable is not accessible' do ++ guest = create(:user) ++ project_1.team << [guest, :guest] ++ ++ post api("/projects/#{project_1.id}/#{issuable_type}/#{issuable.id}/todo", guest) ++ ++ if issuable_type == 'merge_requests' ++ expect(response).to have_http_status(403) ++ else ++ expect(response).to have_http_status(404) ++ end ++ end + end + + describe 'POST :id/issuable_type/:issueable_id/todo' do + context 'for an issue' do + it_behaves_like 'an issuable', 'issues' do +- let(:issuable) { create(:issue, author: author_1, project: project_1) } ++ let(:issuable) { create(:issue, :confidential, author: author_1, project: project_1) } + end + end + diff -Nru gitlab-8.13.11+dfsg/debian/patches/series gitlab-8.13.11+dfsg/debian/patches/series --- gitlab-8.13.11+dfsg/debian/patches/series 2017-03-23 17:16:50.000000000 +0530 +++ gitlab-8.13.11+dfsg/debian/patches/series 2018-03-11 20:07:56.000000000 +0530 @@ -10,3 +10,9 @@ 0210-use-jquery-ui-rails6.patch 0300-git-2-11-support.patch cve-2017-0882.patch +sec-release-8-13-12.patch +cve-2017-0926.patch +cve-2017-3710.patch +cve-2017-0918.patch +cve-2017-0925.patch +cve-2017-0916.patch
signature.asc
Description: OpenPGP digital signature
_______________________________________________ Pkg-ruby-extras-maintainers mailing list Pkg-ruby-extras-maintainers@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-ruby-extras-maintainers