diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-31 17:31:42 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-31 17:31:42 +0300 |
commit | d7fe9575a00f0e734977cc15a5af92e8674bb379 (patch) | |
tree | ecf120856d0d336ac38ca18d0d2c8b1a3a5ca1ee /lib | |
parent | 63a18ecf9b62aba2e0b8b739521c86cf9ce9c746 (diff) |
Add latest changes from gitlab-org/security/gitlab@16-1-stable-ee
Diffstat (limited to 'lib')
18 files changed, 49 insertions, 109 deletions
diff --git a/lib/banzai/filter/autolink_filter.rb b/lib/banzai/filter/autolink_filter.rb index bbddaa37380..336d60055e2 100644 --- a/lib/banzai/filter/autolink_filter.rb +++ b/lib/banzai/filter/autolink_filter.rb @@ -34,13 +34,8 @@ module Banzai # https://github.com/vmg/rinku/blob/v2.0.1/ext/rinku/autolink.c#L65 # # Rubular: http://rubular.com/r/nrL3r9yUiq - # Note that it's not possible to use Gitlab::UntrustedRegexp for LINK_PATTERN, - # as `(?<!` is unsupported in `re2`, see https://github.com/google/re2/wiki/Syntax LINK_PATTERN = %r{([a-z][a-z0-9\+\.-]+://[^\s>]+)(?<!\?|!|\.|,|:)}.freeze - ENTITY_UNTRUSTED = '((?:&[\w#]+;)+)\z' - ENTITY_UNTRUSTED_REGEX = Gitlab::UntrustedRegexp.new(ENTITY_UNTRUSTED, multiline: false) - # Text matching LINK_PATTERN inside these elements will not be linked IGNORE_PARENTS = %w(a code kbd pre script style).to_set @@ -90,14 +85,10 @@ module Banzai # Remove any trailing HTML entities and store them for appending # outside the link element. The entity must be marked HTML safe in # order to be output literally rather than escaped. - dropped = '' - match = ENTITY_UNTRUSTED_REGEX.replace_gsub(match) do |entities| - dropped = entities[1].html_safe - - '' - end + match.gsub!(/((?:&[\w#]+;)+)\z/, '') + dropped = (Regexp.last_match(1) || '').html_safe - # To match the behavior of Rinku, if the matched link ends with a + # To match the behaviour of Rinku, if the matched link ends with a # closing part of a matched pair of punctuation, we remove that trailing # character unless there are an equal number of closing and opening # characters in the link. diff --git a/lib/banzai/filter/plantuml_filter.rb b/lib/banzai/filter/plantuml_filter.rb index 7e6535b86fd..2e5f1b29c52 100644 --- a/lib/banzai/filter/plantuml_filter.rb +++ b/lib/banzai/filter/plantuml_filter.rb @@ -11,7 +11,7 @@ module Banzai def call return doc unless settings.plantuml_enabled? && doc.at_xpath(lang_tag) - Gitlab::Plantuml.configure + plantuml_setup doc.xpath(lang_tag).each do |node| img_tag = Nokogiri::HTML::DocumentFragment.parse( @@ -38,6 +38,15 @@ module Banzai def settings Gitlab::CurrentSettings.current_application_settings end + + def plantuml_setup + Asciidoctor::PlantUml.configure do |conf| + conf.url = settings.plantuml_url + conf.png_enable = settings.plantuml_enabled + conf.svg_enable = false + conf.txt_enable = false + end + end end end end diff --git a/lib/bulk_imports/common/pipelines/lfs_objects_pipeline.rb b/lib/bulk_imports/common/pipelines/lfs_objects_pipeline.rb index 9a22d211ba1..68bd64dc2ff 100644 --- a/lib/bulk_imports/common/pipelines/lfs_objects_pipeline.rb +++ b/lib/bulk_imports/common/pipelines/lfs_objects_pipeline.rb @@ -24,7 +24,7 @@ module BulkImports return if tar_filepath?(file_path) return if lfs_json_filepath?(file_path) return if File.directory?(file_path) - return if Gitlab::Utils::FileInfo.linked?(file_path) + return if File.lstat(file_path).symlink? size = File.size(file_path) oid = LfsObject.calculate_oid(file_path) diff --git a/lib/bulk_imports/common/pipelines/uploads_pipeline.rb b/lib/bulk_imports/common/pipelines/uploads_pipeline.rb index b1eeccf96f7..06132791ea6 100644 --- a/lib/bulk_imports/common/pipelines/uploads_pipeline.rb +++ b/lib/bulk_imports/common/pipelines/uploads_pipeline.rb @@ -24,7 +24,7 @@ module BulkImports # Validate that the path is OK to load Gitlab::PathTraversal.check_allowed_absolute_path_and_path_traversal!(file_path, [Dir.tmpdir]) return if File.directory?(file_path) - return if Gitlab::Utils::FileInfo.linked?(file_path) + return if File.lstat(file_path).symlink? avatar_path = AVATAR_PATTERN.match(file_path) return save_avatar(file_path) if avatar_path diff --git a/lib/bulk_imports/file_downloads/validations.rb b/lib/bulk_imports/file_downloads/validations.rb index e1844843408..b852a50c888 100644 --- a/lib/bulk_imports/file_downloads/validations.rb +++ b/lib/bulk_imports/file_downloads/validations.rb @@ -32,7 +32,7 @@ module BulkImports end def validate_symlink - return unless Gitlab::Utils::FileInfo.linked?(filepath) + return unless File.lstat(filepath).symlink? File.delete(filepath) raise_error 'Invalid downloaded file' diff --git a/lib/bulk_imports/projects/pipelines/design_bundle_pipeline.rb b/lib/bulk_imports/projects/pipelines/design_bundle_pipeline.rb index 235d2629b9e..373cd2bd75a 100644 --- a/lib/bulk_imports/projects/pipelines/design_bundle_pipeline.rb +++ b/lib/bulk_imports/projects/pipelines/design_bundle_pipeline.rb @@ -26,7 +26,7 @@ module BulkImports return unless portable.lfs_enabled? return unless File.exist?(bundle_path) return if File.directory?(bundle_path) - return if Gitlab::Utils::FileInfo.linked?(bundle_path) + return if File.lstat(bundle_path).symlink? portable.design_repository.create_from_bundle(bundle_path) end diff --git a/lib/bulk_imports/projects/pipelines/repository_bundle_pipeline.rb b/lib/bulk_imports/projects/pipelines/repository_bundle_pipeline.rb index 4307cb2bafd..f19d8931f4a 100644 --- a/lib/bulk_imports/projects/pipelines/repository_bundle_pipeline.rb +++ b/lib/bulk_imports/projects/pipelines/repository_bundle_pipeline.rb @@ -26,7 +26,7 @@ module BulkImports return unless File.exist?(bundle_path) return if File.directory?(bundle_path) - return if Gitlab::Utils::FileInfo.linked?(bundle_path) + return if File.lstat(bundle_path).symlink? portable.repository.create_from_bundle(bundle_path) end diff --git a/lib/gitlab/asciidoc.rb b/lib/gitlab/asciidoc.rb index 31e8dcd84b7..955cb14594f 100644 --- a/lib/gitlab/asciidoc.rb +++ b/lib/gitlab/asciidoc.rb @@ -78,11 +78,20 @@ module Gitlab context[:pipeline] = :ascii_doc context[:max_includes] = [MAX_INCLUDES, context[:max_includes]].compact.min - Gitlab::Plantuml.configure + plantuml_setup html = ::Asciidoctor.convert(input, asciidoc_opts) html = Banzai.render(html, context) html.html_safe end + + def self.plantuml_setup + Asciidoctor::PlantUml.configure do |conf| + conf.url = Gitlab::CurrentSettings.plantuml_url + conf.svg_enable = Gitlab::CurrentSettings.plantuml_enabled + conf.png_enable = Gitlab::CurrentSettings.plantuml_enabled + conf.txt_enable = false + end + end end end diff --git a/lib/gitlab/ci/decompressed_gzip_size_validator.rb b/lib/gitlab/ci/decompressed_gzip_size_validator.rb index b386e400423..9b7b5f0dd66 100644 --- a/lib/gitlab/ci/decompressed_gzip_size_validator.rb +++ b/lib/gitlab/ci/decompressed_gzip_size_validator.rb @@ -65,7 +65,7 @@ module Gitlab def validate_archive_path Gitlab::PathTraversal.check_path_traversal!(archive_path) - raise(ServiceError, 'Archive path is a symlink or hard link') if Gitlab::Utils::FileInfo.linked?(archive_path) + raise(ServiceError, 'Archive path is a symlink') if File.lstat(archive_path).symlink? raise(ServiceError, 'Archive path is not a file') unless File.file?(archive_path) end diff --git a/lib/gitlab/import_export/command_line_util.rb b/lib/gitlab/import_export/command_line_util.rb index e2f365fcbf8..d681f39f00b 100644 --- a/lib/gitlab/import_export/command_line_util.rb +++ b/lib/gitlab/import_export/command_line_util.rb @@ -5,11 +5,8 @@ module Gitlab module CommandLineUtil UNTAR_MASK = 'u+rwX,go+rX,go-w' DEFAULT_DIR_MODE = 0700 - CLEAN_DIR_IGNORE_FILE_NAMES = %w[. ..].freeze - CommandLineUtilError = Class.new(StandardError) - FileOversizedError = Class.new(CommandLineUtilError) - HardLinkError = Class.new(CommandLineUtilError) + FileOversizedError = Class.new(StandardError) def tar_czf(archive:, dir:) tar_with_options(archive: archive, dir: dir, options: 'czf') @@ -93,7 +90,7 @@ module Gitlab def untar_with_options(archive:, dir:, options:) execute_cmd(%W(tar -#{options} #{archive} -C #{dir})) execute_cmd(%W(chmod -R #{UNTAR_MASK} #{dir})) - clean_extraction_dir!(dir) + remove_symlinks(dir) end # rubocop:disable Gitlab/ModuleWithInstanceVariables @@ -125,27 +122,17 @@ module Gitlab true end - # Scans and cleans the directory tree. - # Symlinks are considered legal but are removed. - # Files sharing hard links are considered illegal and the directory will be removed - # and a `HardLinkError` exception will be raised. - # - # @raise [HardLinkError] if there multiple hard links to the same file detected. - # @return [Boolean] true - def clean_extraction_dir!(dir) - # Using File::FNM_DOTMATCH to also delete symlinks starting with "." - Dir.glob("#{dir}/**/*", File::FNM_DOTMATCH).each do |filepath| - next if CLEAN_DIR_IGNORE_FILE_NAMES.include?(File.basename(filepath)) - - raise HardLinkError, 'File shares hard link' if Gitlab::Utils::FileInfo.shares_hard_link?(filepath) + def remove_symlinks(dir) + ignore_file_names = %w[. ..] - FileUtils.rm(filepath) if Gitlab::Utils::FileInfo.linked?(filepath) - end + # Using File::FNM_DOTMATCH to also delete symlinks starting with "." + Dir.glob("#{dir}/**/*", File::FNM_DOTMATCH) + .reject { |f| ignore_file_names.include?(File.basename(f)) } + .each do |filepath| + FileUtils.rm(filepath) if File.lstat(filepath).symlink? + end true - rescue HardLinkError - FileUtils.remove_dir(dir) - raise end end end diff --git a/lib/gitlab/import_export/decompressed_archive_size_validator.rb b/lib/gitlab/import_export/decompressed_archive_size_validator.rb index 2e39f3f38c2..104c9e6c456 100644 --- a/lib/gitlab/import_export/decompressed_archive_size_validator.rb +++ b/lib/gitlab/import_export/decompressed_archive_size_validator.rb @@ -87,7 +87,7 @@ module Gitlab def validate_archive_path Gitlab::PathTraversal.check_path_traversal!(@archive_path) - raise(ServiceError, 'Archive path is a symlink or hard link') if Gitlab::Utils::FileInfo.linked?(@archive_path) + raise(ServiceError, 'Archive path is a symlink') if File.lstat(@archive_path).symlink? raise(ServiceError, 'Archive path is not a file') unless File.file?(@archive_path) end diff --git a/lib/gitlab/import_export/file_importer.rb b/lib/gitlab/import_export/file_importer.rb index 37c83e88ef2..d2593289c23 100644 --- a/lib/gitlab/import_export/file_importer.rb +++ b/lib/gitlab/import_export/file_importer.rb @@ -23,7 +23,7 @@ module Gitlab mkdir_p(@shared.export_path) mkdir_p(@shared.archive_path) - clean_extraction_dir!(@shared.export_path) + remove_symlinks(@shared.export_path) copy_archive wait_for_archived_file do @@ -35,7 +35,7 @@ module Gitlab false ensure remove_import_file - clean_extraction_dir!(@shared.export_path) + remove_symlinks(@shared.export_path) end private diff --git a/lib/gitlab/import_export/json/ndjson_reader.rb b/lib/gitlab/import_export/json/ndjson_reader.rb index 93a94716f8d..3de56aacf18 100644 --- a/lib/gitlab/import_export/json/ndjson_reader.rb +++ b/lib/gitlab/import_export/json/ndjson_reader.rb @@ -21,9 +21,7 @@ module Gitlab # This reads from `tree/project.json` path = file_path("#{importable_path}.json") - if !File.exist?(path) || Gitlab::Utils::FileInfo.linked?(path) - raise Gitlab::ImportExport::Error, 'Invalid file' - end + raise Gitlab::ImportExport::Error, 'Invalid file' if !File.exist?(path) || File.symlink?(path) data = File.read(path, MAX_JSON_DOCUMENT_SIZE) json_decode(data) @@ -36,7 +34,7 @@ module Gitlab # This reads from `tree/project/merge_requests.ndjson` path = file_path(importable_path, "#{key}.ndjson") - next if !File.exist?(path) || Gitlab::Utils::FileInfo.linked?(path) + next if !File.exist?(path) || File.symlink?(path) File.foreach(path, MAX_JSON_DOCUMENT_SIZE).with_index do |line, line_num| documents << [json_decode(line), line_num] diff --git a/lib/gitlab/import_export/recursive_merge_folders.rb b/lib/gitlab/import_export/recursive_merge_folders.rb index e6eba60db93..827385d4daf 100644 --- a/lib/gitlab/import_export/recursive_merge_folders.rb +++ b/lib/gitlab/import_export/recursive_merge_folders.rb @@ -57,7 +57,7 @@ module Gitlab source_child = File.join(source_path, child) target_child = File.join(target_path, child) - next if Gitlab::Utils::FileInfo.linked?(source_child) + next if File.lstat(source_child).symlink? if File.directory?(source_child) FileUtils.mkdir_p(target_child, mode: DEFAULT_DIR_MODE) unless File.exist?(target_child) diff --git a/lib/gitlab/pages/virtual_host_finder.rb b/lib/gitlab/pages/virtual_host_finder.rb index d5e2159fb52..5fec60188f8 100644 --- a/lib/gitlab/pages/virtual_host_finder.rb +++ b/lib/gitlab/pages/virtual_host_finder.rb @@ -10,12 +10,13 @@ module Gitlab def execute return if host.blank? - gitlab_host = ::Gitlab.config.pages.host.downcase.prepend(".") + gitlab_host = ::Settings.pages.host.downcase.prepend(".") if host.ends_with?(gitlab_host) name = host.delete_suffix(gitlab_host) - by_unique_domain(name) || by_namespace_domain(name) + by_namespace_domain(name) || + by_unique_domain(name) else by_custom_domain(host) end diff --git a/lib/gitlab/path_regex.rb b/lib/gitlab/path_regex.rb index 8afcf682d5d..e112423f167 100644 --- a/lib/gitlab/path_regex.rb +++ b/lib/gitlab/path_regex.rb @@ -131,7 +131,7 @@ module Gitlab # `NAMESPACE_FORMAT_REGEX`, with the negative lookbehind assertion removed. This means that the client-side validation # will pass for usernames ending in `.atom` and `.git`, but will be caught by the server-side validation. PATH_START_CHAR = '[a-zA-Z0-9_\.]' - PATH_REGEX_STR = PATH_START_CHAR + '[a-zA-Z0-9_\-\.]' + "{0,#{Namespace::URL_MAX_LENGTH - 1}}" + PATH_REGEX_STR = PATH_START_CHAR + '[a-zA-Z0-9_\-\.]*' NAMESPACE_FORMAT_REGEX_JS = PATH_REGEX_STR + '[a-zA-Z0-9_\-]|[a-zA-Z0-9_]' NO_SUFFIX_REGEX = /(?<!\.git|\.atom)/.freeze diff --git a/lib/gitlab/plantuml.rb b/lib/gitlab/plantuml.rb deleted file mode 100644 index 9ec544452fd..00000000000 --- a/lib/gitlab/plantuml.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true - -require "asciidoctor_plantuml/plantuml" - -module Gitlab - module Plantuml - class << self - def configure - Asciidoctor::PlantUml.configure do |conf| - conf.url = Gitlab::CurrentSettings.plantuml_url - conf.png_enable = Gitlab::CurrentSettings.plantuml_enabled - conf.svg_enable = false - conf.txt_enable = false - - conf - end - end - end - end -end diff --git a/lib/gitlab/utils/file_info.rb b/lib/gitlab/utils/file_info.rb deleted file mode 100644 index a0ec370e225..00000000000 --- a/lib/gitlab/utils/file_info.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module Utils - module FileInfo - class << self - # Returns true if: - # - File or directory is a symlink. - # - File shares a hard link. - def linked?(file) - stat = to_file_stat(file) - - stat.symlink? || shares_hard_link?(stat) - end - - # Returns: - # - true if file shares a hard link with another file. - # - false if file is a directory, as directories cannot be hard linked. - def shares_hard_link?(file) - stat = to_file_stat(file) - - stat.file? && stat.nlink > 1 - end - - private - - def to_file_stat(filepath_or_stat) - return filepath_or_stat if filepath_or_stat.is_a?(File::Stat) - - File.lstat(filepath_or_stat) - end - end - end - end -end |