diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-18 12:16:49 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-01-18 12:16:49 +0000 |
commit | fd8a91738ea9c6d2402bb2a2292cb4a6d5f46924 (patch) | |
tree | 190747692df5c18fd43b6bdf9058ca8b2a9965e8 /app/services/bulk_imports | |
parent | a4d8bae6275c0837b314ed6a1b2f6b17c9ba6c69 (diff) | |
download | gitlab-ce-fd8a91738ea9c6d2402bb2a2292cb4a6d5f46924.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/services/bulk_imports')
-rw-r--r-- | app/services/bulk_imports/archive_extraction_service.rb | 4 | ||||
-rw-r--r-- | app/services/bulk_imports/file_decompression_service.rb | 27 | ||||
-rw-r--r-- | app/services/bulk_imports/file_download_service.rb | 28 |
3 files changed, 40 insertions, 19 deletions
diff --git a/app/services/bulk_imports/archive_extraction_service.rb b/app/services/bulk_imports/archive_extraction_service.rb index 9fc828b8e34..caa40d98a76 100644 --- a/app/services/bulk_imports/archive_extraction_service.rb +++ b/app/services/bulk_imports/archive_extraction_service.rb @@ -28,8 +28,8 @@ module BulkImports end def execute - validate_filepath validate_tmpdir + validate_filepath validate_symlink extract_archive @@ -46,7 +46,7 @@ module BulkImports end def validate_tmpdir - raise(BulkImports::Error, 'Invalid target directory') unless File.expand_path(tmpdir).start_with?(Dir.tmpdir) + Gitlab::Utils.check_allowed_absolute_path!(tmpdir, [Dir.tmpdir]) end def validate_symlink diff --git a/app/services/bulk_imports/file_decompression_service.rb b/app/services/bulk_imports/file_decompression_service.rb index fe9017377ec..b76746b199f 100644 --- a/app/services/bulk_imports/file_decompression_service.rb +++ b/app/services/bulk_imports/file_decompression_service.rb @@ -1,21 +1,26 @@ # frozen_string_literal: true +# File Decompression Service allows gzipped files decompression into tmp directory. +# +# @param tmpdir [String] Temp directory to store downloaded file to. Must be located under `Dir.tmpdir`. +# @param filename [String] Name of the file to decompress. module BulkImports class FileDecompressionService include Gitlab::ImportExport::CommandLineUtil ServiceError = Class.new(StandardError) - def initialize(dir:, filename:) - @dir = dir + def initialize(tmpdir:, filename:) + @tmpdir = tmpdir @filename = filename - @filepath = File.join(@dir, @filename) + @filepath = File.join(@tmpdir, @filename) @decompressed_filename = File.basename(@filename, '.gz') - @decompressed_filepath = File.join(@dir, @decompressed_filename) + @decompressed_filepath = File.join(@tmpdir, @decompressed_filename) end def execute - validate_dir + validate_tmpdir + validate_filepath validate_decompressed_file_size if Feature.enabled?(:validate_import_decompressed_archive_size, default_enabled: :yaml) validate_symlink(filepath) @@ -33,10 +38,14 @@ module BulkImports private - attr_reader :dir, :filename, :filepath, :decompressed_filename, :decompressed_filepath + attr_reader :tmpdir, :filename, :filepath, :decompressed_filename, :decompressed_filepath - def validate_dir - raise(ServiceError, 'Invalid target directory') unless dir.start_with?(Dir.tmpdir) + def validate_filepath + Gitlab::Utils.check_path_traversal!(filepath) + end + + def validate_tmpdir + Gitlab::Utils.check_allowed_absolute_path!(tmpdir, [Dir.tmpdir]) end def validate_decompressed_file_size @@ -48,7 +57,7 @@ module BulkImports end def decompress_file - gunzip(dir: dir, filename: filename) + gunzip(dir: tmpdir, filename: filename) end def size_validator diff --git a/app/services/bulk_imports/file_download_service.rb b/app/services/bulk_imports/file_download_service.rb index d08dc72e30b..8d6ba54cd50 100644 --- a/app/services/bulk_imports/file_download_service.rb +++ b/app/services/bulk_imports/file_download_service.rb @@ -1,6 +1,13 @@ # frozen_string_literal: true -# Downloads a remote file. If no filename is given, it'll use the remote filename +# File Download Service allows remote file download into tmp directory. +# +# @param configuration [BulkImports::Configuration] Config object containing url and access token +# @param relative_url [String] Relative URL to download the file from +# @param tmpdir [String] Temp directory to store downloaded file to. Must be located under `Dir.tmpdir`. +# @param file_size_limit [Integer] Maximum allowed file size +# @param allowed_content_types [Array<String>] Allowed file content types +# @param filename [String] Name of the file to download, if known. Use remote filename if none given. module BulkImports class FileDownloadService ServiceError = Class.new(StandardError) @@ -13,20 +20,21 @@ module BulkImports def initialize( configuration:, relative_url:, - dir:, + tmpdir:, file_size_limit: DEFAULT_FILE_SIZE_LIMIT, allowed_content_types: DEFAULT_ALLOWED_CONTENT_TYPES, filename: nil) @configuration = configuration @relative_url = relative_url @filename = filename - @dir = dir + @tmpdir = tmpdir @file_size_limit = file_size_limit @allowed_content_types = allowed_content_types end def execute - validate_dir + validate_tmpdir + validate_filepath validate_url validate_content_type validate_content_length @@ -40,7 +48,7 @@ module BulkImports private - attr_reader :configuration, :relative_url, :dir, :file_size_limit, :allowed_content_types + attr_reader :configuration, :relative_url, :tmpdir, :file_size_limit, :allowed_content_types def download_file File.open(filepath, 'wb') do |file| @@ -76,8 +84,12 @@ module BulkImports @headers ||= http_client.head(relative_url).headers end - def validate_dir - raise(ServiceError, 'Invalid target directory') unless dir.start_with?(Dir.tmpdir) + def validate_filepath + Gitlab::Utils.check_path_traversal!(filepath) + end + + def validate_tmpdir + Gitlab::Utils.check_allowed_absolute_path!(tmpdir, [Dir.tmpdir]) end def validate_symlink @@ -119,7 +131,7 @@ module BulkImports end def filepath - @filepath ||= File.join(@dir, filename) + @filepath ||= File.join(@tmpdir, filename) end def filename |