ОРИГИНАЛЬНАЯ СТАТЬЯ
ПЕРЕВЕДЕНО СПЕЦИАЛЬНО ДЛЯ xss.pro
$600 на SSD для Solidity hacking by Jolah Milovsky---> 0x5B1f2Ac9cF5616D9d7F1819d1519912e85eb5C09
В начале этого месяца GitLab выпустил патч безопасности для версий 14->15. Интересно, что в бюллетене упоминалась ошибка RCE после аутентификации в CVSS 9.9.
Ошибка существует в GitLab Project Importsфункция, которую нашел @vakzz . Кстати, когда я рылся в профиле автора h1. Я обнаружил, что четыре месяца назад он также нашел ошибку в функции импорта проекта:
Сначала я подумал, что это заманчиво, увидев награду, поэтому начал изучать Rails и отладил эту ошибку! (кто бы мог подумать, что 30к не будет так просто (° ͜ʖ ͡°))
Обратите внимание, что статья может быть длиннее, чем обычно. Вы можете прочитать его на досуге, но если вам просто нужен PoC, вы можете перейти к концу, чтобы посмотреть видео!
В моей среде используется виртуальная машина с Ubuntu Desktop 18.04. Первый — сначала настроить набор GitLab GDK:
Подождите 15-30 минут, и мы завершим настройку GDK. Теперь мы можем проверить уязвимую версию GitLab:
После оформления отредактируйте следующие файлы:
После редактирования перейдите в папку GitLab/ и введите следующую команду для компиляции ресурсов сервера:
Когда вы закончите редактирование файлов конфигурации, введите следующие команды, чтобы запустить соответствующие службы:
Что касается IDE, я использую RubyMine (продукт Jetbrains) . Используя RubyMine, мы можем просмотреть и открыть gitlabпапка. Среда IDE автоматически обнаружит и установит соответствующие компоненты. Добавьте конфигурацию отладки, открыв Run > Edit Configurations
Добавьте в Railsконфиг, как показано ниже:
Затем добавьте в sidekiqконфигурация:
В случае использования клона исходного кода из репозитория GitLab конфиги для отладки уже доступны.
Отсюда можно начинать отладку, хотя sidekiqworker может работать нестабильно. В настоящее время я до сих пор не знаю, почему иногда он пропускал работу.
Коммит 5d58c705 имеет интересное название и звук, связанный с этой ошибкой. security-update-bulk-imports-project-pipeline-15 -1
Некоторые замечательные изменения в этом коммите: В lib/gitlab/import_export/decompressed_archive_size_validator.rb
После validate_archive_path, этот метод продолжит вызывать Open3.popen3(command, pgroup: true)для запуска команды. Объявление команды выглядит следующим образом:
Этот метод напрямую добавляет строку @archive_pathк команде gzip -dc, поэтому я предполагаю, что ошибка внедрения команды происходит в этом месте!
учебный класс DecompressedArchiveSizeValidatorиспользуется в 2-х местах:
Сначала мы рассмотрим file_importer.rbфилиал, Мы начинаем с Import::GitlabProjectsControllerи он создает и вызывает Projects::GitlabProjectsImportService.new(current_user, project_params).executeдля создания работы.
Lines 17, 18 and 19были прокомментированы для облегчения отладки. Я не понимаю, почему среда отладки с GDK неисправна. Все загруженные файлы считаются недействительными!! Эта проблема не возникает в версиях продукта.
project_params, который использовался для создания проекта, был ограничен, позволяя передавать только параметры: name, path, namespace_id, file
Трассировка стека в это место:
Из GitlabProjectsImportService.executeпродолжать звонить prepare_import_paramsредактировать, добавлять и удалять другие важные параметры (1)
Затем, GitlabProjectsImportService.execute Projects::CreateService.execute снова, чтобы создать проект с параметрами, переданными из GitlabProjectsController. В Projects::CreateService.execute, если импортируемый проект не является шаблоном, метод продолжит инициализацию объекта Project с переданными параметрами:
Как только проект будет создан, метод продолжит переходить в ветку, вызывающую validate_import_source_enabled! import_type:
Будет две ветки, которые будут удовлетворять условию, причем первое условие, import_typeпринадлежность к одному из следующих типов.
INTERNAL_IMPORT_SOURCES = %w[bare_repository gitlab_custom_project_template gitlab_project_migration].freeze
Во втором случае import_type должен быть в списке Gitlab::CurrentSettings.import_sources:
После создания объекта Project и выполнения других различных модификаций этот метод вызовет Projects::CreateService.import_scheduleчтобы добавить расписание для работника, чтобы сделать импорт:
Для добавления в расписание импорта этот проект должен иметь тип импорта gitlab_project.
После добавления в расписание рабочий получит задание и выполнит следующее:
Stacktrace к DecompressedArchiveSizeValidator.execute
Однако, согласно этой ветке, мы не можем контролировать @archive_path
@archive_fileберется из Project.import_source. Однако этот атрибут не установлен по умолчанию и имеет нулевое значение!
Это значение остается нулевым в Gitlab::ImportExport::FileImporter.new
Только при Gitlab::ImportExport::FileImporter.copy_archive, будет ли установлено это значение:
@archive_file_name генерируется на основе полного_пути проекта, поэтому этим значением нельзя манипулировать. Согласно этой ветке, у нас не может быть внедрения команды ошибки ¯_(ツ)_/¯
Эта ветвь довольно сложна для анализа и требует дополнительных сведений, чтобы получить доступ к нужной полезной нагрузке.
Во-первых, вы должны перейти к функции группы импорта GitLab и заполнить информацию, такую как URL-адрес GitLab и токен доступа.
После его правильного заполнения мы попадем на страницу импорта. Просто нажмите кнопку «Импорт», чтобы начать импорт:
Вернемся к истории запросов Burpsuite:
Searching for the group_entity ключевое слово в исходном коде, я обнаружил, что помимо group_entity, существует также project_entity:
Я не могу найти эту функцию в Интернете или в каком-либо документе. Скорее всего, это скрытая, развивающаяся фича GitLab!
Эта функция массового импорта обрабатывается Import::BulkImportsController.
После выполнения create_bulk_import, BulkImportsController.execute метод продолжает вызывать BulkImportWorker.perform_async, содержание метода следующее:
Обратите внимание на вызов BulkImports::CreatePipelineTrackersService.new(entity.execute!). Этот метод рассматривает, какие конвейеры подходят для выполнения с переданными параметрами:
Например, с project_entity, у нас есть такие конвейеры:
Конвейеры будут иметь объявления и методы переопределения, такие как extract, transform, loadа также after_run.
Бегун будет просматривать и выполнять эти методы по порядку: extract data, transform data, load data, after_run
И будет выполнять конвейеры по очереди в порядке, указанном в stage.rb файл.
Возвращаясь к проекту массового импорта, конвейер ProjectPipeline будет выполняться первым.
Содержимое ProjectPipeline:
в ProjectPipeline.load, есть звонок Projects::CreateService.executeс параметром params = data. Как
ProjectPipeline:
extractor ::BulkImports::Common::Extractors::GraphqlExtractor, query: Graphql::GetProjectQuery
transformer ::BulkImports::Common:
ransformers::ProhibitedAttributesTransformer
transformer ::BulkImports::Projects:
ransformers::ProjectAttributesTransformer
Согласно потоку Pipeline:
Здесь отчетливо видно, что количество переменных, подлежащих извлечению, в основном уменьшено.
Вот пример данных, полученных из GraphqlExtractor:
С ProhibitedAttributesTransformer, основная функция этого преобразователя — удалить некоторые чувствительные атрибуты:
С ProjectAttributesTransformer.execute:
Этот метод берет данные, делает несколько дополнительных шагов для установки необходимых атрибутов, таких как import_type, name, pathа потом звонит data. transform_keys!(&
o_sym) для выполнения конвертации. Все ключи хэша только что перешли в форму символа.
// В Ruby есть концепция Symbol vs String. Примерно символ будет иметь двоеточие «:» впереди
Вот пример после выполнения data.transform_keys!(&
o_sym)
В исправлении фиксации ProjectAttributesTransformer, вместо того, чтобы принимать полученное data, этот преобразователь создал новый хэш и добавил только некоторые необходимые ключи/значения и вернул чистый хеш, что означает, что другие атрибуты не были добавлены:
В настоящее время, data после извлечения и преобразования будут переданы в Projects::CreateService.execute
К сожалению, проекты, созданные из ProjectPipeline, могут иметь только import_type = gitlab_project_migration
Однако на import_schedule, этот проект будет отклонен по условию !@project.gitlab_project_migration?
Хотя можно управлять атрибутами объекта Project, самый важный атрибут был перезаписан, и нет возможности его переопределить (на самом деле да, но я расскажу об этом в другом посте).
До последних нескольких дней я находил другой способ ускорить отладку без включения сервера GitLab, а именно использовать для отладки GitLab RSpec. Удобство этого метода заключается в том, чтобы не ждать sidekiq
Оттуда я начал отлаживать ProjectPipeline с помощью project_pipeline_spec.rb, изменить некоторые данные, связанные с project_dataа затем запустите его:
Благодаря этому моя отладка проходит очень быстро, и я достиг новых результатов.
После внимательного повторного прочтения Projects::CreateService.executeветка, я понял, что пропустил ветку обработки шаблона:
Эта ветвь звонит Projects::CreateFromTemplateService.executeс params, который dataвзято из ProjectPipeline.
Этот метод в основном проверяет наличие template_name, затем звонит GitlabProjectsImportService.execute вместе с paramsдля дальнейшей обработки:
Как обсуждалось в части 1, GitlabProjectsImportService.execute затем позвонит prepare_import_paramsдля обработки параметров:
Здесь, если template_file существует, программа перезапишет параметр import_typeк gitlab_project.
После обработки параметра GitlabProjectsImportService.execute позвоню Projects::CreateService.execute чтобы воссоздать проект с измененными параметрами.
Итак import_type был изменен на gitlab_project, который по-прежнему повторно использует старый Pipeline params=> RCE ( ͡° ͜ʖ ͡°)( ͡° ͜ʖ ͡°)( ͡° ͜ʖ ͡°)
Там было примечание, что введенная команда не будет выполнена немедленно!
В Gitlab::ImportExport::FileImporter.import, wait_for_archived_file метод будет вызываться для ожидания @archive_file наличие перед входом в нижнюю обрабатывающую ветку (ветвь, в которую мы вводим команду)
Содержание wait_for_archived_file:
С MAX_RETRIES= 8, эта программа будет выполнять цикл 8 раз, чтобы дождаться существования файла, каждый раз, когда она будет спать 2 ^ i, я применяю формулу для вычисления суммы степенного ряда. Это могут проверить первокурсники, и мы знаем, что нам придется ждать 2^8 -1 = 255 секунд, если файл не существует:
И в случае, если файл не существует, этот метод также продолжает вызывать yield внизу, что означает, что операторы после wait_for_archived_fileпо-прежнему вызываются нормально, например:
На данный момент с этим багом все понятно, хотя процесс чтения Ruby/Rails достаточно болезненный, но и он приносит много знаний и кое-что интересное.
Если видео не удалось загрузить, вот резервная копия
Спасибо за чтение!
© 2022 СТАР Лабс Питаться от Хьюго и БумагаМод
ПЕРЕВЕДЕНО СПЕЦИАЛЬНО ДЛЯ xss.pro
$600 на SSD для Solidity hacking by Jolah Milovsky---> 0x5B1f2Ac9cF5616D9d7F1819d1519912e85eb5C09
В начале этого месяца GitLab выпустил патч безопасности для версий 14->15. Интересно, что в бюллетене упоминалась ошибка RCE после аутентификации в CVSS 9.9.
Ошибка существует в GitLab Project Importsфункция, которую нашел @vakzz . Кстати, когда я рылся в профиле автора h1. Я обнаружил, что четыре месяца назад он также нашел ошибку в функции импорта проекта:
Сначала я подумал, что это заманчиво, увидев награду, поэтому начал изучать Rails и отладил эту ошибку! (кто бы мог подумать, что 30к не будет так просто (° ͜ʖ ͡°))
Обратите внимание, что статья может быть длиннее, чем обычно. Вы можете прочитать его на досуге, но если вам просто нужен PoC, вы можете перейти к концу, чтобы посмотреть видео!
НАСТРОЙКА СРЕДЫ И ОТЛАДКА
Эта часть также относительно громоздка и сложна, требуя терпения с позиции Re-searcher! Сначала я обратился к сообщению друга в Sun*, чтобы настроить среду. Но после запуска он был довольно медленным и очень ненадежным, поэтому я решил установить его самостоятельно!В моей среде используется виртуальная машина с Ubuntu Desktop 18.04. Первый — сначала настроить набор GitLab GDK:
Код:
apt update
apt install make git -y
curl "https://gitlab.com/gitlab-org/gitlab-development-kit/-/raw/main/support/install" | bash
Подождите 15-30 минут, и мы завершим настройку GDK. Теперь мы можем проверить уязвимую версию GitLab:
Код:
cd gitlab-development-kit/gitlab/
git checkout v15.1.0-ee
После оформления отредактируйте следующие файлы:
- config/gitlab.yml, найдите строку конфигурации хоста gitlab и измените ее на IP-адрес виртуальной машины, чтобы вы могли просматривать снаружи
Код:
gitlab:
## Web server settings (note: host is the FQDN, do not include http://)
host: 192.168.139.137
port: 3000
https: false
/[CODE]
Найдите строки с ключом webpackи установить enabledк false:
[CODE]
webpack:
dev_server:
enabled: false
Код:
rake gitlab:assets:compile
- config/puma.rb, найдите строку, объявляющую workersи снова комментарий:
Когда вы закончите редактирование файлов конфигурации, введите следующие команды, чтобы запустить соответствующие службы:
Код:
gdk stop
gdk start webpack rails-background-jobs sshd praefect praefect-gitaly-0 redis postgresql
Добавьте в Railsконфиг, как показано ниже:
Затем добавьте в sidekiqконфигурация:
В случае использования клона исходного кода из репозитория GitLab конфиги для отладки уже доступны.
Отсюда можно начинать отладку, хотя sidekiqworker может работать нестабильно. В настоящее время я до сих пор не знаю, почему иногда он пропускал работу.
CVE-2022-2185 АНАЛИЗ
Я полагаюсь на более раннюю ошибку, о которой сообщил @vakzz, чтобы проанализировать эту ошибку. Хотя взаимосвязь между обеими ошибками едва ли значительна в том смысле, что только точка входа одинакова, а все остальные методы разные, я бы порекомендовал вам сначала прочитать это здесь, где вы обнаружите, что некоторые методы могут быть связаны со старым.Исправлены версии 15.1.1, 14.10.5. Я выбираю v15.1.1, чтобы начать охоту
Читая коммиты на gitlab-v15.1.1 , мне повезло, что коммитов не так много, но я нашел замечательный коммит ниже:
Коммит 5d58c705 имеет интересное название и звук, связанный с этой ошибкой. security-update-bulk-imports-project-pipeline-15 -1
Некоторые замечательные изменения в этом коммите: В lib/gitlab/import_export/decompressed_archive_size_validator.rb
Код:
The validate_archive_pathметод проверяет случаи, когда @archive_pathэто символическая ссылка, а не строка и не файл.
def validate_archive_path
Gitlab::Utils.check_path_traversal!(@archive_path)
raise(ServiceError, 'Archive path is not a string') unless @archive_path.is_a?(String)
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
Код:
def command
"gzip -dc #{@archive_path} | wc -c"
end
учебный класс DecompressedArchiveSizeValidatorиспользуется в 2-х местах:
- file_importer.rb
- file_decompression_service.rb
Дополнительное примечание о воркерах в GitLab
Gitlab работает по такому механизму, что веб-интерфейс выполняет только обработку общих задач. Для более тяжелых задач используется sidekiqкак рабочие, выполняющие задания, которые выталкиваются из веб-контроллера. Это также является причиной того, что при настройке среды отладки вам придется добавить конфигурацию отладки для sidekiq.Случай 1:
Сначала мы рассмотрим file_importer.rbфилиал, Мы начинаем с Import::GitlabProjectsControllerи он создает и вызывает Projects::GitlabProjectsImportService.new(current_user, project_params).executeдля создания работы.
Lines 17, 18 and 19были прокомментированы для облегчения отладки. Я не понимаю, почему среда отладки с GDK неисправна. Все загруженные файлы считаются недействительными!! Эта проблема не возникает в версиях продукта.
project_params, который использовался для создания проекта, был ограничен, позволяя передавать только параметры: name, path, namespace_id, file
Трассировка стека в это место:
Из GitlabProjectsImportService.executeпродолжать звонить prepare_import_paramsредактировать, добавлять и удалять другие важные параметры (1)
Затем, GitlabProjectsImportService.execute Projects::CreateService.execute снова, чтобы создать проект с параметрами, переданными из GitlabProjectsController. В Projects::CreateService.execute, если импортируемый проект не является шаблоном, метод продолжит инициализацию объекта Project с переданными параметрами:
Как только проект будет создан, метод продолжит переходить в ветку, вызывающую validate_import_source_enabled! import_type:
Будет две ветки, которые будут удовлетворять условию, причем первое условие, import_typeпринадлежность к одному из следующих типов.
INTERNAL_IMPORT_SOURCES = %w[bare_repository gitlab_custom_project_template gitlab_project_migration].freeze
Во втором случае import_type должен быть в списке Gitlab::CurrentSettings.import_sources:
После создания объекта Project и выполнения других различных модификаций этот метод вызовет Projects::CreateService.import_scheduleчтобы добавить расписание для работника, чтобы сделать импорт:
Код:
def import_schedule
if @project.errors.empty?
@project.import_state.schedule if @project.import? && !@project.bare_repository_import? && !@project.gitlab_project_migration?
else
fail(error: @project.errors.full_messages.join(', '))
end
end
Для добавления в расписание импорта этот проект должен иметь тип импорта gitlab_project.
После добавления в расписание рабочий получит задание и выполнит следующее:
Stacktrace к DecompressedArchiveSizeValidator.execute
Однако, согласно этой ветке, мы не можем контролировать @archive_path
@archive_fileберется из Project.import_source. Однако этот атрибут не установлен по умолчанию и имеет нулевое значение!
Это значение остается нулевым в Gitlab::ImportExport::FileImporter.new
Только при Gitlab::ImportExport::FileImporter.copy_archive, будет ли установлено это значение:
@archive_file_name генерируется на основе полного_пути проекта, поэтому этим значением нельзя манипулировать. Согласно этой ветке, у нас не может быть внедрения команды ошибки ¯_(ツ)_/¯
Случай 2
The file_importer.rbветка была подтверждена как неэксплуатируемая, поэтому я переключился на вторую ветку для анализа. Вторая ветвь file_decompression_service.rb
Эта ветвь довольно сложна для анализа и требует дополнительных сведений, чтобы получить доступ к нужной полезной нагрузке.
Во-первых, вы должны перейти к функции группы импорта GitLab и заполнить информацию, такую как URL-адрес GitLab и токен доступа.
После его правильного заполнения мы попадем на страницу импорта. Просто нажмите кнопку «Импорт», чтобы начать импорт:
Вернемся к истории запросов Burpsuite:
Searching for the group_entity ключевое слово в исходном коде, я обнаружил, что помимо group_entity, существует также project_entity:
Я не могу найти эту функцию в Интернете или в каком-либо документе. Скорее всего, это скрытая, развивающаяся фича GitLab!
Эта функция массового импорта обрабатывается Import::BulkImportsController.
После выполнения create_bulk_import, BulkImportsController.execute метод продолжает вызывать BulkImportWorker.perform_async, содержание метода следующее:
Обратите внимание на вызов BulkImports::CreatePipelineTrackersService.new(entity.execute!). Этот метод рассматривает, какие конвейеры подходят для выполнения с переданными параметрами:
Например, с project_entity, у нас есть такие конвейеры:
Примечания сайта о конвейере в массовом импорте
Эта концепция является эксклюзивной для массового импорта. Исполняемый файл для этих конвейеров lib/bulk_imports/pipeline/runner.rb.
Конвейеры будут иметь объявления и методы переопределения, такие как extract, transform, loadа также after_run.
Бегун будет просматривать и выполнять эти методы по порядку: extract data, transform data, load data, after_run
И будет выполнять конвейеры по очереди в порядке, указанном в stage.rb файл.
Возвращаясь к проекту массового импорта, конвейер ProjectPipeline будет выполняться первым.
Содержимое ProjectPipeline:
в ProjectPipeline.load, есть звонок Projects::CreateService.executeс параметром params = data. Как
ProjectPipeline:
extractor ::BulkImports::Common::Extractors::GraphqlExtractor, query: Graphql::GetProjectQuery
transformer ::BulkImports::Common:
transformer ::BulkImports::Projects:
Согласно потоку Pipeline:
- GraphqlExtractor.extract будет получать данные от цели через graphql
- ProhibitedAttributesTransformer& ProjectAttributesTransformerизменит полученные данные
Здесь отчетливо видно, что количество переменных, подлежащих извлечению, в основном уменьшено.
Вот пример данных, полученных из GraphqlExtractor:
С ProhibitedAttributesTransformer, основная функция этого преобразователя — удалить некоторые чувствительные атрибуты:
С ProjectAttributesTransformer.execute:
Этот метод берет данные, делает несколько дополнительных шагов для установки необходимых атрибутов, таких как import_type, name, pathа потом звонит data. transform_keys!(&
// В Ruby есть концепция Symbol vs String. Примерно символ будет иметь двоеточие «:» впереди
Вот пример после выполнения data.transform_keys!(&
- И помни, dataпо-прежнему полностью управляем, поскольку он извлекается из GraphQL, GraphQL и берется с нашего веб-сайта.
В исправлении фиксации ProjectAttributesTransformer, вместо того, чтобы принимать полученное data, этот преобразователь создал новый хэш и добавил только некоторые необходимые ключи/значения и вернул чистый хеш, что означает, что другие атрибуты не были добавлены:
В настоящее время, data после извлечения и преобразования будут переданы в Projects::CreateService.execute
К сожалению, проекты, созданные из ProjectPipeline, могут иметь только import_type = gitlab_project_migration
Однако на import_schedule, этот проект будет отклонен по условию !@project.gitlab_project_migration?
Код:
def import_schedule
if @project.errors.empty?
@project.import_state.schedule if @project.import? && !@project.bare_repository_import? && !@project.gitlab_project_migration?
else
fail(error: @project.errors.full_messages.join(', '))
end
end
Хотя можно управлять атрибутами объекта Project, самый важный атрибут был перезаписан, и нет возможности его переопределить (на самом деле да, но я расскажу об этом в другом посте).
Случай 1 + 2 = 3
И… я застрял там почти на 2 недели, выясняя возможности отладки ruby. Иногда он касается точки останова, а иногда нет. Иногда RubyMine внезапно падает, что вызывает у меня головную боль.До последних нескольких дней я находил другой способ ускорить отладку без включения сервера GitLab, а именно использовать для отладки GitLab RSpec. Удобство этого метода заключается в том, чтобы не ждать sidekiq
Оттуда я начал отлаживать ProjectPipeline с помощью project_pipeline_spec.rb, изменить некоторые данные, связанные с project_dataа затем запустите его:
Благодаря этому моя отладка проходит очень быстро, и я достиг новых результатов.
После внимательного повторного прочтения Projects::CreateService.executeветка, я понял, что пропустил ветку обработки шаблона:
Эта ветвь звонит Projects::CreateFromTemplateService.executeс params, который dataвзято из ProjectPipeline.
Этот метод в основном проверяет наличие template_name, затем звонит GitlabProjectsImportService.execute вместе с paramsдля дальнейшей обработки:
Как обсуждалось в части 1, GitlabProjectsImportService.execute затем позвонит prepare_import_paramsдля обработки параметров:
Здесь, если template_file существует, программа перезапишет параметр import_typeк gitlab_project.
После обработки параметра GitlabProjectsImportService.execute позвоню Projects::CreateService.execute чтобы воссоздать проект с измененными параметрами.
Итак import_type был изменен на gitlab_project, который по-прежнему повторно использует старый Pipeline params=> RCE ( ͡° ͜ʖ ͡°)( ͡° ͜ʖ ͡°)( ͡° ͜ʖ ͡°)
Там было примечание, что введенная команда не будет выполнена немедленно!
В Gitlab::ImportExport::FileImporter.import, wait_for_archived_file метод будет вызываться для ожидания @archive_file наличие перед входом в нижнюю обрабатывающую ветку (ветвь, в которую мы вводим команду)
Содержание wait_for_archived_file:
С MAX_RETRIES= 8, эта программа будет выполнять цикл 8 раз, чтобы дождаться существования файла, каждый раз, когда она будет спать 2 ^ i, я применяю формулу для вычисления суммы степенного ряда. Это могут проверить первокурсники, и мы знаем, что нам придется ждать 2^8 -1 = 255 секунд, если файл не существует:
И в случае, если файл не существует, этот метод также продолжает вызывать yield внизу, что означает, что операторы после wait_for_archived_fileпо-прежнему вызываются нормально, например:
На данный момент с этим багом все понятно, хотя процесс чтения Ruby/Rails достаточно болезненный, но и он приносит много знаний и кое-что интересное.
Видео с доказательством концепции:
Пришло время демонстрации!Если видео не удалось загрузить, вот резервная копия
Спасибо за чтение!
© 2022 СТАР Лабс Питаться от Хьюго и БумагаМод