129 lines
3.9 KiB
Diff
129 lines
3.9 KiB
Diff
|
From 056d35cad0e09a59fdf44cb6bd7063f73a970f01 Mon Sep 17 00:00:00 2001
|
||
|
From: James Lopez <james@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
|
||
|
|