From 0e4967d7fe9d88350df857506cfb274a3a65a8d5 Mon Sep 17 00:00:00 2001 From: texpert Date: Mon, 19 Aug 2024 23:02:31 +0300 Subject: [PATCH] Mitigate Arbitrary file delete vulnerability (GHSL-2024-186) --- CHANGELOG.md | 2 ++ .../camaleon_cms/admin/media_controller.rb | 19 ++++++++++--------- app/uploaders/camaleon_cms_local_uploader.rb | 6 +++++- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 535ed318..0b48c1b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ - Thanks [Peter Stöckli](https://github.com/p-) for reporting and providing clear reproduction steps - **Security fix:** Mitigate stored XSS through user file upload (GHSL-2024-184) - Thanks [Peter Stöckli](https://github.com/p-) for reporting and providing clear reproduction steps +- **Security fix:** Mitigate arbitrary file delete vulnerability (GHSL-2024-186) + - Thanks [Peter Stöckli](https://github.com/p-) for reporting and providing clear reproduction steps ## [2.8.0](https://github.com/owen2345/camaleon-cms/tree/2.8.0) (2024-07-26) - Use jQuery 2.x - 2.2.4 diff --git a/app/controllers/camaleon_cms/admin/media_controller.rb b/app/controllers/camaleon_cms/admin/media_controller.rb index 241558b1..12e8acfe 100644 --- a/app/controllers/camaleon_cms/admin/media_controller.rb +++ b/app/controllers/camaleon_cms/admin/media_controller.rb @@ -53,16 +53,15 @@ def ajax def actions authorize! :manage, :media if params[:media_action] != 'crop_url' params[:folder] = params[:folder].gsub('//', '/') if params[:folder].present? + case params[:media_action] when 'new_folder' params[:folder] = slugify_folder(params[:folder]) - render partial: 'render_file_item', locals: { files: [cama_uploader.add_folder(params[:folder])] } + return render partial: 'render_file_item', locals: { files: [cama_uploader.add_folder(params[:folder])] } when 'del_folder' - cama_uploader.delete_folder(params[:folder]) - render plain: '' + r = cama_uploader.delete_folder(params[:folder]) when 'del_file' - cama_uploader.delete_file(params[:folder].gsub('//', '/')) - render plain: '' + r = cama_uploader.delete_file(params[:folder].gsub('//', '/')) when 'crop_url' user_url = params[:url].to_s user_url = "#{current_site.the_url(locale: nil)}#{user_url}" unless user_url.start_with?('data:', 'http') @@ -72,16 +71,18 @@ def actions else cama_tmp_upload(user_url, formats: params[:formats], name: params[:name]) end - if r[:error].present? - render plain: helpers.sanitize(r[:error]) - else + if r[:error].blank? params[:file_upload] = r[:file_path] sett = { remove_source: true } sett[:same_name] = true if params[:same_name].present? sett[:name] = params[:name] if params[:name].present? - upload(sett) + return upload(sett) end end + + return render plain: helpers.sanitize(r[:error]) if r[:error].present? + + render plain: '' end # upload files from media uploader diff --git a/app/uploaders/camaleon_cms_local_uploader.rb b/app/uploaders/camaleon_cms_local_uploader.rb index c9be051a..d6cb67e8 100644 --- a/app/uploaders/camaleon_cms_local_uploader.rb +++ b/app/uploaders/camaleon_cms_local_uploader.rb @@ -2,7 +2,7 @@ class CamaleonCmsLocalUploader < CamaleonCmsUploader def after_initialize @root_folder = @args[:root_folder] || @current_site.upload_directory - FileUtils.mkdir_p(@root_folder) + FileUtils.mkdir_p(@root_folder) unless Dir.exist?(@root_folder) end def setup_private_folder @@ -109,6 +109,8 @@ def add_folder(key) # remove an existent folder def delete_folder(key) + return { error: 'Invalid folder path' } if key.include?('..') + folder = File.join(@root_folder, key) FileUtils.rm_rf(folder) if Dir.exist? folder get_media_collection.find_by_key(key).take.destroy @@ -116,6 +118,8 @@ def delete_folder(key) # remove an existent file def delete_file(key) + return { error: 'Invalid file path' } if key.include?('..') + file = File.join(@root_folder, key) FileUtils.rm(file) if File.exist? file @instance.hooks_run('after_delete', key)